├── channel-sender ├── .nvmrc ├── .tool-versions ├── .dockerignore ├── config │ ├── dev.exs │ ├── dev1.exs │ ├── dev2.exs │ ├── prod.exs │ ├── config.exs │ ├── test.exs │ └── benchee.exs ├── .formatter.exs ├── test │ ├── test_helper.exs │ └── channel_sender_ex │ │ ├── core │ │ ├── sender_application_test.exs │ │ ├── protocol_message_test.exs │ │ ├── pubsub │ │ │ └── socket_event_bus_test.exs │ │ └── retry │ │ │ └── exponential_backoff_test.exs │ │ ├── transport │ │ ├── entry_point_test.exs │ │ └── transport_spec_test.exs │ │ └── test_config_files │ │ ├── config2.yaml │ │ └── config1.yaml ├── deploy_samples │ ├── k8s │ │ ├── libcluster-kubernetes │ │ │ ├── namespace.yaml │ │ │ └── roles.yaml │ │ ├── libcluster-kubernetes-dns │ │ │ └── namespace.yaml │ │ ├── libcluster-kubernetes-dnssrv │ │ │ └── namespace.yaml │ │ └── README.md │ └── haproxy │ │ ├── run.sh │ │ └── haproxy.cfg ├── lib │ └── channel_sender_ex │ │ ├── core │ │ ├── stats │ │ │ └── core_stats_collector.ex │ │ └── sender_application.ex │ │ └── transport │ │ ├── message_encoder.ex │ │ ├── entry_point.ex │ │ └── encoders │ │ └── json_encoder.ex ├── container_utils │ └── runner.sh ├── rel │ ├── env.bat.eex │ ├── vm.args.eex │ └── env.sh.eex ├── .gitignore ├── bench │ ├── generators.exs │ └── socket_bench.exs └── LICENSE ├── channel-streams ├── .nvmrc ├── .dockerignore ├── .tool-versions ├── apps │ ├── streams_core │ │ ├── test │ │ │ ├── test_helper.exs │ │ │ └── streams_core │ │ │ │ ├── cloud_event │ │ │ │ └── routing_error_test.exs │ │ │ │ ├── boundary │ │ │ │ ├── node_observer_test.exs │ │ │ │ └── channel_registry_test.exs │ │ │ │ ├── user_test.exs │ │ │ │ ├── sender │ │ │ │ └── connector_test.exs │ │ │ │ └── app_client_test.exs │ │ ├── .formatter.exs │ │ ├── lib │ │ │ └── streams_core │ │ │ │ ├── cloud_event │ │ │ │ ├── routing_error.ex │ │ │ │ ├── parser.ex │ │ │ │ ├── mutator │ │ │ │ │ └── default_mutator.ex │ │ │ │ └── mutator.ex │ │ │ │ ├── secret_provider.ex │ │ │ │ ├── caching_provider.ex │ │ │ │ ├── user.ex │ │ │ │ ├── sender │ │ │ │ └── notification_channel.ex │ │ │ │ ├── app_client.ex │ │ │ │ ├── reference.ex │ │ │ │ └── boundary │ │ │ │ ├── node_observer.ex │ │ │ │ └── channel_registry.ex │ │ ├── README.md │ │ └── .gitignore │ ├── streams_rabbitmq │ │ ├── test │ │ │ └── test_helper.exs │ │ ├── .formatter.exs │ │ ├── lib │ │ │ └── streams_rabbitmq.ex │ │ ├── README.md │ │ └── .gitignore │ ├── streams_restapi │ │ ├── test │ │ │ ├── test_helper.exs │ │ │ ├── streams_api_test.exs │ │ │ └── streams_api │ │ │ │ └── rest │ │ │ │ ├── health │ │ │ │ └── probe_test.exs │ │ │ │ └── header_test.exs │ │ ├── .formatter.exs │ │ ├── lib │ │ │ ├── streams_api │ │ │ │ └── rest │ │ │ │ │ ├── prometheus_exporter.ex │ │ │ │ │ ├── health │ │ │ │ │ └── probe.ex │ │ │ │ │ ├── base_router.ex │ │ │ │ │ ├── header.ex │ │ │ │ │ └── error_response.ex │ │ │ └── streams_api.ex │ │ ├── README.md │ │ └── .gitignore │ ├── streams_helper_config │ │ ├── test │ │ │ ├── test_helper.exs │ │ │ ├── streams_helper_config_test.exs │ │ │ └── application_config_test.exs │ │ ├── .formatter.exs │ │ ├── lib │ │ │ ├── streams_helper_config.ex │ │ │ └── streams_helper_config │ │ │ │ ├── application.ex │ │ │ │ └── config_manager.ex │ │ ├── README.md │ │ ├── .gitignore │ │ └── mix.exs │ ├── streams_restapi_auth │ │ ├── test │ │ │ ├── test_helper.exs │ │ │ ├── oauth │ │ │ │ ├── strategy_test.exs │ │ │ │ └── config_test.exs │ │ │ └── passthrough_provider_test.exs │ │ ├── .formatter.exs │ │ ├── lib │ │ │ └── bridge_restapi_auth │ │ │ │ ├── oauth │ │ │ │ ├── strategy.ex │ │ │ │ ├── config.ex │ │ │ │ └── Token.ex │ │ │ │ ├── provider.ex │ │ │ │ ├── passthrough_provider.ex │ │ │ │ └── application.ex │ │ ├── README.md │ │ ├── .gitignore │ │ └── mix.exs │ └── streams_secretmanager │ │ ├── test │ │ ├── test_helper.exs │ │ ├── streams_secret_manager │ │ │ └── application_test.exs │ │ └── aws_config_test.exs │ │ ├── .formatter.exs │ │ ├── README.md │ │ ├── .gitignore │ │ ├── lib │ │ └── streams_secret_manager │ │ │ └── application.ex │ │ └── mix.exs ├── deploy_samples │ └── k8s │ │ ├── certs │ │ ├── .gitignore │ │ └── generate_demo_certs.sh │ │ ├── libcluster-kubernetes │ │ ├── namespace.yaml │ │ └── roles.yaml │ │ ├── libcluster-kubernetes-dns │ │ └── namespace.yaml │ │ └── libcluster-kubernetes-dnssrv │ │ └── namespace.yaml ├── docs │ ├── message_routing.md │ ├── channel_authentication.md │ └── channel_opening.md ├── config │ ├── test.exs │ ├── dev.exs │ ├── prod.exs │ └── config.exs ├── .formatter.exs ├── container_utils │ └── runner.sh ├── data_samples │ └── event_payload_sample.json ├── .gitignore └── LICENSE ├── examples ├── front-async-angular │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── app │ │ │ ├── components │ │ │ │ ├── logs │ │ │ │ │ ├── logs.component.css │ │ │ │ │ ├── logs.component.spec.ts │ │ │ │ │ └── logs.component.html │ │ │ │ ├── settings │ │ │ │ │ ├── settings.component.css │ │ │ │ │ └── settings.component.spec.ts │ │ │ │ └── requests │ │ │ │ │ ├── requests.component.spec.ts │ │ │ │ │ └── requests.component.css │ │ │ ├── app.component.css │ │ │ ├── models │ │ │ │ ├── log.interface.ts │ │ │ │ ├── message.inteface.ts │ │ │ │ └── settings.interface.ts │ │ │ ├── app.routes.ts │ │ │ ├── app.config.ts │ │ │ ├── environments │ │ │ │ ├── environment.prod.ts │ │ │ │ └── environment.ts │ │ │ ├── services │ │ │ │ ├── business.service.spec.ts │ │ │ │ ├── settings.service.spec.ts │ │ │ │ ├── log-capture.service.spec.ts │ │ │ │ └── async-client.service.spec.ts │ │ │ ├── app.component.html │ │ │ ├── app.component.ts │ │ │ └── app.component.spec.ts │ │ ├── favicon.ico │ │ ├── main.ts │ │ ├── index.html │ │ └── styles.css │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ ├── .editorconfig │ ├── start.sh │ ├── .gitignore │ ├── tsconfig.json │ └── README.md └── back-async-java │ ├── domain │ ├── model │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── co │ │ │ └── com │ │ │ └── bancolombia │ │ │ └── model │ │ │ └── async │ │ │ ├── Credentials.java │ │ │ ├── Message.java │ │ │ ├── DeliverMessage.java │ │ │ └── gateways │ │ │ └── AsyncDataFlowGateway.java │ └── usecase │ │ └── build.gradle │ ├── lombok.config │ ├── applications │ └── app-service │ │ ├── src │ │ ├── test │ │ │ └── java │ │ │ │ └── co │ │ │ │ └── com │ │ │ │ └── bancolombia │ │ │ │ └── .gitignore │ │ └── main │ │ │ ├── resources │ │ │ └── log4j2.properties │ │ │ └── java │ │ │ └── co │ │ │ └── com │ │ │ └── bancolombia │ │ │ ├── MainApplication.java │ │ │ └── config │ │ │ └── UseCasesConfig.java │ │ └── build.gradle │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradle.properties │ ├── deployment │ └── Dockerfile │ ├── infrastructure │ ├── entry-points │ │ └── reactive-web │ │ │ ├── build.gradle │ │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── co │ │ │ └── com │ │ │ └── bancolombia │ │ │ └── api │ │ │ └── RouterRest.java │ └── driven-adapters │ │ ├── rest-consumer │ │ ├── src │ │ │ └── main │ │ │ │ └── java │ │ │ │ └── co │ │ │ │ └── com │ │ │ │ └── bancolombia │ │ │ │ └── consumer │ │ │ │ └── models │ │ │ │ ├── DTOCredentials.java │ │ │ │ ├── ObjectRequest.java │ │ │ │ ├── ObjectResponse.java │ │ │ │ └── DTODeliverMessage.java │ │ └── build.gradle │ │ └── async-event-bus │ │ ├── build.gradle │ │ └── src │ │ └── main │ │ └── java │ │ └── co │ │ └── com │ │ └── bancolombia │ │ └── events │ │ └── model │ │ └── ObjectResponse.java │ └── settings.gradle ├── clients ├── client-js │ ├── .eslintignore │ ├── .gitignore │ ├── src │ │ ├── transport │ │ │ ├── socket-state.ts │ │ │ ├── transport-error.ts │ │ │ ├── protocol.ts │ │ │ ├── transport.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── decoder │ │ │ ├── index.ts │ │ │ ├── message-decoder.ts │ │ │ └── json-decoder.ts │ │ ├── channel-message.ts │ │ ├── async-config.ts │ │ └── utils.ts │ ├── .npmignore │ ├── sonar-project.properties │ ├── tsconfig.json │ ├── .eslintrc │ ├── test │ │ ├── cache.test.ts │ │ └── utils │ │ │ └── mocked-transport.ts │ └── LICENSE ├── backend-client-elixir │ ├── config │ │ ├── prod.exs │ │ ├── test.exs │ │ ├── config.exs │ │ └── dev.exs │ ├── .gitignore │ ├── .formatter.exs │ ├── coveralls.json │ ├── test │ │ └── test_helper.exs │ ├── bench │ │ ├── register_channels.exs │ │ └── deliver_message.exs │ └── LICENSE └── client-dart │ ├── example │ ├── ios │ │ ├── Runner │ │ │ ├── Runner-Bridging-Header.h │ │ │ ├── Assets.xcassets │ │ │ │ ├── LaunchImage.imageset │ │ │ │ │ ├── LaunchImage.png │ │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ │ ├── README.md │ │ │ │ │ └── Contents.json │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ │ └── AppDelegate.swift │ │ ├── Flutter │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ └── AppFrameworkInfo.plist │ │ ├── Runner.xcodeproj │ │ │ └── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── Runner.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── .gitignore │ │ └── Podfile.lock │ ├── web │ │ ├── favicon.png │ │ ├── icons │ │ │ ├── Icon-192.png │ │ │ ├── Icon-512.png │ │ │ ├── Icon-maskable-192.png │ │ │ └── Icon-maskable-512.png │ │ └── manifest.json │ ├── windows │ │ ├── runner │ │ │ ├── resources │ │ │ │ └── app_icon.ico │ │ │ ├── resource.h │ │ │ ├── CMakeLists.txt │ │ │ ├── utils.h │ │ │ ├── runner.exe.manifest │ │ │ └── flutter_window.h │ │ ├── .gitignore │ │ └── flutter │ │ │ ├── generated_plugin_registrant.h │ │ │ ├── generated_plugin_registrant.cc │ │ │ └── generated_plugins.cmake │ ├── android │ │ ├── app │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ └── kotlin │ │ │ │ │ └── co │ │ │ │ │ └── com │ │ │ │ │ └── bancolombia │ │ │ │ │ └── app_async_flutter │ │ │ │ │ └── MainActivity.kt │ │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ └── gradle-wrapper.properties │ │ ├── .gitignore │ │ ├── build.gradle.kts │ │ └── settings.gradle.kts │ ├── lib │ │ ├── domain │ │ │ └── model │ │ │ │ ├── gateway │ │ │ │ └── async_client_gateway.dart │ │ │ │ └── channel_credentials.dart │ │ ├── infrastructure │ │ │ ├── async_dataflow │ │ │ │ └── event_handler.dart │ │ │ └── notifier │ │ │ │ └── log_notifier.dart │ │ ├── main.dart │ │ └── ui │ │ │ ├── atoms │ │ │ ├── button.dart │ │ │ └── input_field.dart │ │ │ └── helpers │ │ │ └── home_helper.dart │ ├── README.md │ ├── pubspec.yaml │ ├── .gitignore │ ├── .metadata │ └── test │ │ └── widget_test.dart │ ├── lib │ ├── src │ │ ├── exceptions │ │ │ ├── invalid_strategy_exception.dart │ │ │ ├── exceptions.dart │ │ │ └── max_retries_exception.dart │ │ ├── decoder │ │ │ ├── message_decoder.dart │ │ │ ├── decoder.dart │ │ │ └── json_decoder.dart │ │ ├── sse │ │ │ ├── http_client_adapter.dart │ │ │ ├── utils.dart │ │ │ ├── enum.dart │ │ │ └── models │ │ │ │ └── reconnect.dart │ │ ├── async_client_event_handler.dart │ │ ├── transport │ │ │ └── types │ │ │ │ └── noop_transport.dart │ │ └── utils │ │ │ └── capped_list.dart │ └── channel_sender_client.dart │ ├── .pubignore │ ├── test │ ├── transport │ │ ├── transport_test.dart │ │ ├── noop_transport_test.dart │ │ └── max_retries_exception_test.dart │ └── model │ │ └── channel_message_test.dart │ ├── CHANGELOG.md │ ├── pubspec.yaml │ ├── LICENCE │ └── LICENSE ├── SECURITY.md ├── .github ├── pull_request_template.md ├── issue_template.md ├── dependabot.yml └── workflows │ ├── secret-scanner.yml │ ├── build-client-js.yaml │ ├── release-client-js.yml │ ├── release-client-dart.yml │ ├── release-channel-sender.yml │ └── release-channel-streams.yml ├── .gitignore └── .vscode └── launch.json /channel-sender/.nvmrc: -------------------------------------------------------------------------------- 1 | v20.11.0 -------------------------------------------------------------------------------- /channel-streams/.nvmrc: -------------------------------------------------------------------------------- 1 | v20.11.0 -------------------------------------------------------------------------------- /examples/front-async-angular/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/back-async-java/domain/model/build.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/client-js/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | test -------------------------------------------------------------------------------- /channel-sender/.tool-versions: -------------------------------------------------------------------------------- 1 | erlang 27.3 2 | elixir 1.18.4-otp-27 -------------------------------------------------------------------------------- /channel-streams/.dockerignore: -------------------------------------------------------------------------------- 1 | _build/ 2 | deps 3 | .idea 4 | .elixir_ls -------------------------------------------------------------------------------- /channel-streams/.tool-versions: -------------------------------------------------------------------------------- 1 | erlang 26.2.5.3 2 | elixir 1.16.3-otp-26 -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /channel-streams/deploy_samples/k8s/certs/.gitignore: -------------------------------------------------------------------------------- 1 | *.crt 2 | *.key 3 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/components/logs/logs.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_rabbitmq/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /channel-sender/.dockerignore: -------------------------------------------------------------------------------- 1 | _build 2 | .elixir_ls 3 | deps 4 | *.dump 5 | *.iml -------------------------------------------------------------------------------- /channel-streams/apps/streams_helper_config/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_secretmanager/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /channel-streams/docs/message_routing.md: -------------------------------------------------------------------------------- 1 | # Message routing process 2 | 3 | Work in progress -------------------------------------------------------------------------------- /channel-streams/config/test.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :streams_core, env: Mix.env() 4 | -------------------------------------------------------------------------------- /channel-streams/docs/channel_authentication.md: -------------------------------------------------------------------------------- 1 | # Channel auth process 2 | 3 | Work in progress -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | .tab-icon { 2 | padding-right: 10px; 3 | } -------------------------------------------------------------------------------- /channel-streams/docs/channel_opening.md: -------------------------------------------------------------------------------- 1 | # Channel openning detailed process 2 | 3 | Work in progress -------------------------------------------------------------------------------- /clients/backend-client-elixir/config/prod.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :logger, level: :warn 4 | -------------------------------------------------------------------------------- /clients/backend-client-elixir/config/test.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :logger, level: :debug 4 | -------------------------------------------------------------------------------- /clients/backend-client-elixir/config/config.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | import_config "#{Mix.env()}.exs" 4 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /clients/client-js/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | dist 4 | .nyc_output 5 | coverage 6 | .scannerwork 7 | -------------------------------------------------------------------------------- /examples/back-async-java/domain/usecase/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':model') 3 | } 4 | -------------------------------------------------------------------------------- /examples/back-async-java/lombok.config: -------------------------------------------------------------------------------- 1 | config.stopBubbling = true 2 | lombok.addLombokGeneratedAnnotation = true 3 | -------------------------------------------------------------------------------- /clients/backend-client-elixir/.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | deps 3 | .elixir_ls 4 | generic_test_execution_sonarqube.xml 5 | cover -------------------------------------------------------------------------------- /channel-sender/config/dev.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :channel_sender_ex, 4 | config_file: "./config/config-local.yaml" 5 | -------------------------------------------------------------------------------- /channel-sender/config/dev1.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :channel_sender_ex, 4 | config_file: "./config/config-local1.yaml" 5 | -------------------------------------------------------------------------------- /channel-sender/config/dev2.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :channel_sender_ex, 4 | config_file: "./config/config-local2.yaml" 5 | -------------------------------------------------------------------------------- /channel-sender/config/prod.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :channel_sender_ex, 4 | config_file: "/app/config/config.yaml" 5 | -------------------------------------------------------------------------------- /examples/back-async-java/applications/app-service/src/test/java/co/com/bancolombia/.gitignore: -------------------------------------------------------------------------------- 1 | ArchitectureTest.java 2 | Utils.java -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/components/settings/settings.component.css: -------------------------------------------------------------------------------- 1 | .mat-mdc-form-field { 2 | margin-left: 8px; 3 | } -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/models/log.interface.ts: -------------------------------------------------------------------------------- 1 | export interface Log { 2 | type: string; 3 | message: string; 4 | } -------------------------------------------------------------------------------- /channel-sender/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | export const routes: Routes = []; 4 | -------------------------------------------------------------------------------- /channel-streams/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["mix.exs", "config/*.exs"], 4 | subdirectories: ["apps/*"] 5 | ] 6 | -------------------------------------------------------------------------------- /clients/client-dart/example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/web/favicon.png -------------------------------------------------------------------------------- /clients/client-js/src/transport/socket-state.ts: -------------------------------------------------------------------------------- 1 | export enum SocketState { 2 | CONNECTING, 3 | OPEN, 4 | CLOSING, 5 | CLOSED 6 | } -------------------------------------------------------------------------------- /examples/front-async-angular/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/examples/front-async-angular/src/favicon.ico -------------------------------------------------------------------------------- /clients/backend-client-elixir/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /clients/client-dart/example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /clients/client-dart/example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /clients/client-js/.npmignore: -------------------------------------------------------------------------------- 1 | tsconfig.json 2 | src 3 | .idea 4 | test 5 | .nyc_output 6 | .scannerwork 7 | coverage 8 | Jenkinsfile 9 | sonar-project.properties -------------------------------------------------------------------------------- /clients/client-js/src/transport/transport-error.ts: -------------------------------------------------------------------------------- 1 | export interface TransportError { 2 | code: number; 3 | message: string; 4 | origin: string 5 | } -------------------------------------------------------------------------------- /channel-streams/apps/streams_rabbitmq/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_helper_config/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_secretmanager/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /clients/client-dart/lib/src/exceptions/invalid_strategy_exception.dart: -------------------------------------------------------------------------------- 1 | class InvalidStrategyException implements Exception { 2 | InvalidStrategyException(String message); 3 | } -------------------------------------------------------------------------------- /clients/client-js/src/index.ts: -------------------------------------------------------------------------------- 1 | export { AsyncClient } from './async-client' 2 | export { AsyncConfig } from './async-config' 3 | export { ChannelMessage } from './channel-message' -------------------------------------------------------------------------------- /examples/back-async-java/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/examples/back-async-java/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /channel-streams/apps/streams_rabbitmq/lib/streams_rabbitmq.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsRabbitmq do 2 | @moduledoc """ 3 | Documentation for `StreamsRabbitmq`. 4 | """ 5 | 6 | end 7 | -------------------------------------------------------------------------------- /clients/backend-client-elixir/config/dev.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :adf_sender_connector, 4 | base_path: "http://localhost:8081" 5 | 6 | config :logger, level: :debug 7 | -------------------------------------------------------------------------------- /clients/client-dart/example/web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /clients/client-dart/example/web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /channel-sender/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | Code.compiler_options(ignore_module_conflict: true) 2 | ChannelSenderEx.Core.RulesProvider.Helper.compile(:channel_sender_ex) 3 | ExUnit.start() 4 | -------------------------------------------------------------------------------- /clients/client-dart/lib/src/decoder/message_decoder.dart: -------------------------------------------------------------------------------- 1 | import '../model/channel_message.dart'; 2 | 3 | abstract class MessageDecoder { 4 | ChannelMessage decode(T event); 5 | } 6 | -------------------------------------------------------------------------------- /channel-sender/deploy_samples/k8s/libcluster-kubernetes/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: sendernm 5 | labels: 6 | istio-injection: enabled 7 | -------------------------------------------------------------------------------- /channel-streams/deploy_samples/k8s/libcluster-kubernetes/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: streamsnm 5 | labels: 6 | istio-injection: enabled 7 | -------------------------------------------------------------------------------- /clients/client-dart/example/windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /clients/client-js/src/decoder/index.ts: -------------------------------------------------------------------------------- 1 | export { MessageDecoder } from './message-decoder'; 2 | export { BinaryDecoder } from './binary-decoder'; 3 | export { JsonDecoder } from './json-decoder'; -------------------------------------------------------------------------------- /channel-sender/deploy_samples/k8s/libcluster-kubernetes-dns/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: sendernm 5 | labels: 6 | istio-injection: enabled 7 | -------------------------------------------------------------------------------- /channel-sender/deploy_samples/k8s/libcluster-kubernetes-dnssrv/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: sendernm 5 | labels: 6 | istio-injection: enabled 7 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/lib/streams_api/rest/prometheus_exporter.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsApi.Rest.PrometheusExporter do 2 | @moduledoc false 3 | use Prometheus.PlugExporter 4 | end 5 | -------------------------------------------------------------------------------- /channel-streams/deploy_samples/k8s/libcluster-kubernetes-dns/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: streamsnm 5 | labels: 6 | istio-injection: enabled 7 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/models/message.inteface.ts: -------------------------------------------------------------------------------- 1 | export interface Message { 2 | correlation_id: string; 3 | event: string; 4 | message_id: string; 5 | payload: any; 6 | } 7 | -------------------------------------------------------------------------------- /channel-streams/deploy_samples/k8s/libcluster-kubernetes-dnssrv/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: streamsnm 5 | labels: 6 | istio-injection: enabled 7 | -------------------------------------------------------------------------------- /clients/client-js/src/transport/protocol.ts: -------------------------------------------------------------------------------- 1 | /* List of supported sub-protocols for data transport */ 2 | export const enum Protocol { 3 | JSON = "json_flow", 4 | BINARY = "binary_flow" 5 | } 6 | -------------------------------------------------------------------------------- /clients/client-dart/lib/src/sse/http_client_adapter.dart: -------------------------------------------------------------------------------- 1 | import 'package:http/http.dart'; 2 | 3 | abstract interface class HttpClientAdapter { 4 | Future send(BaseRequest request); 5 | } 6 | -------------------------------------------------------------------------------- /clients/client-dart/lib/src/exceptions/exceptions.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | export 'invalid_strategy_exception.dart' show InvalidStrategyException; 4 | export 'max_retries_exception.dart' show MaxRetriesException; 5 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /clients/client-dart/lib/src/decoder/decoder.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | export 'binary_decoder.dart' show BinaryDecoder; 4 | export 'json_decoder.dart' show JsonDecoder; 5 | export 'message_decoder.dart' show MessageDecoder; 6 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /clients/client-js/src/transport/transport.ts: -------------------------------------------------------------------------------- 1 | export interface Transport { 2 | connect(): void; 3 | disconnect(): void; 4 | name(): string; 5 | connected(): boolean; 6 | send(message: string): void; 7 | } 8 | -------------------------------------------------------------------------------- /clients/backend-client-elixir/coveralls.json: -------------------------------------------------------------------------------- 1 | { 2 | "coverage_options": { 3 | "treat_no_relevant_lines_as_covered": false, 4 | "output_dir": "cover/", 5 | "minimum_coverage": 0, 6 | "xml_base_dir": "./" 7 | } 8 | } -------------------------------------------------------------------------------- /clients/backend-client-elixir/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | Code.compiler_options(ignore_module_conflict: true) 2 | ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter, ExUnitSonarqube]) 3 | ExUnit.start(exclude: [:skip]) 4 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /examples/back-async-java/gradle.properties: -------------------------------------------------------------------------------- 1 | package=co.com.bancolombia 2 | systemProp.version=3.20.15 3 | reactive=true 4 | lombok=true 5 | metrics=true 6 | language=java 7 | org.gradle.parallel=true 8 | systemProp.sonar.gradle.skipCompile=true -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /channel-sender/lib/channel_sender_ex/core/stats/core_stats_collector.ex: -------------------------------------------------------------------------------- 1 | defmodule CoreStatsCollector do 2 | @moduledoc """ 3 | Module whose responsibility is to gather statistics 4 | """ 5 | 6 | def event(_type, _data) do 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /clients/client-js/src/channel-message.ts: -------------------------------------------------------------------------------- 1 | export class ChannelMessage { 2 | constructor( 3 | public message_id: string, 4 | public event: string, 5 | public correlation_id: string, 6 | public payload: any) { } 7 | } 8 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/models/settings.interface.ts: -------------------------------------------------------------------------------- 1 | export interface Settings { 2 | heartbeatDelay: number; 3 | maxRetries: number; 4 | defaultRequestDelay: number; 5 | transports: Array; 6 | server: string; 7 | } -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bancolombia/async-dataflow/HEAD/clients/client-dart/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /clients/client-dart/.pubignore: -------------------------------------------------------------------------------- 1 | # See https://dart.dev/tools/pub/publishing#what-files-are-published 2 | 3 | /coverage/* 4 | /build/* 5 | /test/* 6 | /doc/* 7 | /metrics/* 8 | /tool/* 9 | /website/* 10 | /codecov.yaml 11 | /dart_dependency_validator.yaml 12 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/main/kotlin/co/com/bancolombia/app_async_flutter/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.app_async_flutter 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity : FlutterActivity() 6 | -------------------------------------------------------------------------------- /clients/client-dart/lib/src/exceptions/max_retries_exception.dart: -------------------------------------------------------------------------------- 1 | class MaxRetriesException implements Exception { 2 | final String message; 3 | MaxRetriesException(this.message); 4 | 5 | @override 6 | String toString() => 'MaxRetriesException: $message'; 7 | } -------------------------------------------------------------------------------- /channel-sender/container_utils/runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | trap "echo; exit" INT 4 | 5 | # load any needed env vars 6 | File=/app/config/env.sh 7 | if test -f "$File"; then 8 | . $File 9 | fi 10 | 11 | # run release 12 | /app/bin/channel_sender_ex start 13 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/cloud_event/routing_error.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.CloudEvent.RoutingError do 2 | @moduledoc """ 3 | Error raised when no routing throught ADF channel sender can be made 4 | """ 5 | 6 | defexception message: "" 7 | end 8 | -------------------------------------------------------------------------------- /channel-streams/config/dev.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :streams_core, 4 | env: Mix.env(), 5 | config_file: "./config-local.yaml" 6 | 7 | config :logger, :default_formatter, 8 | format: "\n$time [$level][$metadata] $message\n", 9 | metadata: [:application] 10 | -------------------------------------------------------------------------------- /clients/client-js/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=bancolombia_async-dataflow-client-js 2 | sonar.organization=grupo-bancolombia 3 | sonar.projectName=async-dataflow-client-js 4 | sonar.sources=src 5 | sonar.tests=test 6 | sonar.javascript.lcov.reportPaths=./coverage/lcov.info -------------------------------------------------------------------------------- /channel-streams/config/prod.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :streams_core, 4 | env: Mix.env(), 5 | config_file: "/app/config/config.yaml" 6 | 7 | config :logger, :default_formatter, 8 | format: "\n$time [$level][$metadata] $message\n", 9 | metadata: [:application] 10 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip 6 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/app.config.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | 4 | import { routes } from './app.routes'; 5 | 6 | export const appConfig: ApplicationConfig = { 7 | providers: [provideRouter(routes)], 8 | }; 9 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/lib/streams_api/rest/health/probe.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsApi.Rest.Health.Probe do 2 | @moduledoc false 3 | 4 | @callback readiness() :: :ok | :error 5 | @callback liveness() :: :ok | :error 6 | 7 | def liveness, do: :ok 8 | def readiness, do: :ok 9 | end 10 | -------------------------------------------------------------------------------- /channel-streams/container_utils/runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | trap "echo; exit" INT 4 | 5 | # load any needed env vars 6 | File=/app/config/env.sh 7 | if test -f "$File"; then 8 | echo "Loading env vars from ${File}" 9 | . $File 10 | fi 11 | 12 | # run release 13 | /app/rel/adf_streams/bin/adf_streams start 14 | -------------------------------------------------------------------------------- /clients/client-js/src/transport/index.ts: -------------------------------------------------------------------------------- 1 | export { Transport } from './transport'; 2 | export { TransportError } from './transport-error'; 3 | export { SocketState } from './socket-state'; 4 | export { WsTransport } from './ws-transport'; 5 | export { SseTransport } from './sse-transport'; 6 | export { Protocol } from './protocol'; -------------------------------------------------------------------------------- /clients/client-js/src/decoder/message-decoder.ts: -------------------------------------------------------------------------------- 1 | /* The default serializer for encoding and decoding messages */ 2 | 3 | 4 | import { ChannelMessage } from "../channel-message"; 5 | 6 | export interface MessageDecoder { 7 | decode(event: MessageEvent): ChannelMessage; 8 | decode_sse(event: any): ChannelMessage; 9 | } 10 | -------------------------------------------------------------------------------- /channel-sender/config/config.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :channel_sender_ex, 4 | app_repo: ChannelSenderEx.Repository.ApplicationRepo, 5 | channel_shutdown_tolerance: 10_000, 6 | min_disconnection_tolerance: 50, 7 | socket_event_bus: ChannelSenderEx.Core.PubSub.SocketEventBus 8 | 9 | import_config "#{Mix.env()}.exs" 10 | -------------------------------------------------------------------------------- /examples/back-async-java/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /channel-sender/deploy_samples/haproxy/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd ../../ 3 | MIX_ENV=dev elixir --name async-node0@127.0.0.1 -S mix run --no-halt & 4 | MIX_ENV=dev1 elixir --name async-node1@127.0.0.1 -S mix run --no-halt & 5 | MIX_ENV=dev2 elixir --name async-node2@127.0.0.1 -S mix run --no-halt & 6 | 7 | haproxy -f deploy_samples/haproxy/haproxy.cfg -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /channel-sender/rel/env.bat.eex: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem Set the release to work across nodes. If using the long name format like 3 | rem the one below (my_app@127.0.0.1), you need to also uncomment the 4 | rem RELEASE_DISTRIBUTION variable below. Must be "sname", "name" or "none". 5 | rem set RELEASE_DISTRIBUTION=name 6 | rem set RELEASE_NODE=<%= @release.name %>@127.0.0.1 7 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_secretmanager/test/streams_secret_manager/application_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsSecretManager.ApplicationTest do 2 | use ExUnit.Case, async: true 3 | 4 | test "Should not start app twice" do 5 | 6 | assert {:error, {:already_started, _}} = StreamsSecretManager.Application.start(:normal, []) 7 | 8 | end 9 | 10 | end 11 | -------------------------------------------------------------------------------- /channel-streams/data_samples/event_payload_sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "specVersion": "0", 3 | "type": "some action", 4 | "source" : "Some source", 5 | "subject" : "foo", 6 | "id" : "", 7 | "time" : "2023-01-21T10:12:35.00Z", 8 | "invoker" : "component acme", 9 | "dataContentType" : "application/json", 10 | "data" : "hello world" 11 | } -------------------------------------------------------------------------------- /clients/client-dart/example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | .cxx/ 9 | 10 | # Remember to never publicly share your keystore. 11 | # See https://flutter.dev/to/reference-keystore 12 | key.properties 13 | **/*.keystore 14 | **/*.jks 15 | -------------------------------------------------------------------------------- /clients/client-dart/example/lib/domain/model/gateway/async_client_gateway.dart: -------------------------------------------------------------------------------- 1 | import 'package:app_async_flutter/domain/model/channel_credentials.dart'; 2 | 3 | abstract class AsyncClientGateway { 4 | Future getCredentials(String userRef); 5 | Future callBusinessUseCase( 6 | String channelRef, String userRef, int delay); 7 | } 8 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/secret_provider.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.SecretProvider do 2 | @moduledoc """ 3 | Behaviour definition for a secrets repository 4 | """ 5 | 6 | @type key() :: String.t() 7 | @type opts() :: Keyword.t() 8 | 9 | @callback get_secret(key(), opts()) :: {:ok, any()} | {:error, reason :: term} 10 | end 11 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/back-async-java/deployment/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:17-jdk-alpine 2 | VOLUME /tmp 3 | COPY *.jar back-async.jar 4 | ENV JAVA_OPTS=" -XX:+UseContainerSupport -Djava.security.egd=file:/dev/./urandom" 5 | # Replace with a non-root user to avoid running the container with excessive privileges 6 | ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -jar back-async.jar" ] 7 | -------------------------------------------------------------------------------- /examples/back-async-java/domain/model/src/main/java/co/com/bancolombia/model/async/Credentials.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.model.async; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | 6 | @Builder(toBuilder = true) 7 | @Getter 8 | public class Credentials { 9 | private final String channelRef; 10 | private final String channelSecret; 11 | } 12 | -------------------------------------------------------------------------------- /examples/front-async-angular/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /examples/front-async-angular/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "include": [ 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /examples/front-async-angular/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | const servers = { 2 | main: { 3 | api_business: 'REPLACE', 4 | socket_url_async: 'REPLACE' 5 | } 6 | } as { [key: string]: { api_business: string, socket_url_async: string } }; 7 | 8 | export const environment = { 9 | production: true, 10 | servers, 11 | heartbeat_interval: 20000, 12 | } as any; 13 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/test/streams_api_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsApiTest do 2 | use ExUnit.Case, async: true 3 | 4 | test "Should not start app twice" do 5 | 6 | config = %{ 7 | :streams => %{ 8 | "port" => 8080 9 | } 10 | } 11 | 12 | assert {:error, {:already_started, _}} = StreamsApi.start(:normal, [config]) 13 | 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/lib/streams_api/rest/base_router.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsApi.Rest.BaseRouter do 2 | @moduledoc false 3 | 4 | use Plug.Router 5 | use Plug.ErrorHandler 6 | 7 | plug(:match) 8 | plug(:dispatch) 9 | 10 | forward("/api/v1/channel-streams-ex", to: StreamsApi.Rest.RestRouter) 11 | 12 | match(_, do: send_resp(conn, 404, "Resource not found")) 13 | 14 | end 15 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/lib/bridge_restapi_auth/oauth/strategy.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsRestapiAuth.Oauth.Strategy do 2 | @moduledoc """ 3 | Strategy for handling the OAuth2.0 token. 4 | """ 5 | 6 | alias StreamsRestapiAuth.Oauth.Config 7 | use JokenJwks.DefaultStrategyTemplate 8 | 9 | def init_opts(opts), do: Keyword.merge(opts, jwks_url: Config.jwks_url()) 10 | 11 | end 12 | -------------------------------------------------------------------------------- /clients/client-js/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { "*": ["types/*"] }, 5 | //"lib": [ "es2015" ], 6 | "module": "commonjs", 7 | "target": "es2015", 8 | "declaration": true, 9 | "outDir": "./dist", 10 | "sourceMap": true 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | "dist", 15 | "test" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /examples/back-async-java/infrastructure/entry-points/reactive-web/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':usecase') 3 | implementation project(':model') 4 | implementation 'org.springframework.boot:spring-boot-starter-webflux' 5 | implementation 'org.springframework.boot:spring-boot-starter-actuator' 6 | implementation 'io.micrometer:micrometer-registry-prometheus' 7 | } 8 | -------------------------------------------------------------------------------- /clients/client-dart/example/windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /examples/back-async-java/domain/model/src/main/java/co/com/bancolombia/model/async/Message.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.model.async; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | 6 | @Builder(toBuilder = true) 7 | @Getter 8 | public class Message { 9 | private String code; 10 | private String title; 11 | private String detail; 12 | private String severity; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/lib/streams_api/rest/header.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsApi.Rest.Header do 2 | @moduledoc """ 3 | Helper Function for extractig header values 4 | """ 5 | 6 | @type headers_map :: map() 7 | @type conn :: %Plug.Conn{} 8 | 9 | @spec all_headers(conn()) :: {:ok, headers_map()} 10 | def all_headers(conn) do 11 | {:ok, Enum.into(conn.req_headers, %{})} 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /examples/front-async-angular/start.sh: -------------------------------------------------------------------------------- 1 | #/bin/zsh 2 | set -e 3 | environment=$1 4 | cd ../../clients/client-js 5 | npm run publish-local 6 | version=$(jq -r '.version' package.json) 7 | echo "\n\nInstalling @bancolombia/chanjs-client@$version from local registry" 8 | cd ../../examples/front-async-angular 9 | npm i --registry http://localhost:4873 "@bancolombia/chanjs-client@$version" 10 | ng serve -c "$environment" 11 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/README.md: -------------------------------------------------------------------------------- 1 | # Async DataFlow Streams Core 2 | 3 | Core abstractions for Channel Streams. 4 | 5 | ## Installation 6 | 7 | If [available in Hex](https://hex.pm/docs/publish), the package can be installed 8 | by adding `streams_core` to your list of dependencies in `mix.exs`: 9 | 10 | ```elixir 11 | def deps do 12 | [ 13 | {:streams_core, "~> 0.1.0"} 14 | ] 15 | end 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /channel-sender/rel/vm.args.eex: -------------------------------------------------------------------------------- 1 | ## Customize flags given to the VM: http://erlang.org/doc/man/erl.html 2 | ## -mode/-name/-sname/-setcookie are configured via env vars, do not set them here 3 | 4 | ## Number of dirty schedulers doing IO work (file, sockets, and others) 5 | ##+SDio 5 6 | 7 | ## Increase number of concurrent ports/sockets 8 | ##+Q 65536 9 | 10 | ## Tweak GC to run more often 11 | ##-env ERL_FULLSWEEP_AFTER 10 12 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/caching_provider.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.CachingProvider do 2 | @moduledoc """ 3 | Behaviour definition for caching repository 4 | """ 5 | 6 | @type key() :: String.t() 7 | @type value() :: any() 8 | 9 | @callback get(key()) :: {:ok, result :: term} | {:miss, reason :: term, value :: any()} 10 | @callback put(key(), value()) :: {:ok, value :: any()} 11 | end 12 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/README.md: -------------------------------------------------------------------------------- 1 | # Async dataflow Streams Rest Api 2 | 3 | Channel Streams Rest Api Operations. 4 | 5 | ## Installation 6 | 7 | If [available in Hex](https://hex.pm/docs/publish), the package can be installed 8 | by adding `streams_restapi` to your list of dependencies in `mix.exs`: 9 | 10 | ```elixir 11 | def deps do 12 | [ 13 | {:streams_restapi, "~> 0.1.0"} 14 | ] 15 | end 16 | ``` 17 | -------------------------------------------------------------------------------- /clients/client-dart/example/lib/infrastructure/async_dataflow/event_handler.dart: -------------------------------------------------------------------------------- 1 | import 'package:channel_sender_client/channel_sender_client.dart'; 2 | 3 | class EventHandler implements AsyncClientEventHandler { 4 | @override 5 | void onEvent(AsyncClientEvent event) { 6 | print( 7 | 'Event received: ${event.message}, Transport: ${event.transportType}, Channel: ${event.channelRef}', 8 | ); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /clients/client-dart/test/transport/transport_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:channel_sender_client/channel_sender_client.dart'; 2 | import 'package:test/test.dart'; 3 | 4 | void main() { 5 | test('transportFromString', () { 6 | expect(transportFromString('ws'), TransportType.ws); 7 | expect(transportFromString('sse'), TransportType.sse); 8 | expect(transportFromString('unknown'), TransportType.ws); 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_rabbitmq/README.md: -------------------------------------------------------------------------------- 1 | # Async Dataflow Streams RabbitMQ Adapter 2 | 3 | Channel Streams RabbitMQ Adapter. 4 | 5 | ## Installation 6 | 7 | If [available in Hex](https://hex.pm/docs/publish), the package can be installed 8 | by adding `streams_rabbitmq` to your list of dependencies in `mix.exs`: 9 | 10 | ```elixir 11 | def deps do 12 | [ 13 | {:streams_rabbitmq, "~> 0.1.0"} 14 | ] 15 | end 16 | ``` -------------------------------------------------------------------------------- /clients/client-dart/example/windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/test/streams_api/rest/health/probe_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsApi.Rest.Health.ProbeTest do 2 | use ExUnit.Case 3 | 4 | alias StreamsApi.Rest.Health.Probe 5 | 6 | @moduletag :capture_log 7 | 8 | test "Should validate linevess" do 9 | assert :ok == Probe.liveness() 10 | end 11 | 12 | test "Should validate readiness" do 13 | assert :ok == Probe.readiness() 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /clients/client-js/src/async-config.ts: -------------------------------------------------------------------------------- 1 | export interface AsyncConfig { 2 | socket_url: string; 3 | sse_url?: string; 4 | channel_ref: string; 5 | channel_secret: string; 6 | enable_binary_transport?: boolean; 7 | heartbeat_interval?: number; 8 | dedupCacheDisable?: boolean; 9 | dedupCacheMaxSize?: number; 10 | dedupCacheTtl?: number; 11 | maxReconnectAttempts?: number; 12 | checkConnectionOnFocus?: boolean; 13 | } -------------------------------------------------------------------------------- /examples/back-async-java/infrastructure/driven-adapters/rest-consumer/src/main/java/co/com/bancolombia/consumer/models/DTOCredentials.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.consumer.models; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAlias; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class DTOCredentials { 8 | @JsonAlias("channel_ref") 9 | String channelRef; 10 | @JsonAlias("channel_secret") 11 | String channelSecret; 12 | } 13 | -------------------------------------------------------------------------------- /examples/back-async-java/infrastructure/driven-adapters/rest-consumer/src/main/java/co/com/bancolombia/consumer/models/ObjectRequest.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.consumer.models; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAlias; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | @Data 8 | @Builder(toBuilder = true) 9 | public class ObjectRequest { 10 | private String application_ref; 11 | private String user_ref; 12 | } 13 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/test/streams_core/cloud_event/routing_error_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.CloudEvent.RoutingErrorTest do 2 | use ExUnit.Case 3 | 4 | alias StreamsCore.CloudEvent.RoutingError 5 | 6 | @moduletag :capture_log 7 | 8 | test "Should extract channel alias from data" do 9 | 10 | assert_raise RoutingError, fn -> 11 | raise RoutingError, message: "dummy reason" 12 | end 13 | 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | 0.1.1 | :white_check_mark: | 8 | | 0.1.0 | :white_check_mark: | 9 | 10 | ## Reporting a Vulnerability 11 | 12 | This repository runs security code scanning weekly to identify vulnerabilities. 13 | If you want to report a vulnerability, please create an issue with a clear description and we will try to fix it. 14 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/back-async-java/applications/app-service/src/main/resources/log4j2.properties: -------------------------------------------------------------------------------- 1 | name=PropertiesConfig 2 | property.filename=logs 3 | appenders=console 4 | appender.console.type=Console 5 | appender.console.name=STDOUT 6 | appender.console.layout.type=PatternLayout 7 | appender.console.layout.pattern=[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n 8 | rootLogger.level=debug 9 | rootLogger.appenderRefs=stdout 10 | rootLogger.appenderRef.stdout.ref=STDOUT 11 | -------------------------------------------------------------------------------- /examples/back-async-java/infrastructure/driven-adapters/rest-consumer/src/main/java/co/com/bancolombia/consumer/models/ObjectResponse.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.consumer.models; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder(toBuilder = true) 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class ObjectResponse { 13 | private String state; 14 | } -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/environments/environment.ts: -------------------------------------------------------------------------------- 1 | const servers = { 2 | local: { 3 | api_business: 'http://localhost:8080/api', 4 | socket_url_async: 'ws://localhost:8082', 5 | sse_url_async: 'http://localhost:8082' 6 | } 7 | } as { [key: string]: { api_business: string, socket_url_async: string, sse_url_async: string } }; 8 | 9 | export const environment = { 10 | production: false, 11 | servers, 12 | heartbeat_interval: 2000, 13 | } as any; 14 | -------------------------------------------------------------------------------- /clients/client-dart/example/windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | 11 | void RegisterPlugins(flutter::PluginRegistry* registry) { 12 | ConnectivityPlusWindowsPluginRegisterWithRegistrar( 13 | registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); 14 | } 15 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/lib/bridge_restapi_auth/provider.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsRestapiAuth.Provider do 2 | @moduledoc """ 3 | Behaviour definition for the authentication strategy 4 | """ 5 | 6 | @type all_headers :: map() 7 | @type credentials() :: map() 8 | @type reason() :: any() 9 | 10 | @doc """ 11 | Validates user credentials 12 | """ 13 | @callback validate_credentials(all_headers()) :: {:error, reason()} | {:ok, credentials()} 14 | 15 | end 16 | -------------------------------------------------------------------------------- /clients/client-dart/lib/src/async_client_event_handler.dart: -------------------------------------------------------------------------------- 1 | import '../channel_sender_client.dart'; 2 | 3 | abstract class AsyncClientEventHandler { 4 | void onEvent(AsyncClientEvent event); 5 | } 6 | 7 | class AsyncClientEvent { 8 | final String message; 9 | final TransportType transportType; 10 | final String? channelRef; 11 | 12 | AsyncClientEvent({ 13 | required this.message, 14 | this.transportType = TransportType.ws, 15 | this.channelRef, 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /clients/client-dart/example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:app_async_flutter/setup.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_dotenv/flutter_dotenv.dart'; 4 | import 'package:shared_preferences/shared_preferences.dart'; 5 | 6 | void main() async { 7 | await dotenv.load(fileName: ".env"); 8 | WidgetsFlutterBinding.ensureInitialized(); 9 | SharedPreferences prefs = await SharedPreferences.getInstance(); 10 | 11 | runApp(Setup.getApp(prefs)); 12 | } 13 | -------------------------------------------------------------------------------- /examples/back-async-java/domain/model/src/main/java/co/com/bancolombia/model/async/DeliverMessage.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.model.async; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | 6 | @Builder(toBuilder = true) 7 | @Getter 8 | public class DeliverMessage { 9 | private final String channelRef; 10 | private final String messageId; 11 | private final String CorrelationId; 12 | private final Message messageData; 13 | private final String eventName; 14 | } 15 | -------------------------------------------------------------------------------- /examples/back-async-java/infrastructure/driven-adapters/async-event-bus/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':model') 3 | implementation 'io.cloudevents:cloudevents-json-jackson:4.0.1' 4 | implementation 'org.reactivecommons:async-commons-rabbit-starter:5.2.3' 5 | implementation 'org.springframework:spring-context' 6 | implementation 'org.springframework.boot:spring-boot-autoconfigure' 7 | implementation 'org.springframework.boot:spring-boot-starter-webflux' 8 | } 9 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/services/business.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { BusinessService } from './business.service'; 4 | 5 | describe('BusinessService', () => { 6 | let service: BusinessService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(BusinessService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/services/settings.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { SettingsService } from './settings.service'; 4 | 5 | describe('SettingsService', () => { 6 | let service: SettingsService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(SettingsService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /channel-sender/config/test.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :channel_sender_ex, 4 | secret_base: 5 | {"aV4ZPOf7T7HX6GvbhwyBlDM8B9jfeiwi+9qkBnjXxUZXqAeTrehojWKHkV3U0kGc", "socket auth"}, 6 | initial_redelivery_time: 100, 7 | app_repo: ChannelSenderEx.Repository.ApplicationRepo, 8 | channel_shutdown_tolerance: 10_000, 9 | max_age: 900, 10 | socket_idle_timeout: 60000, 11 | socket_port: 8082, 12 | rest_port: 8081, 13 | topology: [ 14 | strategy: Cluster.Strategy.Gossip 15 | ] 16 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_helper_config/lib/streams_helper_config.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsHelperConfig do 2 | @moduledoc """ 3 | Documentation for `StreamsHelperConfig`. 4 | """ 5 | 6 | @spec get(list(), any()) :: any() 7 | def get(key, default) do 8 | case StreamsHelperConfig.ConfigManager.lookup(key) do 9 | nil -> 10 | default 11 | value -> 12 | value 13 | end 14 | end 15 | 16 | def load(file), do: StreamsHelperConfig.ConfigManager.load(file) 17 | 18 | end 19 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/services/log-capture.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { LogCaptureService } from '../log-capture.service'; 4 | 5 | describe('LogCaptureService', () => { 6 | let service: LogCaptureService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(LogCaptureService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/services/async-client.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { AsyncClientService } from './async-client.service'; 4 | 5 | describe('AsyncClientService', () => { 6 | let service: AsyncClientService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(AsyncClientService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /clients/client-js/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "parserOptions": { 4 | "ecmaVersion": 12, 5 | "sourceType": "module" 6 | }, 7 | "plugins": ["@typescript-eslint"], 8 | "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], 9 | "rules": { 10 | "@typescript-eslint/no-unused-vars": "warn", 11 | "@typescript-eslint/no-explicit-any": "off" 12 | }, 13 | "env": { 14 | "browser": true, 15 | "es2016": true 16 | } 17 | } -------------------------------------------------------------------------------- /examples/back-async-java/applications/app-service/src/main/java/co/com/bancolombia/MainApplication.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 6 | 7 | @SpringBootApplication 8 | public class MainApplication { 9 | public static void main(String[] args) { 10 | SpringApplication.run(MainApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /clients/client-dart/example/windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /examples/back-async-java/domain/model/src/main/java/co/com/bancolombia/model/async/gateways/AsyncDataFlowGateway.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.model.async.gateways; 2 | 3 | import co.com.bancolombia.model.async.Credentials; 4 | import co.com.bancolombia.model.async.DeliverMessage; 5 | import reactor.core.publisher.Mono; 6 | 7 | public interface AsyncDataFlowGateway { 8 | Mono generateCredentials(String user_identifier); 9 | 10 | Mono deliverMessage(String channelRef, String userRef, DeliverMessage message); 11 | } 12 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/cloud_event/parser.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.CloudEvent.Parser do 2 | @moduledoc """ 3 | JSON parser for encoded cloud events. 4 | """ 5 | 6 | @type t :: module 7 | 8 | @typedoc "JSON encoded CloudEvent." 9 | @type encoded_json :: String.t() 10 | 11 | @typedoc "Map CloudEvent." 12 | @type json :: map() 13 | 14 | @doc """ 15 | Parse a JSON encoded CloudEvent and performs validation against a json schema 16 | """ 17 | @callback validate(json) :: {:ok, json()} | {:error, any()} 18 | end 19 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/lib/bridge_restapi_auth/oauth/config.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsRestapiAuth.Oauth.Config do 2 | @moduledoc """ 3 | Configuration for the OAuth2.0 authenticator. 4 | """ 5 | 6 | def iss, do: cfg() |> Map.get("allowed_issuers") 7 | 8 | def aud, do: cfg() |> Map.get("allowed_audiences") 9 | 10 | def jwks_url, do: cfg() |> Map.get("jwks") 11 | 12 | # def json_library, do: Jason 13 | 14 | defp cfg, do: get_in(Application.get_env(:channel_streams, :config), [:streams, "channel_authenticator", "config"]) 15 | 16 | end 17 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /channel-sender/config/benchee.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :channel_sender_ex, 4 | secret_base: 5 | {"aV4ZPOf7T7HX6GvbhwyBlDM8B9jfeiwi+9qkBnjXxUZXqAeTrehojWKHkV3U0kGc", "socket auth"}, 6 | initial_redelivery_time: 100, 7 | max_age: 900, 8 | # message_encoder: ChannelSenderEx.Transport.Encoders.BinaryEncoder, 9 | message_encoder: ChannelSenderEx.Transport.Encoders.JsonEncoder, 10 | no_start: true, 11 | socket_idle_timeout: 60000, 12 | socket_port: 8082, 13 | rest_port: 8081, 14 | topology: [ 15 | strategy: Cluster.Strategy.Gossip 16 | ] 17 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /clients/client-dart/example/lib/domain/model/channel_credentials.dart: -------------------------------------------------------------------------------- 1 | class ChannelCredential { 2 | final String channelRef; 3 | final String channelSecret; 4 | 5 | const ChannelCredential( 6 | {required this.channelRef, required this.channelSecret}); 7 | 8 | ChannelCredential.fromMap(dynamic map) 9 | : assert(map["channelRef"] != null, "'channelRef' cannot be null"), 10 | assert(map["channelSecret"] != null, "'channelSecret' cannot be null"), 11 | channelRef = map["channelRef"], 12 | channelSecret = map["channelSecret"]; 13 | } 14 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | 4 | 5 | ## Category 6 | 7 | - [ ] Feature 8 | - [ ] Fix 9 | 10 | ## Checklist 11 | 12 | - [ ] The pull request is complete according to the [guide of contributing](https://github.com/bancolombia/async-dataflow/wiki/Contributing) 13 | - [ ] Automated tests are written 14 | - [ ] The documentation is up-to-date 15 | - [ ] the version of the mix.exs was increased 16 | - [ ] The pull request has a descriptive title that describes what has changed, and provides enough context for the changelog 17 | -------------------------------------------------------------------------------- /clients/client-dart/lib/channel_sender_client.dart: -------------------------------------------------------------------------------- 1 | library; 2 | 3 | export 'src/async_client.dart' show AsyncClient; 4 | export 'src/async_client_conf.dart' 5 | show CustomConnectionState, MessageWithState, CustomAppLifecycleState; 6 | export 'src/async_client_event_handler.dart' 7 | show AsyncClientEvent, AsyncClientEventHandler; 8 | export 'src/async_config.dart' show AsyncConfig; 9 | export 'src/model/channel_message.dart'; 10 | export 'src/transport/transport.dart' show TransportType, transportFromString; 11 | export 'src/utils/async_data_flow_logger.dart' show AsyncDataFlowLogger; 12 | -------------------------------------------------------------------------------- /clients/client-dart/lib/src/decoder/json_decoder.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import '../model/channel_message.dart'; 4 | import '../utils/utils.dart'; 5 | import 'message_decoder.dart'; 6 | 7 | class JsonDecoder extends MessageDecoder { 8 | @override 9 | ChannelMessage decode(String event) { 10 | var eventAsList = jsonDecode('{"received": $event }')['received']; 11 | 12 | return ChannelMessage( 13 | checkString(eventAsList[0]), 14 | checkString(eventAsList[1]), 15 | checkString(eventAsList[2]), 16 | eventAsList[3], 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/main.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapApplication } from '@angular/platform-browser'; 2 | import { appConfig } from './app/app.config'; 3 | import { AppComponent } from './app/app.component'; 4 | import { HttpClientModule } from '@angular/common/http'; 5 | import { importProvidersFrom } from '@angular/core'; 6 | import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; 7 | 8 | bootstrapApplication(AppComponent, { 9 | providers: [importProvidersFrom(HttpClientModule), provideAnimationsAsync()] 10 | }) 11 | .catch((err) => console.error(err)); 12 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/user.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.User do 2 | @moduledoc """ 3 | An User representation for whom a channel is opened 4 | """ 5 | 6 | require Logger 7 | 8 | @type id() :: String.t() 9 | 10 | @type t() :: %__MODULE__{ 11 | id: id() 12 | } 13 | 14 | @derive Jason.Encoder 15 | defstruct id: nil, 16 | name: nil 17 | 18 | @doc """ 19 | creates a simple user representation 20 | """ 21 | @spec new(id()) :: struct() 22 | def new(id) do 23 | %__MODULE__{ 24 | id: id 25 | } 26 | end 27 | 28 | end 29 | -------------------------------------------------------------------------------- /channel-sender/test/channel_sender_ex/core/sender_application_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ChannelSenderEx.Core.SenderApplicationTest do 2 | use ExUnit.Case 3 | alias ChannelSenderEx.Core.SenderApplication 4 | 5 | test "Should create a new SenderApplication struct" do 6 | sender_application = SenderApplication.new(name: "app1", id: "1", api_key: "", api_secret: "") 7 | assert sender_application.name == "app1" 8 | end 9 | 10 | test "Should create a new SenderApplication with defaults" do 11 | sender_application = SenderApplication.new() 12 | assert sender_application.name == nil 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FrontAsync 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /channel-sender/test/channel_sender_ex/transport/entry_point_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ChannelSenderEx.Transport.EntryPointTest do 2 | use ExUnit.Case 3 | import Mock 4 | 5 | alias ChannelSenderEx.Transport.CowboyStarter 6 | alias ChannelSenderEx.Transport.EntryPoint 7 | 8 | test "Should load with custom port" do 9 | with_mock CowboyStarter, start_listeners: fn _ -> :ok end do 10 | EntryPoint.start(9099) 11 | end 12 | end 13 | 14 | test "Should load port from config" do 15 | with_mock CowboyStarter, start_listeners: fn _ -> :ok end do 16 | EntryPoint.start() 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /clients/client-dart/example/lib/infrastructure/notifier/log_notifier.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class LogNotifier extends ChangeNotifier { 4 | LogLevel level = LogLevel.all; 5 | 6 | List logs = []; 7 | void setLog(log) { 8 | logs.insert(0, log); 9 | notifyListeners(); 10 | } 11 | 12 | void setLevel(newLevel) { 13 | level = newLevel; 14 | notifyListeners(); 15 | } 16 | 17 | void clean() { 18 | logs.clear(); 19 | notifyListeners(); 20 | } 21 | 22 | List getLogs() { 23 | return logs; 24 | } 25 | } 26 | 27 | enum LogLevel { info, all } 28 | -------------------------------------------------------------------------------- /channel-sender/lib/channel_sender_ex/core/sender_application.ex: -------------------------------------------------------------------------------- 1 | defmodule ChannelSenderEx.Core.SenderApplication do 2 | @moduledoc false 3 | 4 | defstruct [:name, :id, :api_key, :api_secret] 5 | 6 | @type name() :: String.t() 7 | @type id() :: String.t() 8 | @type api_key() :: String.t() 9 | @type api_secret() :: String.t() 10 | 11 | @type t() :: %ChannelSenderEx.Core.SenderApplication{ 12 | name: name(), 13 | id: id(), 14 | api_key: api_key(), 15 | api_secret: api_secret() 16 | } 17 | 18 | def new(fields \\ []) do 19 | struct(__MODULE__, fields) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | --- 5 | 6 | **Is your feature request related to a problem? Please describe.** 7 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 8 | 9 | **Describe the solution you'd like** 10 | A clear and concise description of what you want to happen. 11 | 12 | **Describe alternatives you've considered** 13 | A clear and concise description of any alternative solutions or features you've considered. 14 | 15 | **Additional context** 16 | Add any other context or screenshots about the feature request here. -------------------------------------------------------------------------------- /clients/client-dart/example/README.md: -------------------------------------------------------------------------------- 1 | # app_async_flutter 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /examples/back-async-java/applications/app-service/src/main/java/co/com/bancolombia/config/UseCasesConfig.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.config; 2 | 3 | import org.springframework.context.annotation.ComponentScan; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.context.annotation.FilterType; 6 | 7 | @Configuration 8 | @ComponentScan(basePackages = "co.com.bancolombia.usecase", 9 | includeFilters = { 10 | @ComponentScan.Filter(type = FilterType.REGEX, pattern = "^.+UseCase$") 11 | }, 12 | useDefaultFilters = false) 13 | public class UseCasesConfig { 14 | } 15 | -------------------------------------------------------------------------------- /clients/client-js/test/cache.test.ts: -------------------------------------------------------------------------------- 1 | import * as chai from 'chai'; 2 | 3 | import { Cache } from "../src/cache"; 4 | 5 | const assert: Chai.AssertStatic = chai.assert; 6 | describe('Cache Tests', function () { 7 | 8 | it('Should save at most item count', () => { 9 | const cache = new Cache(3); 10 | cache.save('a', 1); 11 | cache.save('b', 2); 12 | cache.save('c', 3); 13 | cache.save('d', 4); 14 | assert.isUndefined(cache.get('a')); 15 | assert.equal(cache.get('b'), 2); 16 | assert.equal(cache.get('c'), 3); 17 | assert.equal(cache.get('d'), 4); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/lib/bridge_restapi_auth/passthrough_provider.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsRestapiAuth.PassthroughProvider do 2 | @behaviour StreamsRestapiAuth.Provider 3 | 4 | @moduledoc """ 5 | This Auth Provider behaviour implementation performs NO AUTHENTICATION at all. 6 | IMPORTANT: Write your own auth stratey by implementing the StreamsRestapiAuth.Provider behaviour. 7 | """ 8 | 9 | @doc """ 10 | Performs no validations, and returns an empty Map since no JWT parsing nor validation is performed. 11 | """ 12 | @impl true 13 | def validate_credentials(_all_headers) do 14 | {:ok, %{}} 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /clients/backend-client-elixir/bench/register_channels.exs: -------------------------------------------------------------------------------- 1 | alias AdfSenderConnector.Channel 2 | 3 | children = [ 4 | AdfSenderConnector.http_client_spec() 5 | ] 6 | 7 | Supervisor.start_link(children, strategy: :one_for_one) 8 | 9 | Benchee.run( 10 | %{ 11 | "register channels" => fn user_ref -> 12 | {:ok, pid} = AdfSenderConnector.channel_registration("app_ref1", user_ref) 13 | end 14 | }, 15 | before_each: fn (_) -> "user_" <> to_string(:rand.uniform(1000000000000)) end, 16 | warmup: 2, 17 | time: 8, 18 | parallel: 1, 19 | formatters: [{Benchee.Formatters.Console, extended_statistics: true}], 20 | profile_after: true 21 | ) -------------------------------------------------------------------------------- /clients/client-dart/test/model/channel_message_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:channel_sender_client/channel_sender_client.dart'; 2 | import 'package:test/test.dart'; 3 | 4 | void main() { 5 | test('mapper', () { 6 | ChannelMessage channelMessage = ChannelMessage.fromMap({ 7 | 'message_id': 'message_id', 8 | 'correlation_id': 'correlation_id', 9 | 'event': 'event', 10 | 'payload': 'payload' 11 | }); 12 | expect(channelMessage.messageId, 'message_id'); 13 | expect(channelMessage.correlationId, 'correlation_id'); 14 | expect(channelMessage.event, 'event'); 15 | expect(channelMessage.payload, 'payload'); 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | Async Dataflow 3 | 4 | 5 | 6 | 7 | sync_alt 8 | Requests 9 | 10 | 11 | 12 | 13 | 14 | 15 | settings 16 | Settings 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_secretmanager/README.md: -------------------------------------------------------------------------------- 1 | # Async Dataflow Streams Aws Secret Manager 2 | 3 | **TODO: Add description** 4 | 5 | ## Installation 6 | 7 | If [available in Hex](https://hex.pm/docs/publish), the package can be installed 8 | by adding `streams_secretmanager` to your list of dependencies in `mix.exs`: 9 | 10 | ```elixir 11 | def deps do 12 | [ 13 | {:streams_secretmanager, "~> 0.1.0"} 14 | ] 15 | end 16 | ``` 17 | 18 | Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) 19 | and published on [HexDocs](https://hexdocs.pm). Once published, the docs can 20 | be found at . 21 | 22 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_helper_config/test/streams_helper_config_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsHelperConfigTest do 2 | use ExUnit.Case 3 | doctest StreamsHelperConfig 4 | 5 | setup_all do 6 | :ok 7 | end 8 | 9 | test "loads empty configuration" do 10 | assert StreamsHelperConfig.get("foo_key", "default_bar") == "default_bar" 11 | end 12 | 13 | test "loads file" do 14 | file = Path.dirname(__ENV__.file) <> "/test-config.yaml" 15 | config = StreamsHelperConfig.load(file) 16 | assert get_in(config, [:sender, "url"]) == "http://localhost:8081" 17 | assert StreamsHelperConfig.get([:sender, "url"], nil) == "http://localhost:8081" 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/build.gradle.kts: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | val newBuildDir: Directory = 9 | rootProject.layout.buildDirectory 10 | .dir("../../build") 11 | .get() 12 | rootProject.layout.buildDirectory.value(newBuildDir) 13 | 14 | subprojects { 15 | val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) 16 | project.layout.buildDirectory.value(newSubprojectBuildDir) 17 | } 18 | subprojects { 19 | project.evaluationDependsOn(":app") 20 | } 21 | 22 | tasks.register("clean") { 23 | delete(rootProject.layout.buildDirectory) 24 | } 25 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_helper_config/README.md: -------------------------------------------------------------------------------- 1 | # Async Dataflow Channel Streams Config Helper 2 | 3 | Channel streams configuration helper. 4 | 5 | ## Installation 6 | 7 | If [available in Hex](https://hex.pm/docs/publish), the package can be installed 8 | by adding `streams_helper_config` to your list of dependencies in `mix.exs`: 9 | 10 | ```elixir 11 | def deps do 12 | [ 13 | {:streams_helper_config, "~> 0.1.0"} 14 | ] 15 | end 16 | ``` 17 | 18 | Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) 19 | and published on [HexDocs](https://hexdocs.pm). Once published, the docs can 20 | be found at . 21 | 22 | -------------------------------------------------------------------------------- /clients/client-dart/example/windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(runner LANGUAGES CXX) 3 | 4 | add_executable(${BINARY_NAME} WIN32 5 | "flutter_window.cpp" 6 | "main.cpp" 7 | "utils.cpp" 8 | "win32_window.cpp" 9 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 10 | "Runner.rc" 11 | "runner.exe.manifest" 12 | ) 13 | apply_standard_settings(${BINARY_NAME}) 14 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 15 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 16 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 17 | add_dependencies(${BINARY_NAME} flutter_assemble) 18 | -------------------------------------------------------------------------------- /examples/back-async-java/infrastructure/driven-adapters/rest-consumer/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':model') 3 | implementation 'org.springframework:spring-context' 4 | implementation 'org.springframework.boot:spring-boot-starter-webflux' 5 | implementation 'org.springframework.boot:spring-boot-starter-aop' 6 | implementation 'io.github.resilience4j:resilience4j-spring-boot3:2.3.0' 7 | implementation 'io.github.resilience4j:resilience4j-reactor:2.3.0' 8 | implementation 'io.micrometer:micrometer-core' 9 | 10 | testImplementation 'com.squareup.okhttp3:okhttp:4.12.0' 11 | testImplementation 'com.squareup.okhttp3:mockwebserver:4.12.0' 12 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # The directory Mix will write compiled artifacts to. 4 | /_build/ 5 | 6 | # If you run "mix test --cover", coverage assets end up here. 7 | /cover/ 8 | 9 | # The directory Mix downloads your dependencies sources to. 10 | /deps/ 11 | 12 | # Ignore .fetch files in case you like to edit your project deps locally. 13 | /.fetch 14 | 15 | # If the VM crashes, it generates a dump, let's ignore it too. 16 | erl_crash.dump 17 | 18 | # Also ignore archive artifacts (built via "mix archive.build"). 19 | *.ez 20 | 21 | # Temporary files, for example, from tests. 22 | /tmp/ 23 | 24 | /.elixir_ls/ 25 | 26 | /**/.elixir_ls/ 27 | 28 | .vscode 29 | 30 | .idea 31 | 32 | *.iml 33 | -------------------------------------------------------------------------------- /channel-sender/lib/channel_sender_ex/transport/message_encoder.ex: -------------------------------------------------------------------------------- 1 | defmodule ChannelSenderEx.Transport.MessageEncoder do 2 | @moduledoc """ 3 | Definition of generic encoding contract functions 4 | """ 5 | alias ChannelSenderEx.Core.ProtocolMessage 6 | 7 | @type encoded_type :: :text | :binary 8 | @type encoded_data :: {encoded_type(), iodata()} 9 | 10 | @callback encode_message(message :: ProtocolMessage.t()) :: 11 | {:ok, encoded_data()} | {:error, any()} 12 | @callback decode_message(message :: binary()) :: ProtocolMessage.t() 13 | 14 | @callback heartbeat_frame(hb_seq :: binary()) :: encoded_data() 15 | @callback simple_frame(event :: binary()) :: encoded_data() 16 | end 17 | -------------------------------------------------------------------------------- /clients/client-dart/example/lib/ui/atoms/button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Button extends StatelessWidget { 4 | const Button({Key? key, required this.onTap, required this.text}) 5 | : super(key: key); 6 | final Function onTap; 7 | final String text; 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | decoration: BoxDecoration( 13 | color: Colors.amber, borderRadius: BorderRadius.circular(15)), 14 | child: TextButton( 15 | onPressed: () { 16 | onTap(); 17 | }, 18 | child: Text(text, style: Theme.of(context).textTheme.bodyLarge), 19 | )); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /channel-sender/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | channel_sender_ex-*.tar 24 | 25 | .idea 26 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: daily 7 | - package-ecosystem: pub 8 | directory: clients/client-dart 9 | schedule: 10 | interval: daily 11 | - package-ecosystem: npm 12 | directory: clients/client-js 13 | schedule: 14 | interval: daily 15 | - package-ecosystem: Hex 16 | directory: clients/backend-client-elixir 17 | schedule: 18 | interval: daily 19 | - package-ecosystem: Hex 20 | directory: channel-sender 21 | schedule: 22 | interval: daily 23 | - package-ecosystem: Hex 24 | directory: channel-streams 25 | schedule: 26 | interval: daily 27 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/README.md: -------------------------------------------------------------------------------- 1 | # Async Dataflow Channel Streams Rest Api Auth 2 | 3 | Module for defining auth/autz mechanisms for the `:streams_restapi` app. 4 | 5 | ## Installation 6 | 7 | If [available in Hex](https://hex.pm/docs/publish), the package can be installed 8 | by adding `streams_restapi_auth` to your list of dependencies in `mix.exs`: 9 | 10 | ```elixir 11 | def deps do 12 | [ 13 | {:streams_restapi_auth, "~> 0.1.0"} 14 | ] 15 | end 16 | ``` 17 | 18 | Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) 19 | and published on [HexDocs](https://hexdocs.pm). Once published, the docs can 20 | be found at . 21 | 22 | -------------------------------------------------------------------------------- /clients/client-dart/lib/src/transport/types/noop_transport.dart: -------------------------------------------------------------------------------- 1 | import '../../model/channel_message.dart'; 2 | import '../transport.dart'; 3 | 4 | class NoopTransport implements Transport { 5 | @override 6 | Future connect() { 7 | return Future.value(false); 8 | } 9 | 10 | @override 11 | Future disconnect() { 12 | return Future.value(null); 13 | } 14 | 15 | @override 16 | void send(String message) { 17 | // No operation 18 | } 19 | 20 | @override 21 | bool isOpen() { 22 | return false; 23 | } 24 | 25 | @override 26 | TransportType name() { 27 | return TransportType.none; 28 | } 29 | 30 | @override 31 | Stream get stream => Stream.empty(); 32 | } 33 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/lib/streams_api.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsApi do 2 | @moduledoc """ 3 | Documentation for `ChannelStreamsApi`. 4 | """ 5 | 6 | use Application 7 | 8 | alias StreamsApi.Rest.BaseRouter 9 | 10 | @doc false 11 | @impl Application 12 | def start(_type, _args) do 13 | children = [ 14 | {Plug.Cowboy, 15 | scheme: :http, 16 | plug: BaseRouter, 17 | options: [ 18 | port: StreamsHelperConfig.get([:streams, "port"], 8080), 19 | protocol_options: [max_keepalive: 2_000, active_n: 200] 20 | ]} 21 | ] 22 | 23 | opts = [strategy: :one_for_one, name: StreamsApi.Supervisor] 24 | Supervisor.start_link(children, opts) 25 | end 26 | 27 | end 28 | -------------------------------------------------------------------------------- /examples/back-async-java/infrastructure/driven-adapters/async-event-bus/src/main/java/co/com/bancolombia/events/model/ObjectResponse.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.events.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAlias; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder(toBuilder = true) 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class ObjectResponse { 14 | private Credentials result; 15 | 16 | @Data 17 | public static class Credentials { 18 | @JsonAlias("channel_ref") 19 | String channelRef; 20 | @JsonAlias("channel_secret") 21 | String channelSecret; 22 | } 23 | } -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/components/logs/logs.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LogsComponent } from './logs.component'; 4 | 5 | describe('LogsComponent', () => { 6 | let component: LogsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [LogsComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(LogsComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/sender/notification_channel.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.Sender.NotificationChannel do 2 | @moduledoc """ 3 | Behaviour definition for a notification channel API (i.e Async Dataflow Channel Sender or hosted service like Pusher) 4 | """ 5 | 6 | @type application_ref() :: String.t() 7 | @type user_ref() :: String.t() 8 | @type client() :: any() 9 | @type args() :: map() 10 | 11 | @callback new(args()) :: client() 12 | @callback create_channel(client(), application_ref(), user_ref()) :: 13 | {:ok, result :: term} | {:error, reason :: term} 14 | @callback deliver_message(client(), request :: term) :: 15 | {:ok, result :: term} | {:error, reason :: term} 16 | end 17 | -------------------------------------------------------------------------------- /channel-streams/config/config.exs: -------------------------------------------------------------------------------- 1 | # This file is responsible for configuring your umbrella 2 | # and **all applications** and their dependencies with the 3 | # help of the Config module. 4 | # 5 | # Note that all applications in your umbrella share the 6 | # same configuration and dependencies, which is why they 7 | # all use the same configuration file. If you want different 8 | # configurations or dependencies per app, it is best to 9 | # move said applications out of the umbrella. 10 | import Config 11 | 12 | # Sample configuration: 13 | # 14 | # config :logger, :console, 15 | # level: :info, 16 | # format: "$date $time [$level] $metadata$message\n", 17 | # metadata: [:user_id] 18 | # 19 | 20 | import_config "#{Mix.env()}.exs" 21 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /clients/client-dart/test/transport/noop_transport_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:channel_sender_client/src/model/channel_message.dart'; 2 | import 'package:channel_sender_client/src/transport/transport.dart'; 3 | import 'package:channel_sender_client/src/transport/types/noop_transport.dart'; 4 | import 'package:test/test.dart'; 5 | 6 | void main() { 7 | group('Noop Transport Tests', () { 8 | test('Noop tests', () async { 9 | NoopTransport transport = NoopTransport(); 10 | 11 | expect(await transport.connect(), false); 12 | await transport.disconnect(); 13 | expect(transport.isOpen(), false); 14 | expect(transport.name(), TransportType.none); 15 | expect(transport.stream, isA>()); 16 | }); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /channel-streams/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Temporary files, for example, from tests. 23 | /tmp/ 24 | 25 | /.elixir_ls/ 26 | 27 | /**/.elixir_ls/ 28 | 29 | .vscode 30 | 31 | .idea 32 | 33 | *.iml -------------------------------------------------------------------------------- /clients/client-dart/lib/src/sse/utils.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | /// Enum to represent different types of EventFlux Log. 4 | enum LogEvent { 5 | info, 6 | error, 7 | reconnect, 8 | } 9 | 10 | /// Returns the emoji corresponding to the given [event]. 11 | String _getEmoji(LogEvent event) { 12 | switch (event) { 13 | case LogEvent.info: 14 | return 'ℹ️'; 15 | case LogEvent.error: 16 | return '❌'; 17 | case LogEvent.reconnect: 18 | return '🔄'; 19 | } 20 | } 21 | 22 | /// Logs the given [message] with the corresponding [event] and [tag]. 23 | void eventFluxLog(String message, LogEvent event, String? tag) { 24 | log( 25 | '${_getEmoji(event)} $message', 26 | name: tag ?? 'EventFlux ${DateTime.now()}', 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | streams_core-*.tar 24 | 25 | # Temporary files, for example, from tests. 26 | /tmp/ 27 | -------------------------------------------------------------------------------- /clients/client-dart/example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: app_async_flutter 2 | description: A Flutter project to implement client of async data flow to get asynchronous responses in real time. 3 | publish_to: "none" 4 | version: 1.0.0+1 5 | 6 | environment: 7 | sdk: ">=3.0.0 <4.0.0" 8 | flutter: ">=3.10.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | cupertino_icons: ^1.0.2 14 | channel_sender_client: 15 | path: '../' 16 | shared_preferences: ^2.0.13 17 | http: ^0.13.4 18 | flutter_dotenv: ^5.0.2 19 | logging: ^1.2.0 20 | uuid: ^3.0.7 21 | dependency_overrides: 22 | http: ^1.0.0 23 | dev_dependencies: 24 | flutter_test: 25 | sdk: flutter 26 | flutter_lints: ^1.0.0 27 | flutter: 28 | uses-material-design: true 29 | assets: 30 | - .env 31 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/components/requests/requests.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { RequestsComponent } from './requests.component'; 4 | 5 | describe('RequestsComponent', () => { 6 | let component: RequestsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [RequestsComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(RequestsComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/components/settings/settings.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SettingsComponent } from './settings.component'; 4 | 5 | describe('SettingsComponent', () => { 6 | let component: SettingsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [SettingsComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(SettingsComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_rabbitmq/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | streams_rabbitmq-*.tar 24 | 25 | # Temporary files, for example, from tests. 26 | /tmp/ 27 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | streams_restapi-*.tar 24 | 25 | # Temporary files, for example, from tests. 26 | /tmp/ 27 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/test/streams_api/rest/header_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsApi.Rest.HeaderTest do 2 | use ExUnit.Case 3 | use Plug.Test 4 | 5 | alias StreamsApi.Rest.Header 6 | 7 | @moduletag :capture_log 8 | 9 | test "Should extract headers" do 10 | conn = 11 | conn(:post, "/ext/channel", %{}) 12 | |> put_req_header("content-type", "application/json") 13 | |> put_req_header("authorization", "Bearer ey.a.c") 14 | |> put_req_header("session-tracker", "xxxx") 15 | 16 | assert {:ok, 17 | %{ 18 | "authorization" => "Bearer ey.a.c", 19 | "content-type" => "application/json", 20 | "session-tracker" => "xxxx" 21 | }} == Header.all_headers(conn) 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /clients/client-dart/example/windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | -------------------------------------------------------------------------------- /examples/back-async-java/infrastructure/driven-adapters/rest-consumer/src/main/java/co/com/bancolombia/consumer/models/DTODeliverMessage.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.consumer.models; 2 | 3 | import co.com.bancolombia.model.async.Message; 4 | import com.fasterxml.jackson.annotation.JsonAlias; 5 | import com.fasterxml.jackson.databind.PropertyNamingStrategy; 6 | import com.fasterxml.jackson.databind.annotation.JsonNaming; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.Getter; 10 | 11 | @Data 12 | @Builder 13 | @Getter 14 | @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) 15 | public class DTODeliverMessage { 16 | String channelRef; 17 | String messageId; 18 | String correlationId; 19 | Message messageData; 20 | String eventName; 21 | } 22 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_helper_config/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | streams_helper_config-*.tar 24 | 25 | # Temporary files, for example, from tests. 26 | /tmp/ 27 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | streams_restapi_auth-*.tar 24 | 25 | # Temporary files, for example, from tests. 26 | /tmp/ 27 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_secretmanager/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | streams_secretmanager-*.tar 24 | 25 | # Temporary files, for example, from tests. 26 | /tmp/ 27 | -------------------------------------------------------------------------------- /clients/client-js/src/decoder/json-decoder.ts: -------------------------------------------------------------------------------- 1 | /* The Json serializer for encoding and decoding messages */ 2 | 3 | 4 | import { ChannelMessage } from "../channel-message"; 5 | import { MessageDecoder } from "./message-decoder"; 6 | 7 | export class JsonDecoder implements MessageDecoder { 8 | 9 | public decode(messageEvent: MessageEvent): ChannelMessage { 10 | const [message_id, correlation_id, event, payload] = JSON.parse(messageEvent.data); 11 | return new ChannelMessage(message_id, event, correlation_id, payload); 12 | } 13 | 14 | public decode_sse(sse_event: string): ChannelMessage { 15 | const [message_id, correlation_id, event, payload] = JSON.parse(sse_event); 16 | return new ChannelMessage(message_id, event, correlation_id, payload); 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /channel-sender/bench/generators.exs: -------------------------------------------------------------------------------- 1 | alias ChannelSenderEx.Core.ChannelIDGenerator 2 | alias ChannelSenderEx.Core.Security.ChannelAuthenticator 3 | 4 | app_id = "app_22929" 5 | user_id = "user33243222" 6 | channel_id = ChannelIDGenerator.generate_channel_id(app_id, user_id) 7 | token = ChannelIDGenerator.generate_token(channel_id, app_id, user_id) 8 | 9 | Benchee.run( 10 | %{ 11 | "Generate Ids uuid4/uuid3" => fn -> ChannelIDGenerator.generate_channel_id(app_id, user_id) end, 12 | "Generate Secret channel token" => fn -> ChannelIDGenerator.generate_token(channel_id, app_id, user_id) end, 13 | "Authorize Channel" => fn -> ChannelAuthenticator.authorize_channel(channel_id, token) end, 14 | }, 15 | 16 | time: 8, 17 | # parallel: 12, 18 | formatters: [{Benchee.Formatters.Console, extended_statistics: true}] 19 | ) -------------------------------------------------------------------------------- /clients/client-dart/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | ## [3.2.0] 3 | - Add deduplication support for ws. 4 | ## [3.1.1] 5 | - Update dart sdk to `>= 3.8.0` 6 | ## [3.1.0] 7 | - Add connectivity awareness. 8 | - Add EventHandler interface. 9 | ## [3.0.0-beta.3] 10 | - Downgrade SDK requirement 11 | ## [3.0.0-beta] 12 | - Support SSE protocol 13 | ## [2.0.4] 14 | - Fix overflow of exp Backoff 15 | ## [2.0.3] 16 | - Fix reconnection with heartbeats issue 17 | - Improve logs 18 | - Refactor 19 | ## [2.0.2] 20 | - Fix reconnection 21 | - Refactor 22 | ## [2.0.1] 23 | - Null safety 24 | - Refactor 25 | ## [2.0.0] - Add Channel Message to `subscribeTo` 26 | ## [1.0.2] - Add Dart Code Linter 27 | ## [1.0.1] - Update of dependencies to comply with null safety definition 28 | ## [1.0.0] - First version of channel_sender_client 29 | 30 | -------------------------------------------------------------------------------- /examples/front-async-angular/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /.angular/cache 33 | .sass-cache/ 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | testem.log 38 | /typings 39 | 40 | # System files 41 | .DS_Store 42 | Thumbs.db 43 | environment.poc*.ts 44 | -------------------------------------------------------------------------------- /clients/client-js/src/utils.ts: -------------------------------------------------------------------------------- 1 | 2 | export class Utils { 3 | 4 | public static jitter(baseTime: number, randomFactor: number): number { 5 | const rest = baseTime * randomFactor 6 | return (baseTime - rest) + Math.random() * rest; 7 | } 8 | 9 | public static expBackoff(initial: number, max: number, actualRetry: number, jitterFn: (x: number) => number) { 10 | const base = initial * Math.pow(2, actualRetry); 11 | if (base > max) { 12 | return jitterFn(max) 13 | } else { 14 | return jitterFn(base); 15 | } 16 | } 17 | 18 | public static extractReason(reason): number { 19 | const reasonNumber = parseInt(reason); 20 | if (isNaN(reasonNumber)) { 21 | return 0; 22 | } 23 | return reasonNumber; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/test/streams_core/boundary/node_observer_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.Boundary.NodeObserverTest do 2 | use ExUnit.Case 3 | 4 | alias StreamsCore.Boundary.{ChannelRegistry, ChannelSupervisor, NodeObserver} 5 | 6 | setup do 7 | {:ok, rpid} = ChannelRegistry.start_link(nil) 8 | {:ok, spid} = ChannelSupervisor.start_link(nil) 9 | 10 | on_exit(fn -> 11 | Process.exit(rpid, :kill) 12 | Process.exit(spid, :kill) 13 | end) 14 | 15 | :ok 16 | end 17 | 18 | test "Should start nodeobserver" do 19 | {:ok, pid} = NodeObserver.start_link(nil) 20 | assert is_pid(pid) 21 | 22 | assert {:noreply, nil} == NodeObserver.handle_info({:nodeup, nil, nil}, nil) 23 | assert {:noreply, nil} == NodeObserver.handle_info({:nodedown, nil, nil}, nil) 24 | 25 | end 26 | 27 | end 28 | -------------------------------------------------------------------------------- /.github/workflows/secret-scanner.yml: -------------------------------------------------------------------------------- 1 | name: Leaked Secrets Scan 2 | on: 3 | push: 4 | branches: [ master ] 5 | pull_request: 6 | branches: [ master ] 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | TruffleHog: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Harden Runner 15 | uses: step-security/harden-runner@248ae51c2e8cc9622ecf50685c8bf7150c6e8813 16 | with: 17 | egress-policy: audit 18 | - name: Checkout code 19 | uses: actions/checkout@d0651293c4a5a52e711f25b41b05b2212f385d28 20 | with: 21 | fetch-depth: 0 22 | - name: TruffleHog OSS 23 | uses: trufflesecurity/trufflehog@212aa9ba1e4698807023a1c11be6f9f77bef2a2c 24 | with: 25 | path: ./ 26 | base: ${{ github.event.repository.default_branch }} 27 | head: HEAD 28 | -------------------------------------------------------------------------------- /clients/backend-client-elixir/bench/deliver_message.exs: -------------------------------------------------------------------------------- 1 | alias AdfSenderConnector.Message 2 | 3 | children = [ 4 | AdfSenderConnector.http_client_spec() 5 | ] 6 | 7 | Supervisor.start_link(children, strategy: :one_for_one) 8 | 9 | {:ok, response} = AdfSenderConnector.channel_registration("a", "b") 10 | channel_ref = Map.fetch!(response, "channel_ref") 11 | 12 | create_msg = fn -> 13 | msgid = "#{UUID.uuid4()}" 14 | Message.new(channel_ref, msgid, nil, "{ \"hello\": \"world\" }", "event.name") 15 | end 16 | 17 | Benchee.run( 18 | %{ 19 | "deliver messages" => {fn msg -> 20 | AdfSenderConnector.route_message(msg) 21 | end, before_scenario: fn _input -> create_msg.() end} 22 | }, 23 | warmup: 2, 24 | time: 8, 25 | parallel: 1, 26 | formatters: [{Benchee.Formatters.Console, extended_statistics: true}], 27 | profile_after: true 28 | ) 29 | -------------------------------------------------------------------------------- /examples/back-async-java/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | //mavenLocal() 4 | //maven { url '...' } 5 | gradlePluginPortal() 6 | } 7 | } 8 | 9 | rootProject.name = 'back-async' 10 | 11 | include ':app-service' 12 | include ':model' 13 | include ':usecase' 14 | project(':app-service').projectDir = file('./applications/app-service') 15 | project(':model').projectDir = file('./domain/model') 16 | project(':usecase').projectDir = file('./domain/usecase') 17 | include ':reactive-web' 18 | project(':reactive-web').projectDir = file('./infrastructure/entry-points/reactive-web') 19 | include ':rest-consumer' 20 | project(':rest-consumer').projectDir = file('./infrastructure/driven-adapters/rest-consumer') 21 | include ':async-event-bus' 22 | project(':async-event-bus').projectDir = file('./infrastructure/driven-adapters/async-event-bus') -------------------------------------------------------------------------------- /.github/workflows/build-client-js.yaml: -------------------------------------------------------------------------------- 1 | name: client-js-build 2 | on: 3 | pull_request: 4 | paths: 5 | - 'clients/client-js/**' 6 | branches: 7 | - master 8 | jobs: 9 | build: 10 | defaults: 11 | run: 12 | working-directory: clients/client-js 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | # Setup .npmrc file to publish to npm 17 | - uses: actions/setup-node@v4 18 | with: 19 | node-version: '22.15.0' 20 | - run: npm install 21 | name: Install dependencies 22 | - run: npm run build 23 | name: Build 24 | - run: npm run test 25 | name: Test 26 | - name: SonarQube Scan 27 | uses: SonarSource/sonarqube-scan-action@v4 28 | with: 29 | projectBaseDir: clients/client-js 30 | env: 31 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN_CLIENT_JS }} -------------------------------------------------------------------------------- /clients/client-dart/test/transport/max_retries_exception_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:channel_sender_client/src/exceptions/max_retries_exception.dart'; 2 | import 'package:test/test.dart'; 3 | 4 | void main() { 5 | test('should create exception with message', () { 6 | final exception = MaxRetriesException('Retry limit exceeded'); 7 | 8 | expect(exception.message, 'Retry limit exceeded'); 9 | }); 10 | 11 | test('should throw MaxRetriesException', () { 12 | void throwException() { 13 | throw MaxRetriesException('Too many attempts'); 14 | } 15 | 16 | expect(throwException, throwsA(isA())); 17 | }); 18 | 19 | test('should have correct toString output', () { 20 | final exception = MaxRetriesException('Failed after 3 retries'); 21 | 22 | expect(exception.toString(), 'MaxRetriesException: Failed after 3 retries'); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /.github/workflows/release-client-js.yml: -------------------------------------------------------------------------------- 1 | name: client-js-release 2 | on: 3 | push: 4 | tags: 5 | - 'chanjs_*' # Push events to matching chanjs_*, i.e. chanjs_0.2.0 6 | jobs: 7 | build: 8 | defaults: 9 | run: 10 | working-directory: clients/client-js 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: actions/setup-node@v4 15 | with: 16 | node-version: '20.18.1' 17 | registry-url: 'https://registry.npmjs.org' 18 | - run: npm install 19 | - run: npm publish --access public 20 | env: 21 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 22 | - uses: actions/setup-node@v4 23 | with: 24 | registry-url: 'https://npm.pkg.github.com' 25 | scope: '@bancolombia' 26 | - run: npm publish 27 | env: 28 | NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | -------------------------------------------------------------------------------- /clients/client-dart/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: channel_sender_client 2 | description: A Dart client for sending and receiving real-time events using WebSocket or SSE over Async DataFlow channels. 3 | version: 3.2.0 4 | homepage: https://github.com/bancolombia/async-dataflow 5 | repository: https://github.com/bancolombia/async-dataflow.git 6 | 7 | environment: 8 | sdk: '>=3.8.0 <4.0.0' 9 | flutter: ">=3.32.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | web_socket_channel: ^2.3.0 15 | logging: ^1.1.0 16 | logger: ^1.0.0 17 | validators: ^3.0.0 18 | http: ^1.1.0 19 | connectivity_plus: ^6.0.1 20 | rxdart: ^0.27.7 21 | 22 | dependency_overrides: 23 | source_span: 1.9.1 24 | 25 | dev_dependencies: 26 | flutter_test: 27 | sdk: flutter 28 | test: ^1.26.0 29 | mocktail: ^1.0.0 30 | flutter_lints: ^2.0.3 31 | dart_code_linter: ^3.0.0 32 | build_runner: ^2.2.0 33 | -------------------------------------------------------------------------------- /channel-sender/deploy_samples/haproxy/haproxy.cfg: -------------------------------------------------------------------------------- 1 | global 2 | maxconn 50000 3 | 4 | defaults 5 | mode http 6 | timeout connect 5000ms 7 | timeout client 50000ms 8 | timeout server 50000ms 9 | 10 | frontend http-rest 11 | bind *:81 12 | stats enable 13 | stats uri /admin?stats 14 | default_backend servers-rest 15 | 16 | backend servers-rest 17 | balance roundrobin 18 | server webrest1 127.0.0.1:8081 maxconn 3200 19 | server webrest2 127.0.0.1:8091 maxconn 3200 20 | server webrest3 127.0.0.1:8071 maxconn 3200 21 | 22 | frontend http-ws 23 | bind *:82 24 | stats enable 25 | stats uri /admin?stats 26 | default_backend servers-ws 27 | 28 | backend servers-ws 29 | balance roundrobin 30 | server webws1 127.0.0.1:8082 maxconn 3200 31 | server webws2 127.0.0.1:8092 maxconn 3200 32 | server webws3 127.0.0.1:8072 maxconn 3200 33 | 34 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/lib/bridge_restapi_auth/application.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsRestapiAuth.Application do 2 | @moduledoc false 3 | 4 | use Application 5 | require Logger 6 | 7 | @doc false 8 | @impl Application 9 | def start(_type, _args) do 10 | 11 | children = case (Application.get_env(:streams_core, :env)) do 12 | e when e in [:test, :bench] -> 13 | [] 14 | _ -> 15 | [ 16 | build_child_spec(Application.get_env(:channel_streams, :config)) 17 | ] 18 | end 19 | 20 | Logger.info("StreamsRestapiAuth.Application starting...") 21 | 22 | opts = [strategy: :one_for_one, name: StreamsRestapiAuth.Supervisor] 23 | Supervisor.start_link(children, opts) 24 | end 25 | 26 | def build_child_spec(_config), do: {StreamsRestapiAuth.Oauth.Strategy, 27 | [first_fetch_sync: true, explicit_alg: "RS256"]} 28 | 29 | end 30 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/cloud_event/mutator/default_mutator.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.CloudEvent.Mutator.DefaultMutator do 2 | @moduledoc """ 3 | A mutator performs changes to the cloud event before sending it 4 | to the client. 5 | 6 | In this case the DefaultMutator does not perform any changes. 7 | 8 | You can create your own mutators by implement the Mutator behaviour. 9 | """ 10 | @behaviour StreamsCore.CloudEvent.Mutator 11 | 12 | alias StreamsCore.CloudEvent 13 | 14 | @type t() :: CloudEvent.t() 15 | 16 | @doc false 17 | @impl true 18 | def applies?(_cloud_event, _config \\ nil) do 19 | true 20 | end 21 | 22 | @doc false 23 | @impl true 24 | def mutate(cloud_event, _config \\ nil) do 25 | # No changes are made to the input cloud_event. You can implement mutation functionality here. 26 | {:ok, cloud_event} 27 | end 28 | 29 | end 30 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_secretmanager/lib/streams_secret_manager/application.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsSecretManager.Application do 2 | # See https://hexdocs.pm/elixir/Application.html 3 | # for more information on OTP Applications 4 | @moduledoc false 5 | 6 | use Application 7 | require Logger 8 | alias StreamsSecretManager.AwsConfig 9 | 10 | @impl true 11 | def start(_type, args) do 12 | children = [ 13 | {StreamsSecretManager, args} 14 | ] 15 | 16 | AwsConfig.setup_aws_config( 17 | Application.get_env(:channel_streams, :config) 18 | ) 19 | 20 | Logger.info("StreamsSecretManager.Application starting...") 21 | 22 | # See https://hexdocs.pm/elixir/Supervisor.html 23 | # for other strategies and supported options 24 | opts = [strategy: :one_for_one, name: StreamsSecretManager.Supervisor] 25 | Supervisor.start_link(children, opts) 26 | end 27 | 28 | end 29 | -------------------------------------------------------------------------------- /clients/client-dart/example/windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | connectivity_plus 7 | ) 8 | 9 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 10 | ) 11 | 12 | set(PLUGIN_BUNDLED_LIBRARIES) 13 | 14 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 15 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 16 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 19 | endforeach(plugin) 20 | 21 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 22 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 23 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 24 | endforeach(ffi_plugin) 25 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/test/streams_core/user_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.UserTest do 2 | use ExUnit.Case 3 | 4 | alias StreamsCore.User 5 | 6 | @moduletag :capture_log 7 | 8 | # setup do 9 | # test_request = 10 | # ChannelRequest.new( 11 | # %{ 12 | # "user-id" => "CC1989637100", 13 | # "application-id" => "abc321" 14 | # }, 15 | # nil, 16 | # %{ 17 | # "channelAlias" => "my-alias" 18 | # }, 19 | # nil 20 | # ) 21 | 22 | # on_exit(fn -> 23 | # Application.delete_env(:channel_streams, :request_user_identifier) 24 | # end) 25 | 26 | # {:ok, init_args: %{request: test_request}} 27 | # end 28 | 29 | test "Should build new user" do 30 | user = User.new("abc321") 31 | assert %User{} = User.new(nil) 32 | assert user != nil 33 | assert user.id == "abc321" 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | val flutterSdkPath = 3 | run { 4 | val properties = java.util.Properties() 5 | file("local.properties").inputStream().use { properties.load(it) } 6 | val flutterSdkPath = properties.getProperty("flutter.sdk") 7 | require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } 8 | flutterSdkPath 9 | } 10 | 11 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 12 | 13 | repositories { 14 | google() 15 | mavenCentral() 16 | gradlePluginPortal() 17 | } 18 | } 19 | 20 | plugins { 21 | id("dev.flutter.flutter-plugin-loader") version "1.0.0" 22 | id("com.android.application") version "8.9.1" apply false 23 | id("org.jetbrains.kotlin.android") version "2.1.0" apply false 24 | } 25 | 26 | include(":app") 27 | -------------------------------------------------------------------------------- /.github/workflows/release-client-dart.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Async DataFlow channel sender Dart client 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'channel_sender_client_*' # Push events to matching chanjs_*, i.e. chanjs_0.2.0 7 | jobs: 8 | publish: 9 | name: 'Publish to pub.dev' 10 | environment: pub.dev 11 | permissions: 12 | id-token: write 13 | defaults: 14 | run: 15 | working-directory: clients/client-dart 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v3 19 | - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f 20 | - name: Setup Flutter 21 | uses: bancolombia/flutter-setup-action@v1.1 22 | with: 23 | channel: 'stable' 24 | flutter-version: '3.35.0' 25 | - name: Install dependencies 26 | run: dart pub get 27 | - name: Publish to pub.dev 28 | run: dart pub publish -f -------------------------------------------------------------------------------- /channel-sender/test/channel_sender_ex/transport/transport_spec_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ChannelSenderEx.Transport.TransportSpecTest do 2 | use ExUnit.Case, async: true 3 | 4 | test "my_macro defines the generated_macro function" do 5 | defmodule TestTransport do 6 | alias ChannelSenderEx.Transport.TransportSpec 7 | use TransportSpec 8 | end 9 | 10 | assert function_exported?(TestTransport, :lookup_channel_addr, 1) 11 | assert TestTransport.lookup_channel_addr({:error, "foo"}) == {:error, "foo"} 12 | end 13 | 14 | test "my_macro defines the generated_macro function 2" do 15 | defmodule TestTransport do 16 | alias ChannelSenderEx.Transport.TransportSpec 17 | use TransportSpec, option: :sse 18 | end 19 | 20 | assert function_exported?(TestTransport, :lookup_channel_addr, 1) 21 | assert TestTransport.lookup_channel_addr({:error, "foo"}) == {:error, "foo"} 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/components/requests/requests.component.css: -------------------------------------------------------------------------------- 1 | .arrow_upward { 2 | color: #4caf50; 3 | } 4 | 5 | .arrow_downward { 6 | color: #f44336; 7 | } 8 | 9 | .mat-mdc-raised-button { 10 | margin: 8px 8px 8px 0; 11 | } 12 | 13 | /* Basic styling for the circular indicator */ 14 | .indicator { 15 | margin: 10px; 16 | width: 10px; 17 | height: 10px; 18 | border-radius: 50%; 19 | /* Makes it circular */ 20 | transition: background-color 0.3s ease; 21 | /* Smooth color transition */ 22 | } 23 | 24 | /* When the state is true (active), the circle will be green */ 25 | .indicator.active { 26 | background-color: green; 27 | } 28 | 29 | /* When the state is false (inactive), the circle will be red */ 30 | .indicator.inactive { 31 | background-color: red; 32 | } 33 | 34 | /* Optional: Add hover effect for better interaction */ 35 | .indicator:hover { 36 | opacity: 0.8; 37 | } -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/cloud_event/mutator.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.CloudEvent.Mutator do 2 | @moduledoc """ 3 | Definition for a Mutator. A Mutator role is to perform changes to 4 | the cloud event before is sent to the client via ADF Channel Sender. 5 | """ 6 | 7 | alias StreamsCore.CloudEvent 8 | 9 | @type cloud_event() :: CloudEvent.t() 10 | @type config() :: map() 11 | 12 | @doc """ 13 | Function that defines if the mutator should be applied to the cloud event 14 | """ 15 | @callback applies?(cloud_event(), config()) :: boolean() | {:error, any()} 16 | 17 | @doc """ 18 | Apply the mutator logic to the CloudEvent, an :ok result means the CloudEvent was mutated, else a :noop result means 19 | the CloudEvent was not mutated due an error invoking the related endpoint. 20 | """ 21 | @callback mutate(cloud_event(), config()) :: {:ok | :noop, cloud_event()} | {:error, any()} 22 | end 23 | -------------------------------------------------------------------------------- /examples/back-async-java/infrastructure/entry-points/reactive-web/src/main/java/co/com/bancolombia/api/RouterRest.java: -------------------------------------------------------------------------------- 1 | package co.com.bancolombia.api; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.reactive.function.server.RouterFunction; 6 | import org.springframework.web.reactive.function.server.ServerResponse; 7 | 8 | import static org.springframework.web.reactive.function.server.RequestPredicates.GET; 9 | import static org.springframework.web.reactive.function.server.RouterFunctions.route; 10 | 11 | @Configuration 12 | public class RouterRest { 13 | @Bean 14 | public RouterFunction routerFunction(Handler handler) { 15 | return route(GET("/api/business"), handler::listenBusiness) 16 | .andRoute(GET("/api/credentials"), handler::listenGenerateCredentials); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/components/logs/logs.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | Captured Logs 5 | 6 | 7 |
8 |
9 | {{ log.message }} 10 |
11 |
12 |
13 | 14 | 17 | 20 | 21 |
22 |
-------------------------------------------------------------------------------- /examples/front-async-angular/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RouterOutlet } from '@angular/router'; 3 | import { CommonModule } from '@angular/common'; 4 | import { MatToolbarModule } from '@angular/material/toolbar'; 5 | import { MatTabsModule } from '@angular/material/tabs'; 6 | import { MatIconModule } from '@angular/material/icon'; 7 | import { LogsComponent } from "./components/logs/logs.component"; 8 | import { RequestsComponent } from './components/requests/requests.component'; 9 | import { SettingsComponent } from './components/settings/settings.component'; 10 | 11 | @Component({ 12 | selector: 'app-root', 13 | standalone: true, 14 | imports: [RouterOutlet, CommonModule, MatToolbarModule, MatIconModule, MatTabsModule, LogsComponent, RequestsComponent, SettingsComponent], 15 | templateUrl: './app.component.html', 16 | styleUrl: './app.component.css' 17 | }) 18 | export class AppComponent { 19 | } -------------------------------------------------------------------------------- /channel-sender/rel/env.sh.eex: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Sets and enables heart (recommended only in daemon mode) 4 | # case $RELEASE_COMMAND in 5 | # daemon*) 6 | # HEART_COMMAND="$RELEASE_ROOT/bin/$RELEASE_NAME $RELEASE_COMMAND" 7 | # export HEART_COMMAND 8 | # export ELIXIR_ERL_OPTIONS="-heart" 9 | # ;; 10 | # *) 11 | # ;; 12 | # esac 13 | 14 | # Set the release to work across nodes. If using the long name format like 15 | # the one below (my_app@127.0.0.1), you need to also uncomment the 16 | # RELEASE_DISTRIBUTION variable below. Must be "sname", "name" or "none". 17 | # export RELEASE_DISTRIBUTION=name 18 | # export RELEASE_NODE=<%= @release.name %>@127.0.0.1 19 | 20 | if [ -z ${RELEASE_DISTRIBUTION+x} ]; then echo "RELEASE_DISTRIBUTION is unset"; else echo "RELEASE_DISTRIBUTION is set to '$RELEASE_DISTRIBUTION'"; fi 21 | if [ -z ${RELEASE_NODE+x} ]; then echo "RELEASE_NODE is unset"; else echo "RELEASE_NODE is set to '$RELEASE_NODE'"; fi 22 | -------------------------------------------------------------------------------- /clients/client-dart/example/lib/ui/atoms/input_field.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class InputField extends StatelessWidget { 4 | const InputField( 5 | {Key? key, 6 | required this.textEditingController, 7 | this.keyboardType = TextInputType.number, 8 | required this.labelText, 9 | this.icon}) 10 | : super(key: key); 11 | 12 | final TextEditingController textEditingController; 13 | final TextInputType? keyboardType; 14 | final String labelText; 15 | final IconData? icon; 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return TextField( 20 | controller: textEditingController, 21 | keyboardType: keyboardType, 22 | style: const TextStyle(color: Colors.white), 23 | decoration: InputDecoration( 24 | border: const UnderlineInputBorder(), 25 | icon: Icon(icon), 26 | labelText: labelText, 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /clients/client-dart/example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsRestapiAuth.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :streams_restapi_auth, 7 | version: "0.1.0", 8 | build_path: "../../_build", 9 | config_path: "../../config/config.exs", 10 | deps_path: "../../deps", 11 | lockfile: "../../mix.lock", 12 | elixir: "~> 1.15", 13 | start_permanent: Mix.env() == :prod, 14 | deps: deps(), 15 | test_coverage: [tool: ExCoveralls] 16 | ] 17 | end 18 | 19 | # Run "mix help compile.app" to learn about applications. 20 | def application do 21 | [ 22 | extra_applications: [:logger] 23 | ] 24 | end 25 | 26 | # Run "mix help deps" to learn about dependencies. 27 | defp deps do 28 | [ 29 | {:jason, "~> 1.4"}, 30 | {:joken, "~> 2.6"}, 31 | {:joken_jwks, "~> 1.6.0"}, 32 | {:mock, "~> 0.3.8", only: :test}, 33 | ] 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /channel-sender/deploy_samples/k8s/libcluster-kubernetes/roles.yaml: -------------------------------------------------------------------------------- 1 | ## rol required to allow query of existing pods in namespace 2 | ## in order to form the erlang cluster. 3 | ## This is required by libcluster strategy Cluster.Strategy.Kubernetes. 4 | ## To see other strategies supported by libcluster, see library documentation. 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | kind: Role 7 | metadata: 8 | creationTimestamp: null 9 | name: read-pods-role 10 | namespace: sendernm 11 | rules: 12 | - apiGroups: 13 | - "" 14 | resources: 15 | - pods 16 | verbs: 17 | - get 18 | - list 19 | 20 | --- 21 | apiVersion: rbac.authorization.k8s.io/v1 22 | kind: RoleBinding 23 | metadata: 24 | creationTimestamp: null 25 | name: role-binding 26 | namespace: sendernm 27 | roleRef: 28 | apiGroup: rbac.authorization.k8s.io 29 | kind: Role 30 | name: read-pods-role 31 | subjects: 32 | - kind: ServiceAccount 33 | name: default 34 | namespace: sendernm -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/app_client.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.AppClient do 2 | @moduledoc """ 3 | An application that uses ADF to route messages to front end 4 | """ 5 | 6 | require Logger 7 | 8 | @default_channel_inactivity_timeout 420 # in seconds = 7 minutes 9 | 10 | @type id() :: String.t() 11 | @type name() :: String.t() 12 | 13 | @type t() :: %__MODULE__{ 14 | id: id(), 15 | name: name(), 16 | channel_timeout: integer() 17 | } 18 | 19 | @derive Jason.Encoder 20 | defstruct id: nil, 21 | name: nil, 22 | channel_timeout: 0 23 | 24 | @doc """ 25 | creates a simple client application representation 26 | """ 27 | @spec new(id(), name(), integer()) :: t() 28 | def new(id, name, ch_timeout \\ @default_channel_inactivity_timeout) do 29 | %__MODULE__{ 30 | id: id, 31 | name: name, 32 | channel_timeout: ch_timeout 33 | } 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_helper_config/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsHelperConfig.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :streams_helper_config, 7 | version: "0.1.0", 8 | build_path: "../../_build", 9 | config_path: "../../config/config.exs", 10 | deps_path: "../../deps", 11 | lockfile: "../../mix.lock", 12 | elixir: "~> 1.15", 13 | start_permanent: Mix.env() == :prod, 14 | deps: deps(), 15 | test_coverage: [tool: ExCoveralls] 16 | ] 17 | end 18 | 19 | # Run "mix help compile.app" to learn about applications. 20 | def application do 21 | [ 22 | extra_applications: [:logger], 23 | mod: {StreamsHelperConfig.Application, []} 24 | ] 25 | end 26 | 27 | # Run "mix help deps" to learn about dependencies. 28 | defp deps do 29 | [ 30 | {:vapor, "~> 0.10.0"}, 31 | {:dialyxir, "~> 1.4", only: [:dev], runtime: false} 32 | ] 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /channel-sender/lib/channel_sender_ex/transport/entry_point.ex: -------------------------------------------------------------------------------- 1 | defmodule ChannelSenderEx.Transport.EntryPoint do 2 | @moduledoc """ 3 | Configure application web entry points 4 | """ 5 | alias ChannelSenderEx.Transport.CowboyStarter 6 | alias ChannelSenderEx.Transport.LongPoll 7 | alias ChannelSenderEx.Transport.Socket 8 | alias ChannelSenderEx.Transport.Sse 9 | 10 | def start(port \\ ext_port()) do 11 | routes(port) |> CowboyStarter.start_listeners() 12 | end 13 | 14 | def routes(port) do 15 | [ 16 | {:external_server, port, 17 | [ 18 | {"/ext/socket", Socket, []}, 19 | {"/ext/longpoll/:ran/xhr", LongPoll, []}, 20 | {"/ext/sse", Sse, []} 21 | # Enable below line for load testing purposes 22 | # {:_, Plug.Cowboy.Handler, {ChannelSenderEx.Transport.Rest.RestController, []}} 23 | ]} 24 | ] 25 | end 26 | 27 | defp ext_port, do: Application.get_env(:channel_sender_ex, :socket_port, 8082) 28 | end 29 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/test/streams_core/boundary/channel_registry_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.Boundary.ChannelRegistryTest do 2 | use ExUnit.Case 3 | 4 | import Mock 5 | 6 | alias Horde.Registry 7 | alias StreamsCore.Boundary.ChannelRegistry 8 | 9 | test "Should init registry" do 10 | pid = ChannelRegistry.start_link(nil) 11 | assert pid != nil 12 | end 13 | 14 | test "Should lookup channel" do 15 | with_mocks([ 16 | {Registry, [], [lookup: fn _ref -> [{:c.pid(0, 250, 0), "xx"}] end]} 17 | ]) do 18 | pid = ChannelRegistry.lookup_channel_addr("A") 19 | assert pid != nil 20 | # assert Process.info(pid, :priority) == {:priority, :normal} 21 | end 22 | end 23 | 24 | test "Should not lookup channel" do 25 | with_mocks([ 26 | {Registry, [], [lookup: fn _ref -> [] end]} 27 | ]) do 28 | nopid = ChannelRegistry.lookup_channel_addr("B") 29 | assert nopid == :noproc 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /channel-streams/deploy_samples/k8s/libcluster-kubernetes/roles.yaml: -------------------------------------------------------------------------------- 1 | ## rol required to allow query of existing pods in namespace 2 | ## in order to form the erlang cluster. 3 | ## This is required by libcluster strategy Cluster.Strategy.Kubernetes. 4 | ## To see other strategies supported by libcluster, see library documentation. 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | kind: Role 7 | metadata: 8 | creationTimestamp: null 9 | name: read-pods-role 10 | namespace: streamsnm 11 | rules: 12 | - apiGroups: 13 | - "" 14 | resources: 15 | - pods 16 | verbs: 17 | - get 18 | - list 19 | 20 | --- 21 | apiVersion: rbac.authorization.k8s.io/v1 22 | kind: RoleBinding 23 | metadata: 24 | creationTimestamp: null 25 | name: role-binding 26 | namespace: streamsnm 27 | roleRef: 28 | apiGroup: rbac.authorization.k8s.io 29 | kind: Role 30 | name: read-pods-role 31 | subjects: 32 | - kind: ServiceAccount 33 | name: default 34 | namespace: streamsnm -------------------------------------------------------------------------------- /clients/client-dart/example/windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /channel-sender/lib/channel_sender_ex/transport/encoders/json_encoder.ex: -------------------------------------------------------------------------------- 1 | defmodule ChannelSenderEx.Transport.Encoders.JsonEncoder do 2 | @moduledoc """ 3 | Encoder for json format 4 | """ 5 | alias ChannelSenderEx.Core.ProtocolMessage 6 | alias ChannelSenderEx.Transport.MessageEncoder 7 | 8 | @behaviour MessageEncoder 9 | 10 | @impl MessageEncoder 11 | def encode_message(message) do 12 | case Jason.encode(ProtocolMessage.to_socket_message(message)) do 13 | {:ok, data} -> {:ok, {:text, data}} 14 | err -> err 15 | end 16 | end 17 | 18 | @impl MessageEncoder 19 | def decode_message(message) do 20 | Jason.decode!(message) |> ProtocolMessage.from_socket_message() 21 | end 22 | 23 | @impl MessageEncoder 24 | def heartbeat_frame(seq) do 25 | {:text, ["[\"\", \"", seq, "\", \":hb\", \"\"]"]} 26 | end 27 | 28 | @impl MessageEncoder 29 | def simple_frame(event) do 30 | {:text, ["[\"\", \"\", \"", event, "\", \"\"]"]} 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/test/oauth/strategy_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsRestapiAuth.Oauth.StrategyTest do 2 | use ExUnit.Case 3 | 4 | alias StreamsRestapiAuth.Oauth.Strategy 5 | 6 | @moduletag :capture_log 7 | 8 | setup_all do 9 | cfg = %{ 10 | streams: %{ 11 | "channel_authenticator" => %{ 12 | "auth_module" => Elixir.StreamsRestapiAuth.JwtValidationProvider, 13 | "config" => %{ 14 | "jwks" => "https://someprovider.com/keys", 15 | "allowed_audiences" => ["aud1", "aud2"], 16 | "allowed_issuers" => ["iss1", "some.issuer"], 17 | } 18 | } 19 | } 20 | } 21 | Application.put_env(:channel_streams, :config, cfg) 22 | 23 | on_exit(fn -> 24 | Application.delete_env(:channel_streams, :config) 25 | end) 26 | end 27 | 28 | test "should build opts for strategy" do 29 | assert Strategy.init_opts([]) == [jwks_url: "https://someprovider.com/keys"] 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | html, body { height: 100%; } 4 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } 5 | 6 | /* app.component.css */ 7 | .log-container { 8 | max-width: 800px; 9 | margin: 0 auto; 10 | padding: 20px; 11 | } 12 | 13 | .console { 14 | width: 100%; 15 | height: 300px; 16 | background-color: #222; 17 | color: white; 18 | padding: 10px; 19 | font-family: Consolas, "Courier New", monospace; 20 | overflow-y: auto; 21 | white-space: pre-wrap; 22 | word-wrap: break-word; 23 | box-sizing: border-box; 24 | border: 1px solid #444; 25 | } 26 | 27 | .console div { 28 | padding: 5px 0; 29 | } 30 | 31 | .console .log { 32 | color: #f1f1f1; 33 | } 34 | 35 | .console .warn { 36 | color: #ffcc00; 37 | } 38 | 39 | .console .error { 40 | color: #ff3333; 41 | } 42 | 43 | .console .info { 44 | color: #66cc66; 45 | } -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/lib/bridge_restapi_auth/oauth/Token.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsRestapiAuth.Oauth.Token do 2 | @moduledoc """ 3 | Token configuration for the OAuth2.0 token. 4 | """ 5 | use Joken.Config, default_signer: nil 6 | 7 | add_hook(JokenJwks, strategy: StreamsRestapiAuth.Oauth.Strategy) 8 | 9 | @impl true 10 | def token_config do 11 | default_claims(skip: [:aud, :iss]) 12 | |> add_claim("iss", nil, &issued_by_domain?/1) 13 | |> add_claim("aud", nil, &has_custom_api_audience?/1) 14 | end 15 | 16 | def issued_by_domain?(iss), do: validate_contained(iss, StreamsRestapiAuth.Oauth.Config.iss()) 17 | def has_custom_api_audience?(aud), do: validate_contained(aud, StreamsRestapiAuth.Oauth.Config.aud()) 18 | 19 | defp validate_contained(value, configured_values) when is_list(value) do 20 | Enum.all?(value, &(&1 in configured_values)) 21 | end 22 | 23 | defp validate_contained(value, configured_values), do: validate_contained([value], configured_values) 24 | 25 | end 26 | -------------------------------------------------------------------------------- /examples/front-async-angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "outDir": "./dist/out-tsc", 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "skipLibCheck": true, 12 | "esModuleInterop": true, 13 | "sourceMap": true, 14 | "declaration": false, 15 | "experimentalDecorators": true, 16 | "moduleResolution": "node", 17 | "importHelpers": true, 18 | "target": "ES2022", 19 | "module": "ES2022", 20 | "useDefineForClassFields": false, 21 | "lib": [ 22 | "ES2022", 23 | "dom" 24 | ] 25 | }, 26 | "angularCompilerOptions": { 27 | "enableI18nLegacyMessageIdFormat": false, 28 | "strictInjectionParameters": true, 29 | "strictInputAccessModifiers": true, 30 | "strictTemplates": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/test/streams_core/sender/connector_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.Sender.ConnectorTest do 2 | use ExUnit.Case, async: false 3 | require Logger 4 | 5 | alias StreamsCore.Sender.Connector 6 | 7 | test "Should check channel registration operation" do 8 | assert {:error, :channel_sender_econnrefused} == 9 | Connector.channel_registration("app_ref", "user_ref") 10 | end 11 | 12 | test "Should check starting router process operation" do 13 | {:ok, pid} = Connector.start_router_process("app_ref") 14 | assert is_pid(pid) 15 | end 16 | 17 | test "Should check routing operation" do 18 | assert {:error, :unknown_channel_reference} == 19 | Connector.route_message("xxx", "yyy", AdfSenderConnector.Message.new("a", "hello", "evt")) 20 | end 21 | 22 | test "Should check routing operation II" do 23 | assert {:error, :unknown_channel_reference} == 24 | Connector.route_message("www", AdfSenderConnector.Message.new("a", "hello", "evt")) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /channel-sender/deploy_samples/k8s/README.md: -------------------------------------------------------------------------------- 1 | # K8S Templates 2 | 3 | This folder contains templates to deploy channel sender in a kubernetes environment and specific configurations to build an erlang cluster with several nodes. 4 | 5 | ## Libcluster for cluster erlang configuration 6 | 7 | The demo templates rely on [libcluster](https://hexdocs.pm/libcluster/readme.html), which is a dependency used in Sender to configure the Erlang cluster. 8 | 9 | ## Istio 10 | 11 | These templates also asume istio is installed and enforcing mtls cluster-wide. 12 | 13 | ## Strategies 14 | 15 | a. [libcluster-kubernetes](./libcluster-kubernetes/README.md): Templates for deploying sender using `libcluster` strategy `Cluster.Strategy.Kubernetes`. 16 | 17 | b. [libcluster-kubernetes-dns](./libcluster-kubernetes-dns/README.md): Similar to (A), but using the `Cluster.Strategy.Kubernetes.DNS` strategy. 18 | 19 | c. [libcluster-kubernetes-dnssrv](./libcluster-kubernetes-dnssrv/README.md): Similar to (A) but using the 20 | `Cluster.Strategy.Kubernetes.DNSSRV` strategy. 21 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/reference.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.Reference do 2 | @moduledoc false 3 | 4 | @type channel_ref() :: binary() 5 | @type channel_secret() :: binary() 6 | 7 | @type t() :: %__MODULE__{ 8 | channel_ref: channel_ref(), 9 | channel_secret: channel_secret(), 10 | created_at: DateTime.t(), 11 | status: atom(), 12 | updated_at: DateTime.t() | nil, 13 | last_message_at: DateTime.t() | nil 14 | } 15 | 16 | defstruct channel_ref: nil, 17 | channel_secret: nil, 18 | created_at: nil, 19 | status: nil, 20 | updated_at: nil, 21 | last_message_at: nil 22 | 23 | @spec new(channel_ref(), channel_secret()) :: t() 24 | def new(channel_ref, channel_secret) do 25 | %__MODULE__{ 26 | channel_ref: channel_ref, 27 | channel_secret: channel_secret, 28 | created_at: DateTime.utc_now(), 29 | status: :new, 30 | updated_at: nil, 31 | last_message_at: nil 32 | } 33 | end 34 | 35 | end 36 | -------------------------------------------------------------------------------- /clients/client-js/test/utils/mocked-transport.ts: -------------------------------------------------------------------------------- 1 | import { ChannelMessage } from "../../src"; 2 | import { Transport, TransportError } from "../../src/transport"; 3 | import * as sinon from "sinon"; 4 | 5 | export class MockedTransport implements Transport { 6 | public connect = sinon.spy(); 7 | public disconnect = sinon.spy(); 8 | public connected = sinon.spy(); 9 | constructor(private readonly nameValue: string, 10 | private readonly handleMessage: (_message: ChannelMessage) => void, 11 | private readonly errorCallback: (_error: TransportError) => void) { 12 | } 13 | 14 | name(): string { 15 | return this.nameValue; 16 | } 17 | 18 | send(message: string): void { 19 | // Simulate sending a message 20 | console.log(`MockedTransport: Sending message: ${message}`); 21 | } 22 | 23 | simulateMessage(message: ChannelMessage) { 24 | this.handleMessage(message); 25 | } 26 | 27 | simulateError(error: TransportError) { 28 | this.errorCallback(error); 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/test/streams_core/app_client_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.AppClientTest do 2 | use ExUnit.Case 3 | 4 | alias StreamsCore.AppClient 5 | 6 | @moduletag :capture_log 7 | 8 | # setup do 9 | # test_cloud_event = %{ 10 | # data: %{ 11 | # "say" => "Hi" 12 | # }, 13 | # dataContentType: "application/json", 14 | # id: "1", 15 | # invoker: "invoker1", 16 | # source: "source1", 17 | # specVersion: "0.1", 18 | # time: "xxx", 19 | # type: "type1" 20 | # } 21 | 22 | # on_exit(fn -> 23 | # Application.delete_env(:channel_streams, :cloud_event_app_identifier) 24 | # end) 25 | 26 | # {:ok, init_args: %{request: test_request, cloud_event: test_cloud_event}} 27 | # end 28 | 29 | test "Should build new client" do 30 | client = AppClient.new("abc321", "some app") 31 | assert %AppClient{} = AppClient.new(nil, nil) 32 | assert client != nil 33 | assert client.id == "abc321" 34 | assert client.name == "some app" 35 | end 36 | 37 | end 38 | -------------------------------------------------------------------------------- /clients/client-dart/lib/src/sse/enum.dart: -------------------------------------------------------------------------------- 1 | /// Enum representing the various statuses of an EventFlux connection. 2 | /// 3 | /// - `connectionInitiated`: Indicates that the connection process has started. 4 | /// - `connected`: Represents a successful connection to the event stream. 5 | /// - `disconnected`: Signifies that the connection has been closed or lost. 6 | /// - `error`: Indicates that an error has occurred during the connection/disconnection process. 7 | enum EventFluxStatus { 8 | connectionInitiated, 9 | connected, 10 | disconnected, 11 | error, 12 | } 13 | 14 | /// Enum to define the type of HTTP connection to be used in EventFlux. 15 | /// 16 | /// - `get`: Use an HTTP GET request for the connection. This is typically used 17 | /// for retrieving data from a server without modifying any server-side state. 18 | /// - `post`: Use an HTTP POST request. This is commonly used for submitting data 19 | /// to be processed to a server, which may result in a change in server-side state 20 | /// or data being stored. 21 | enum EventFluxConnectionType { get, post } 22 | -------------------------------------------------------------------------------- /.github/workflows/release-channel-sender.yml: -------------------------------------------------------------------------------- 1 | name: Deploy image Async DataFlow channel sender 2 | on: 3 | push: 4 | tags: 5 | - 'sender_*' # Push events to matching sender_*, i.e. sender_1.5.0 6 | jobs: 7 | deploy: 8 | defaults: 9 | run: 10 | working-directory: channel-sender 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@d171c3b028d844f2bf14e9fdec0c58114451e4bf 14 | - name: Login to Docker Hub 15 | uses: docker/login-action@v3 16 | with: 17 | username: ${{ secrets.DOCKER_USER }} 18 | password: ${{ secrets.DOCKER_TOKEN }} 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v3 21 | - name: Set up Docker Buildx 22 | uses: docker/setup-buildx-action@v3 23 | - name: Config Builder 24 | run: docker buildx create --name mbuilder && docker buildx use mbuilder 25 | - name: Docker Build Multiplatform 26 | run: docker buildx build --platform linux/amd64 -t bancolombia/async-dataflow-channel-sender:${GITHUB_REF##*_} --push . 27 | -------------------------------------------------------------------------------- /channel-sender/test/channel_sender_ex/core/protocol_message_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ChannelSenderEx.Core.ProtocolMessageTest do 2 | use ExUnit.Case 3 | alias ChannelSenderEx.Core.ProtocolMessage 4 | 5 | test "should convert to ProtocolMessage" do 6 | external_message = %{ 7 | channel_ref: "channel_ref", 8 | message_id: "message_id2", 9 | correlation_id: "correlation_id2", 10 | message_data: "message_data1", 11 | event_name: "event_name2" 12 | } 13 | 14 | message = ProtocolMessage.to_protocol_message(external_message) 15 | assert {"message_id2", "correlation_id2", "event_name2", "message_data1", timestamp} = message 16 | assert is_number(timestamp) 17 | end 18 | 19 | test "should convert to socket message" do 20 | protocol_message = 21 | {"message_id2", "correlation_id2", "event_name2", "message_data1", _timestamp = 14_532_123} 22 | 23 | socket_message = ProtocolMessage.to_socket_message(protocol_message) 24 | assert socket_message == ["message_id2", "correlation_id2", "event_name2", "message_data1"] 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /examples/front-async-angular/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async () => { 6 | await TestBed.configureTestingModule({ 7 | imports: [AppComponent], 8 | }).compileComponents(); 9 | }); 10 | 11 | it('should create the app', () => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.componentInstance; 14 | expect(app).toBeTruthy(); 15 | }); 16 | 17 | it(`should have the 'front-async' title`, () => { 18 | const fixture = TestBed.createComponent(AppComponent); 19 | const app = fixture.componentInstance; 20 | expect(app.title).toEqual('front-async'); 21 | }); 22 | 23 | it('should render title', () => { 24 | const fixture = TestBed.createComponent(AppComponent); 25 | fixture.detectChanges(); 26 | const compiled = fixture.nativeElement as HTMLElement; 27 | expect(compiled.querySelector('h1')?.textContent).toContain('Hello, front-async'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_helper_config/test/application_config_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ApplicationConfigTest do 2 | use ExUnit.Case 3 | doctest StreamsHelperConfig.ApplicationConfig 4 | 5 | setup_all do 6 | :ok 7 | end 8 | 9 | test "test loads empty config when file not found" do 10 | assert StreamsHelperConfig.ApplicationConfig.load("some.yaml") == %{} 11 | end 12 | 13 | test "test fails when nil passed instead of file path" do 14 | # assert throw 15 | assert_raise ArgumentError, "No configuration file specified", fn -> 16 | StreamsHelperConfig.ApplicationConfig.load(nil) 17 | end 18 | end 19 | 20 | test "test fails when no args" do 21 | # assert throw 22 | assert_raise ArgumentError, "No configuration file specified", fn -> 23 | StreamsHelperConfig.ApplicationConfig.load 24 | end 25 | end 26 | 27 | test "test loads full config" do 28 | config = StreamsHelperConfig.ApplicationConfig.load(Path.dirname(__ENV__.file) <> "/test-config.yaml") 29 | assert get_in(config, [:sender, "url"]) == "http://localhost:8081" 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi/lib/streams_api/rest/error_response.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsApi.Rest.ErrorResponse do 2 | @moduledoc """ 3 | Error definition 4 | """ 5 | 6 | @type reason() :: String.t() 7 | @type domain() :: String.t() 8 | @type code() :: String.t() 9 | @type message() :: String.t() 10 | @type type() :: String.t() 11 | 12 | @type t() :: %__MODULE__{ 13 | reason: reason(), 14 | domain: domain(), 15 | code: code(), 16 | message: message(), 17 | type: type() 18 | } 19 | 20 | @derive Jason.Encoder 21 | defstruct reason: nil, 22 | domain: nil, 23 | code: nil, 24 | message: nil, 25 | type: nil 26 | 27 | @doc """ 28 | creates a simple error representation 29 | """ 30 | @spec new(reason(), domain(), code(), message(), type()) :: t() 31 | def new(reason, domain, code, message, type) do 32 | %__MODULE__{ 33 | reason: reason, 34 | domain: domain, 35 | code: code, 36 | message: message, 37 | type: type 38 | } 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /examples/back-async-java/applications/app-service/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'org.springframework.boot' 2 | 3 | dependencies { 4 | implementation project(':async-event-bus') 5 | testImplementation 'com.tngtech.archunit:archunit:1.3.0' 6 | implementation project(':rest-consumer') 7 | implementation 'org.springframework.boot:spring-boot-starter-webflux' 8 | implementation project(':reactive-web') 9 | implementation project(':model') 10 | implementation project(':usecase') 11 | implementation 'org.springframework.boot:spring-boot-starter' 12 | runtimeOnly('org.springframework.boot:spring-boot-devtools') 13 | testImplementation 'com.tngtech.archunit:archunit:1.1.1' 14 | testImplementation 'com.fasterxml.jackson.core:jackson-databind' 15 | } 16 | 17 | tasks.register('explodedJar', Copy) { 18 | with jar 19 | into layout.buildDirectory.dir("exploded") 20 | } 21 | 22 | jar { 23 | // To disable the *-plain.jar 24 | enabled = false 25 | } 26 | 27 | bootJar { 28 | // Sets output jar name 29 | archiveFileName = "${project.getParent().getName()}.${archiveExtension.get()}" 30 | } -------------------------------------------------------------------------------- /channel-streams/apps/streams_secretmanager/test/aws_config_test.exs: -------------------------------------------------------------------------------- 1 | defmodule AwsConfigTest do 2 | alias StreamsSecretManager.AwsConfig 3 | use ExUnit.Case, async: false 4 | 5 | test "Should obtain configure env" do 6 | cfg = %{ 7 | :aws => %{ 8 | "region" => "us-east-1", 9 | "secretsmanager" => %{} 10 | }, 11 | } 12 | AwsConfig.setup_aws_config(cfg) 13 | end 14 | 15 | test "Should obtain configure with env keys" do 16 | cfg = %{ 17 | :aws => %{ 18 | "region" => "us-east-1", 19 | "creds" => %{ 20 | "access_key_id" => ["SYSTEM:xxxx"], 21 | "secret_access_key" => ["SYSTEM:xxxx"] 22 | } 23 | }, 24 | } 25 | AwsConfig.setup_aws_config(cfg) 26 | end 27 | 28 | test "Should obtain configure with instance role" do 29 | cfg = %{ 30 | :aws => %{ 31 | "region" => "us-east-1", 32 | "creds" => %{ 33 | "access_key_id" => ["xxxx"], 34 | "secret_access_key" => ["xxxx"] 35 | } 36 | }, 37 | } 38 | AwsConfig.setup_aws_config(cfg) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /clients/client-dart/example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app_async_flutter", 3 | "short_name": "app_async_flutter", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /clients/client-dart/example/windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /.github/workflows/release-channel-streams.yml: -------------------------------------------------------------------------------- 1 | name: Deploy image Async DataFlow channel streams 2 | on: 3 | push: 4 | tags: 5 | - 'streams_*' # Push events to matching streams_*, i.e. streams_1.5.0 6 | jobs: 7 | deploy: 8 | defaults: 9 | run: 10 | working-directory: channel-streams 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@d171c3b028d844f2bf14e9fdec0c58114451e4bf 14 | - name: Docker Login 15 | uses: Azure/docker-login@74280010feb87216b500bd8971cf1402e1165da2 16 | with: 17 | username: ${{ secrets.DOCKER_USER }} 18 | password: ${{ secrets.DOCKER_PASSWORD }} 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v3 21 | - name: Set up Docker Buildx 22 | uses: docker/setup-buildx-action@v3 23 | - name: Config Builder 24 | run: docker buildx create --name mbuilder && docker buildx use mbuilder 25 | - name: Docker Build Multiplatform 26 | run: docker buildx build --platform linux/amd64 -t bancolombia/async-dataflow-channel-streams:${GITHUB_REF##*_} --push . 27 | -------------------------------------------------------------------------------- /channel-streams/deploy_samples/k8s/certs/generate_demo_certs.sh: -------------------------------------------------------------------------------- 1 | # Create a root certificate and private key to sign the certificates for your services 2 | if ! [ -f ./example.com.key ]; then 3 | openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \ 4 | -subj '/O=example Inc./CN=example.com' \ 5 | -keyout ./example.com.key \ 6 | -out ./example.com.crt 7 | fi 8 | 9 | # Generate a certificate and a private key for adfstreams.example.com: 10 | openssl req \ 11 | -out ./adfstreams.example.com.csr -newkey rsa:2048 -nodes \ 12 | -keyout ./adfstreams.example.com.key \ 13 | -subj "/CN=adfstreams.example.com/O=adf organization" 14 | 15 | openssl x509 -req -sha256 -days 365 \ 16 | -CA ./example.com.crt \ 17 | -CAkey ./example.com.key -set_serial 0 \ 18 | -in ./adfstreams.example.com.csr \ 19 | -out ./adfstreams.example.com.crt 20 | 21 | # upload cert and key to k8s 22 | kubectl create -n istio-system secret tls adfstreams-credential \ 23 | --key=./adfstreams.example.com.key \ 24 | --cert=./adfstreams.example.com.crt 25 | 26 | # clean up 27 | rm ./adfstreams.example.com.csr -------------------------------------------------------------------------------- /clients/client-dart/example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "20f82749394e68bcfbbeee96bad384abaae09c13" 8 | channel: "stable" 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 20f82749394e68bcfbbeee96bad384abaae09c13 17 | base_revision: 20f82749394e68bcfbbeee96bad384abaae09c13 18 | - platform: android 19 | create_revision: 20f82749394e68bcfbbeee96bad384abaae09c13 20 | base_revision: 20f82749394e68bcfbbeee96bad384abaae09c13 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/boundary/node_observer.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.Boundary.NodeObserver do 2 | @moduledoc """ 3 | Observes the nodes in the cluster and updates the members of the cluster. 4 | """ 5 | use GenServer 6 | 7 | alias StreamsCore.Boundary.{ChannelRegistry, ChannelSupervisor} 8 | 9 | def start_link(_), do: GenServer.start_link(__MODULE__, []) 10 | 11 | def init(_) do 12 | :net_kernel.monitor_nodes(true, node_type: :visible) 13 | 14 | {:ok, nil} 15 | end 16 | 17 | def handle_info({:nodeup, _node, _node_type}, state) do 18 | set_members(ChannelRegistry) 19 | set_members(ChannelSupervisor) 20 | 21 | {:noreply, state} 22 | end 23 | 24 | def handle_info({:nodedown, _node, _node_type}, state) do 25 | set_members(ChannelRegistry) 26 | set_members(ChannelSupervisor) 27 | 28 | {:noreply, state} 29 | end 30 | 31 | defp set_members(name) do 32 | members = Enum.map([Node.self() | Node.list()], &{name, &1}) 33 | 34 | :ok = Horde.Cluster.set_members(name, members) 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /clients/client-dart/example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "java", 9 | "name": "MainApplication", 10 | "request": "launch", 11 | "mainClass": "co.com.bancolombia.MainApplication" 12 | }, 13 | { 14 | "name": "client-dart", 15 | "cwd": "clients/client-dart", 16 | "request": "launch", 17 | "type": "dart" 18 | }, 19 | { 20 | "name": "app_async_flutter", 21 | "cwd": "examples/app_async_flutter", 22 | "request": "launch", 23 | "type": "dart" 24 | }, 25 | { 26 | "name": "app_async_flutter (profile mode)", 27 | "cwd": "examples/app_async_flutter", 28 | "request": "launch", 29 | "type": "dart", 30 | "flutterMode": "profile" 31 | } 32 | ] 33 | } -------------------------------------------------------------------------------- /channel-streams/apps/streams_secretmanager/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsSecretManager.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :streams_secretmanager, 7 | version: "0.1.0", 8 | build_path: "../../_build", 9 | config_path: "../../config/config.exs", 10 | deps_path: "../../deps", 11 | lockfile: "../../mix.lock", 12 | elixir: "~> 1.15", 13 | start_permanent: Mix.env() == :prod, 14 | deps: deps(), 15 | test_coverage: [tool: ExCoveralls] 16 | ] 17 | end 18 | 19 | # Run "mix help compile.app" to learn about applications. 20 | def application do 21 | [ 22 | extra_applications: [:logger], 23 | mod: {StreamsSecretManager.Application, []} 24 | ] 25 | end 26 | 27 | # Run "mix help deps" to learn about dependencies. 28 | defp deps do 29 | [ 30 | {:streams_helper_config, in_umbrella: true}, 31 | {:ex_aws, "~> 2.2"}, 32 | {:ex_aws_sts, "~> 2.2"}, 33 | {:ex_aws_secretsmanager, "~> 2.0"}, 34 | # test only dependencies 35 | {:mock, "~> 0.3.8", only: :test}, 36 | ] 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /channel-sender/test/channel_sender_ex/core/pubsub/socket_event_bus_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ChannelSenderEx.Core.PubSub.SocketEventBusTest do 2 | use ExUnit.Case 3 | 4 | alias ChannelSenderEx.Core.Channel 5 | alias ChannelSenderEx.Core.ChannelSupervisor 6 | alias ChannelSenderEx.Core.PubSub.SocketEventBus 7 | 8 | import Mock 9 | 10 | test "Should retry n times" do 11 | channel = "some_channel" 12 | socket_pid = self() 13 | 14 | with_mock ChannelSupervisor, whereis_channel: fn _ -> :undefined end do 15 | assert_raise RuntimeError, "No channel found", fn -> 16 | SocketEventBus.notify_event({:connected, channel, :websocket}, socket_pid) 17 | end 18 | end 19 | end 20 | 21 | test "Should not retry n times" do 22 | channel = "some_channel" 23 | pid = :c.pid(0, 250, 0) 24 | socket_pid = self() 25 | 26 | with_mocks([ 27 | {ChannelSupervisor, [], [whereis_channel: fn _ -> pid end]}, 28 | {Channel, [], [socket_connected: fn _, _, _ -> :ok end]} 29 | ]) do 30 | assert SocketEventBus.notify_event({:connected, channel, :websocket}, socket_pid) == pid 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /channel-sender/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2019 Bancolombia S.A 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /channel-streams/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2019 Bancolombia S.A 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /channel-streams/apps/streams_helper_config/lib/streams_helper_config/application.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsHelperConfig.Application do 2 | # See https://hexdocs.pm/elixir/Application.html 3 | # for more information on OTP Applications 4 | @moduledoc false 5 | 6 | use Application 7 | require Logger 8 | @default_file "config-local.yaml" 9 | 10 | @impl true 11 | def start(_type, args) do 12 | 13 | config_file_path = case Application.get_env(:streams_core, :config_file) do 14 | nil -> 15 | Logger.warning("No configuration file specified, looking for default file: #{@default_file}") 16 | @default_file 17 | value -> value 18 | end 19 | 20 | new_args = args ++ [file_path: config_file_path] 21 | 22 | children = [ 23 | # Starts a worker by calling: StreamsHelperConfig.Worker.start_link(arg) 24 | {StreamsHelperConfig.ConfigManager, new_args} 25 | ] 26 | 27 | # See https://hexdocs.pm/elixir/Supervisor.html 28 | # for other strategies and supported options 29 | opts = [strategy: :one_for_one, name: StreamsHelperConfig.Supervisor] 30 | Supervisor.start_link(children, opts) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /clients/client-dart/LICENCE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Bancolombia S.A. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /clients/client-js/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2019 Bancolombia S.A 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /clients/client-dart/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2019 Bancolombia S.A 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /channel-sender/bench/socket_bench.exs: -------------------------------------------------------------------------------- 1 | alias ChannelSenderEx.Transport.Socket 2 | alias ChannelSenderEx.Core.Security.ChannelAuthenticator 3 | alias ChannelSenderEx.Core.RulesProvider.Helper 4 | alias ChannelSenderEx.Transport.Encoders.JsonEncoder 5 | 6 | 7 | Helper.compile(:channel_sender_ex) 8 | 9 | app_id = "app_22929" 10 | user_id = "user33243222" 11 | {channel_id, channel_secret} = ChannelAuthenticator.create_channel(app_id, user_id) 12 | auth_frame = {:text, "Auth::" <> channel_secret} 13 | state = {channel_id, :connected, JsonEncoder, {app_id, user_id}, %{}} 14 | state_pre_auth = {channel_id, :pre_auth, JsonEncoder} 15 | 16 | 17 | Benchee.run( 18 | %{ 19 | # "Noop" => fn -> for _ <- 0..1000, do: :ok end, 20 | "Socket / HeartBeat handle" => fn -> Socket.websocket_handle({:text, "hb::29"}, state) end, 21 | "ChannelAuthenticator / Authorize Channel" => fn -> ChannelAuthenticator.authorize_channel(channel_id, channel_secret) end, 22 | "Socket / Handle Auth" => fn -> Socket.websocket_handle(auth_frame, state_pre_auth) end, 23 | }, 24 | 25 | time: 5, 26 | # parallel: 6, 27 | formatters: [{Benchee.Formatters.Console, extended_statistics: true}] 28 | ) 29 | -------------------------------------------------------------------------------- /channel-sender/test/channel_sender_ex/test_config_files/config2.yaml: -------------------------------------------------------------------------------- 1 | channel_sender_ex: 2 | rest_port: 8081 3 | socket_port: 8082 4 | secret_generator: 5 | base: "aV4ZPOf7T7HX6GvbhwyBlDM8B9jfeiwi+9qkBnjXxUZXqAeTrehojWKHkV3U0kGc" 6 | salt: "socket auth" 7 | max_age: 300 8 | initial_redelivery_time: 900 9 | socket_idle_timeout: 30000 10 | channel_shutdown_tolerance: 10000 11 | min_disconnection_tolerance: 50 12 | on_connected_channel_reply_timeout: 2000 13 | accept_channel_reply_timeout: 1000 14 | no_start: false 15 | topology: 16 | strategy: Elixir.Cluster.Strategy.Kubernetes 17 | config: 18 | mode: :hostname 19 | kubernetes_ip_lookup_mode: :pods 20 | kubernetes_service_name: "adfsender-headless" 21 | kubernetes_node_basename: "channel_sender_ex" 22 | kubernetes_selector: "cluster=beam" 23 | namespace: "sendernm" 24 | polling_interval: 5000 25 | opentelemetry: 26 | traces_enable: true 27 | traces_endpoint: "http://localhost:4318" 28 | traces_ignore_routes: [ "/health", "/metrics" ] 29 | metrics: 30 | active_interval_minutes_count: 1 31 | logger: 32 | level: debug 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /clients/backend-client-elixir/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2022 Bancolombia S.A 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /examples/front-async-angular/README.md: -------------------------------------------------------------------------------- 1 | # FrontAsync 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.3.9. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. 28 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_helper_config/lib/streams_helper_config/config_manager.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsHelperConfig.ConfigManager do 2 | @moduledoc """ 3 | Configuration manager for the application. 4 | """ 5 | use GenServer 6 | 7 | alias StreamsHelperConfig.ApplicationConfig 8 | 9 | @doc """ 10 | Starts the configuration manager process. 11 | """ 12 | def start_link(args) do 13 | file_path_arg = Keyword.get(args, :file_path, nil) 14 | GenServer.start_link(__MODULE__, file_path_arg, name: __MODULE__) 15 | end 16 | 17 | def lookup(key) do 18 | GenServer.call(__MODULE__, {:lookup, key}) 19 | end 20 | 21 | def load(file) do 22 | GenServer.call(__MODULE__, {:load, file}) 23 | end 24 | 25 | @impl true 26 | def init(file_path_arg) do 27 | {:ok, ApplicationConfig.load(file_path_arg)} 28 | end 29 | 30 | @impl true 31 | def handle_call({:lookup, key}, _from, data) do 32 | {:reply, get_in(data, key), data} 33 | rescue 34 | _ -> 35 | {:reply, nil, data} 36 | end 37 | 38 | @impl true 39 | def handle_call({:load, file}, _from, _data) do 40 | new_data = ApplicationConfig.load(file) 41 | {:reply, new_data, new_data} 42 | end 43 | 44 | end 45 | -------------------------------------------------------------------------------- /clients/client-dart/example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - connectivity_plus (0.0.1): 3 | - Flutter 4 | - ReachabilitySwift 5 | - Flutter (1.0.0) 6 | - ReachabilitySwift (5.2.4) 7 | - shared_preferences_foundation (0.0.1): 8 | - Flutter 9 | - FlutterMacOS 10 | 11 | DEPENDENCIES: 12 | - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) 13 | - Flutter (from `Flutter`) 14 | - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) 15 | 16 | SPEC REPOS: 17 | trunk: 18 | - ReachabilitySwift 19 | 20 | EXTERNAL SOURCES: 21 | connectivity_plus: 22 | :path: ".symlinks/plugins/connectivity_plus/ios" 23 | Flutter: 24 | :path: Flutter 25 | shared_preferences_foundation: 26 | :path: ".symlinks/plugins/shared_preferences_foundation/darwin" 27 | 28 | SPEC CHECKSUMS: 29 | connectivity_plus: 481668c94744c30c53b8895afb39159d1e619bdf 30 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 31 | ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda 32 | shared_preferences_foundation: 0b09b969fb36da5551c0bc4a2dbd9d0ff9387478 33 | 34 | PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 35 | 36 | COCOAPODS: 1.16.2 37 | -------------------------------------------------------------------------------- /clients/client-dart/example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:app_async_flutter/my_app.dart'; 9 | import 'package:flutter/material.dart'; 10 | import 'package:flutter_test/flutter_test.dart'; 11 | 12 | void main() { 13 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 14 | // Build our app and trigger a frame. 15 | await tester.pumpWidget(const MyApp()); 16 | 17 | // Verify that our counter starts at 0. 18 | expect(find.text('0'), findsOneWidget); 19 | expect(find.text('1'), findsNothing); 20 | 21 | // Tap the '+' icon and trigger a frame. 22 | await tester.tap(find.byIcon(Icons.add)); 23 | await tester.pump(); 24 | 25 | // Verify that our counter has incremented. 26 | expect(find.text('0'), findsNothing); 27 | expect(find.text('1'), findsOneWidget); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/test/oauth/config_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsRestapiAuth.Oauth.ConfigTest do 2 | use ExUnit.Case 3 | 4 | alias StreamsRestapiAuth.Oauth.Config 5 | 6 | @moduletag :capture_log 7 | 8 | setup_all do 9 | cfg = %{ 10 | streams: %{ 11 | "channel_authenticator" => %{ 12 | "auth_module" => Elixir.StreamsRestapiAuth.JwtValidationProvider, 13 | "config" => %{ 14 | "jwks" => "https://someprovider.com/keys", 15 | "allowed_audiences" => ["aud1", "aud2"], 16 | "allowed_issuers" => ["iss1", "some.issuer"], 17 | } 18 | } 19 | } 20 | } 21 | Application.put_env(:channel_streams, :config, cfg) 22 | 23 | on_exit(fn -> 24 | Application.delete_env(:channel_streams, :config) 25 | end) 26 | end 27 | 28 | test "should get configured issuers data" do 29 | assert Config.iss() == ["iss1", "some.issuer"] 30 | end 31 | 32 | test "should get configured audiences data" do 33 | assert Config.aud() == ["aud1", "aud2"] 34 | end 35 | 36 | test "should get configured jwks uri" do 37 | assert Config.jwks_url() == "https://someprovider.com/keys" 38 | end 39 | 40 | end 41 | -------------------------------------------------------------------------------- /clients/client-dart/example/lib/ui/helpers/home_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:app_async_flutter/async_client_service.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class HomeHelper { 5 | final AsyncClientService asyncClientService; 6 | 7 | HomeHelper(this.asyncClientService); 8 | 9 | void callAsyncBackend(TextEditingController textEditingController) { 10 | int start = DateTime.now().millisecondsSinceEpoch; 11 | 12 | asyncClientService.asyncClientGateway 13 | .callBusinessUseCase( 14 | asyncClientService.prefs.getString("channelRef") ?? "", 15 | asyncClientService.prefs.getString("userRef") ?? "", 16 | int.tryParse(textEditingController.text) ?? 100) 17 | .then((value) => asyncClientService.responsesNotifier.addResponse( 18 | "Get empty response after ${DateTime.now().millisecondsSinceEpoch - start} ms")); 19 | } 20 | 21 | Future disconnect() async { 22 | await asyncClientService.closeSession(); 23 | } 24 | 25 | Future connect() async { 26 | await asyncClientService.initAsyncClient(); 27 | } 28 | 29 | Future switchProtocols() async { 30 | await asyncClientService.switchProtocols(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_core/lib/streams_core/boundary/channel_registry.ex: -------------------------------------------------------------------------------- 1 | defmodule StreamsCore.Boundary.ChannelRegistry do 2 | @moduledoc """ 3 | Registry abstraction to locate a channel 4 | """ 5 | use Horde.Registry 6 | require Logger 7 | 8 | def start_link(_) do 9 | Horde.Registry.start_link(__MODULE__, [keys: :unique], name: __MODULE__) 10 | end 11 | 12 | def init(init_arg) do 13 | result = [members: members()] 14 | |> Keyword.merge(init_arg) 15 | |> Horde.Registry.init() 16 | Logger.debug("Channel registry init #{inspect(result)}") 17 | result 18 | end 19 | 20 | @type channel_ref :: String.t() 21 | @type channel_addr :: pid() 22 | @spec lookup_channel_addr(channel_ref()) :: :noproc | channel_addr() 23 | # @compile {:inline, lookup_session_addr: 1} 24 | def lookup_channel_addr(channel_ref) do 25 | case Horde.Registry.lookup(via_tuple(channel_ref)) do 26 | [{pid, _}] -> pid 27 | [] -> :noproc 28 | end 29 | end 30 | 31 | # @compile {:inline, via_tuple: 1} 32 | def via_tuple(channel_ref), do: {:via, Registry, {__MODULE__, channel_ref}} 33 | 34 | defp members do 35 | Enum.map([Node.self() | Node.list()], &{__MODULE__, &1}) 36 | end 37 | 38 | end 39 | -------------------------------------------------------------------------------- /channel-sender/test/channel_sender_ex/test_config_files/config1.yaml: -------------------------------------------------------------------------------- 1 | channel_sender_ex: 2 | rest_port: 8081 3 | socket_port: 8082 4 | secret_generator: 5 | base: "aV4ZPOf7T7HX6GvbhwyBlDM8B9jfeiwi+9qkBnjXxUZXqAeTrehojWKHkV3U0kGc" 6 | salt: "socket auth" 7 | max_age: 300 8 | initial_redelivery_time: 900 9 | socket_idle_timeout: 30000 10 | channel_shutdown_tolerance: 10000 11 | min_disconnection_tolerance: 50 12 | on_connected_channel_reply_timeout: 2000 13 | accept_channel_reply_timeout: 1000 14 | no_start: false 15 | topology: 16 | strategy: Elixir.Cluster.Strategy.Gossip 17 | # strategy: Elixir.Cluster.Strategy.Kubernetes 18 | # config: 19 | # mode: :hostname 20 | # kubernetes_ip_lookup_mode: :pods 21 | # kubernetes_service_name: "adfsender-headless" 22 | # kubernetes_node_basename: "channel_sender_ex" 23 | # kubernetes_selector: "cluster=beam" 24 | # namespace: "sendernm" 25 | # polling_interval: 5000 26 | opentelemetry: 27 | traces_enable: true 28 | traces_endpoint: "http://localhost:4318" 29 | traces_ignore_routes: [ "/health", "/metrics" ] 30 | metrics: 31 | active_interval_minutes_count: 2 32 | logger: 33 | level: debug 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /channel-sender/test/channel_sender_ex/core/retry/exponential_backoff_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ChannelSenderEx.Core.Retry.ExponentialBackoffTest do 2 | use ExUnit.Case 3 | 4 | alias ChannelSenderEx.Core.Retry.ExponentialBackoff 5 | 6 | test "execute/5 retries the action function with exponential backoff" do 7 | # Setup 8 | initial = 100 9 | max_delay = 1000 10 | max_retries = 3 11 | action_fn = fn _delay -> :retry end 12 | 13 | # Exercise 14 | assert ExponentialBackoff.execute( 15 | initial, 16 | max_delay, 17 | max_retries, 18 | action_fn, 19 | fn -> :void end, 20 | "dummy key" 21 | ) == :void 22 | end 23 | 24 | test "execute/5 retries the action function with exponential backoff, that raises err" do 25 | # Setup 26 | initial = 100 27 | max_delay = 1000 28 | max_retries = 3 29 | action_fn = fn _delay -> raise("dummy") end 30 | 31 | # Exercise 32 | assert ExponentialBackoff.execute( 33 | initial, 34 | max_delay, 35 | max_retries, 36 | action_fn, 37 | fn -> :void end, 38 | "dummy key" 39 | ) == :void 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /channel-streams/apps/streams_restapi_auth/test/passthrough_provider_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StreamsRestapiAuth.PassthroughProviderTest do 2 | use ExUnit.Case 3 | 4 | alias StreamsRestapiAuth.PassthroughProvider 5 | 6 | @moduletag :capture_log 7 | 8 | test "should perform no autentication when a token is given" do 9 | 10 | headers = %{ 11 | "content-type" => "application/json", 12 | "authorization" => "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c", 13 | "session-tracker" => "xxxx" 14 | } 15 | 16 | assert PassthroughProvider.validate_credentials(headers) == 17 | {:ok, %{}} 18 | 19 | end 20 | 21 | test "should handle empty header authentication" do 22 | 23 | headers = %{ 24 | "content-type" => "application/json", 25 | "authorization" => "", 26 | "session-tracker" => "xxxx" 27 | } 28 | 29 | assert PassthroughProvider.validate_credentials(headers) == {:ok, %{}} 30 | end 31 | 32 | test "should handle empty map headers" do 33 | 34 | headers = %{} 35 | 36 | assert PassthroughProvider.validate_credentials(headers) == {:ok, %{}} 37 | end 38 | 39 | end 40 | -------------------------------------------------------------------------------- /clients/client-dart/lib/src/sse/models/reconnect.dart: -------------------------------------------------------------------------------- 1 | /// Reconnect configuration for the client. 2 | /// Reconnect config takes three parameters: 3 | /// - [mode]: ReconnectMode, which can be linear or exponential. 4 | /// - [interval]: Duration, the time interval between reconnection attempts. If mode is linear, the interval is fixed. 5 | /// If mode is exponential, the interval is multiplied by 2 after each attempt. 6 | /// - [maxAttempts]: int, the maximum number of reconnection attempts. 7 | /// - [onReconnect]: Function, a callback function that is called when the client reconnects. 8 | /// - [reconnectHeader]: Future> Function(), a function that returns the headers to be sent with the reconnection request. 9 | class ReconnectConfig { 10 | final ReconnectMode mode; 11 | final Duration interval; 12 | final Function()? onReconnect; 13 | final int maxAttempts; 14 | final Future> Function()? reconnectHeader; 15 | 16 | ReconnectConfig({ 17 | required this.mode, 18 | this.interval = const Duration(seconds: 2), 19 | this.maxAttempts = 5, 20 | this.reconnectHeader, 21 | this.onReconnect, 22 | }); 23 | } 24 | 25 | /// Enum for reconnect mode. 26 | enum ReconnectMode { linear, exponential } 27 | -------------------------------------------------------------------------------- /clients/client-dart/lib/src/utils/capped_list.dart: -------------------------------------------------------------------------------- 1 | /// A class that represents a capped list, which maintains a fixed maximum size. 2 | /// When the maximum size is reached, adding a new element will remove the oldest element. 3 | /// 4 | /// This class is generic and can hold elements of any type [T]. 5 | /// 6 | /// Example usage: 7 | /// ```dart 8 | /// final cappedList = CappedList(3); 9 | /// cappedList.add(1); 10 | /// cappedList.add(2); 11 | /// cappedList.add(3); 12 | /// cappedList.add(4); // This will remove the element '1' 13 | /// print(cappedList.contains(1)); // false 14 | /// cappedList.clear(); // Clears the list 15 | /// ``` 16 | /// 17 | /// Properties: 18 | /// - [maxSize]: The maximum number of elements the list can hold. 19 | /// - [_list]: The internal list that stores the elements. 20 | class CappedList { 21 | final int maxSize; 22 | final List _list = []; 23 | 24 | CappedList(this.maxSize); 25 | 26 | void add(T element) { 27 | if (_list.length >= maxSize) { 28 | _list.removeAt(0); // Remove the oldest element 29 | } 30 | _list.add(element); 31 | } 32 | 33 | bool contains(T element) { 34 | return _list.contains(element); 35 | } 36 | 37 | void clear() { 38 | _list.clear(); 39 | } 40 | } 41 | --------------------------------------------------------------------------------