├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── SUPPORT.md ├── docs ├── common │ ├── azure-bot-app-registration.md │ ├── azure-bot.md │ ├── customize_bdk_slate_image.md │ ├── images │ │ ├── architecture.png │ │ ├── cert-files.png │ │ ├── certificate_password.png │ │ ├── certificate_personal.png │ │ ├── certificate_thumbprint.png │ │ ├── default-slate-image-solution-route.png │ │ ├── default-slate-image.png │ │ ├── import_certificate.png │ │ ├── install_nginx.png │ │ ├── nginx_as_windows_service.png │ │ ├── nginx_device_monitor.png │ │ ├── nginx_ffplay.png │ │ ├── nginx_repository.png │ │ ├── nginx_using_gstreamer.png │ │ ├── nginx_vlc_player.png │ │ ├── nginx_wasapi_device.png │ │ ├── open_nginx.png │ │ └── run_certificate.png │ ├── install-and-configure-nginx-with-rtmp-module-on-windows.md │ └── install-domain-certificate.md ├── how-to-run-the-solution-in-azure │ ├── README.md │ ├── app-service-plan.md │ ├── application-insights.md │ ├── authorization-token.md │ ├── azure-key-vault.md │ ├── azure-sdk-app-registration.md │ ├── bot-service-api-app-registration.md │ ├── bot-service-client-app-registration.md │ ├── bot-service-deploy.md │ ├── cosmos-db.md │ ├── event-grid.md │ ├── function-app-deploy.md │ ├── function-app.md │ ├── images │ │ ├── add_graph_permissions.png │ │ ├── app_registration_add_client_application.png │ │ ├── app_registration_add_client_application_blade.png │ │ ├── appi_graph_permissions.png │ │ ├── bot_service_client_enabled_permissions.png │ │ ├── configuration_to_publish_bot_service.png │ │ ├── configure_windows_service.png │ │ ├── create_role_bot_service_api.png │ │ ├── create_role_management_api.png │ │ ├── deploy_function_app_sa_check.png │ │ ├── deploy_function_app_sa_config.png │ │ ├── deploy_function_app_sa_select.png │ │ ├── deploy_function_app_sa_uncheck.png │ │ ├── deploy_function_app_select_azure.png │ │ ├── deploy_function_app_select_function_app_created.png │ │ ├── deploy_function_app_select_specific_destination.png │ │ ├── deploy_web_app_select_azure.png │ │ ├── deploy_web_app_select_specific_destination.png │ │ ├── deploy_web_app_select_web_app_created.png │ │ ├── function_app_configuration_application_settings.png │ │ ├── function_app_save_new_application_settings.png │ │ ├── function_app_search.png │ │ ├── management_api_add_scope.png │ │ ├── management_api_optional_claims_of_manifest copy.png │ │ ├── management_api_optional_claims_of_manifest.png │ │ ├── manifest_botservice_api.png │ │ ├── permission_entry_bot_service.png │ │ ├── postman_add_service_auth_header.png │ │ ├── postman_add_service_payload.png │ │ ├── publish_bot_service.png │ │ ├── request_api_permissions.png │ │ ├── save_publish_from_bot_service.png │ │ ├── search_api_permissions.png │ │ ├── security_group_add_members.png │ │ ├── security_group_select_members.png │ │ ├── test_function_app_postman_send_start.png │ │ ├── test_function_app_postman_send_state.png │ │ ├── test_function_app_postman_send_stop.png │ │ ├── test_function_app_queues.png │ │ ├── test_web_app_postman_add_service_auth_header.png │ │ ├── test_with_postman_web_app.png │ │ ├── web_app_configuration_application_settings.png │ │ ├── web_app_save_new_application_settings.png │ │ └── web_app_search.png │ ├── management-api-app-registration.md │ ├── management-api-deploy.md │ ├── register-service.md │ ├── security-group.md │ ├── storage-account.md │ ├── test-function-app.md │ ├── test-web-app.md │ ├── virtual-machine.md │ └── web-app.md ├── how-to-run-the-solution-locally │ ├── README.md │ ├── gstreamer.md │ ├── images │ │ ├── botservice_fails.png │ │ ├── cosmos_add_service.png │ │ ├── cosmos_db_data_explorer.png │ │ ├── environment_variables.png │ │ ├── environment_variables_option.png │ │ ├── environment_variables_path.png │ │ ├── gstreamer_bin_path.png │ │ ├── gstreamer_installer.png │ │ ├── invite_link.png │ │ ├── ngrok_authtoken.png │ │ ├── ngrok_configuration.png │ │ ├── ngrok_console.png │ │ ├── ngrok_create_config_file_1.png │ │ ├── ngrok_create_config_file_2.png │ │ ├── ngrok_create_config_file_3.png │ │ ├── ngrok_create_config_file_4.png │ │ ├── ngrok_create_config_file_5.png │ │ ├── open_console.png │ │ ├── postman_header.png │ │ ├── start.png │ │ ├── startup_projects.png │ │ ├── test_with_postman.png │ │ ├── visual_set_startup_projects.png │ │ └── vs_run_as_admin.png │ └── ngrok.md ├── how-to-use-the-solution │ ├── README.md │ └── images │ │ ├── added_api_permission.png │ │ ├── get_token.png │ │ ├── get_token_client_credentials.png │ │ ├── invite_link.png │ │ ├── management_access_token.png │ │ ├── management_api_swagger_ui.jpg │ │ ├── request_api_permissions.png │ │ ├── search_api_permissions.png │ │ └── use_bearer_token.png ├── media-synchronization │ ├── README.md │ └── images │ │ ├── gst-play-example-1.png │ │ ├── gst-play-example-2.png │ │ ├── gst-play-example-3.png │ │ ├── multiple-streams-example-2.png │ │ ├── multiple-streams-example-3.png │ │ ├── multiple-streams-example-4.png │ │ ├── multiple-streams-example.png │ │ ├── obs-example-1.png │ │ ├── obs-example-2.png │ │ ├── obs-example-3.png │ │ ├── obs-example-4.png │ │ ├── obs-example-reset-stream.png │ │ ├── obs-gst-play-comparison-2.png │ │ ├── obs-gst-play-comparison-3.png │ │ └── obs-gst-play-comparison.png ├── pull_request_template.md └── upgrade_path.md ├── scripts └── Add-GStreamer-Path.ps1 └── src ├── .editorconfig ├── Application ├── Application.csproj ├── Call │ ├── Commands │ │ ├── DeleteCallContext.cs │ │ ├── GenerateStreamKey.cs │ │ ├── RequestEndCall.cs │ │ ├── RequestInviteBot.cs │ │ ├── RequestMuteBot.cs │ │ ├── RequestUnmuteBot.cs │ │ ├── SetCallAsEstablished.cs │ │ ├── SetCallAsTerminated.cs │ │ └── SetCallContext.cs │ ├── MappingProfile.cs │ ├── Queries │ │ ├── GetActiveCalls.cs │ │ ├── GetArchivedCalls.cs │ │ ├── GetCall.cs │ │ ├── GetCallByMeetingId.cs │ │ └── GetPublicCallForParticipantByMeetingId.cs │ └── Specifications │ │ ├── CallGetActiveSpecification.cs │ │ ├── CallGetArchivedAggregationSpecification.cs │ │ ├── CallGetArchivedSpecification.cs │ │ └── CallGetByMeetingIdSpecification.cs ├── Common │ ├── Config │ │ ├── AzServicePrincipalConfiguration.cs │ │ ├── AzStorageConfiguration.cs │ │ ├── AzureAdConfiguration.cs │ │ ├── BotConfiguration.cs │ │ ├── BotServiceAuthenticationConfiguration.cs │ │ ├── CloudConfigSettings.cs │ │ ├── CosmosDbConfiguration.cs │ │ ├── DevelopmentConfiguration.cs │ │ ├── GraphClientConfiguration.cs │ │ ├── HttpRouteConstants.cs │ │ └── IAppConfiguration.cs │ ├── Converter │ │ ├── JsonCreationConverter.cs │ │ ├── StartStreamExtractionBodyConverter.cs │ │ └── StartStreamInjectionBodyConverter.cs │ ├── Models │ │ ├── Api │ │ │ └── SetInjectionVolumeRequest.cs │ │ ├── CallModel.cs │ │ ├── GetPublicCallForParticipantBody.cs │ │ ├── InfrastructureModel.cs │ │ ├── JoinUrlContext.cs │ │ ├── PagedQueryResult.cs │ │ ├── ParticipantStreamDetailsModel.cs │ │ ├── ParticipantStreamModel.cs │ │ ├── ProvisioningDetailsModel.cs │ │ ├── PublicCallModelForParticipant.cs │ │ ├── ResourceIdentity.cs │ │ ├── RtmpStreamExtractionBody.cs │ │ ├── RtmpStreamInjectionBody.cs │ │ ├── ServiceModel.cs │ │ ├── SrtStreamExtractionBody.cs │ │ ├── SrtStreamInjectionBody.cs │ │ ├── StartRtmpStreamExtractionResponse.cs │ │ ├── StartSrtStreamExtractionResponse.cs │ │ ├── StartStreamExtractionBody.cs │ │ ├── StartStreamExtractionResponse.cs │ │ ├── StartStreamInjectionBody.cs │ │ ├── StopStreamExtractionBody.cs │ │ ├── StopStreamExtractionResponse.cs │ │ └── StreamModel.cs │ └── ValidationBehaviour.cs ├── DependencyInjection.cs ├── Exceptions │ ├── ApiValidationException.cs │ ├── BotClientBaseUrlNotSetException.cs │ ├── CertificateNotFoundException.cs │ ├── CustomBaseException.cs │ ├── GenerateStreamKeyException.cs │ ├── Models │ │ └── ExceptionDetails.cs │ ├── NotSuccessfulRequestException.cs │ ├── NotValidStreamKeyException.cs │ ├── ServiceUnavailableException.cs │ ├── SetStreamVolumeException.cs │ ├── StartStreamExtractionException.cs │ ├── StartStreamInjectionException.cs │ ├── StopStreamExtractionException.cs │ └── StopStreamInjectionException.cs ├── Interfaces │ ├── Common │ │ ├── IAzService.cs │ │ ├── IAzStorageHandler.cs │ │ ├── IAzVirtualMachineService.cs │ │ ├── IBot.cs │ │ ├── IBotServiceAuthenticationProvider.cs │ │ ├── IBotServiceClient.cs │ │ ├── ICloudConfigurationService.cs │ │ ├── IExtractionUrlHelper.cs │ │ ├── IGraphService.cs │ │ ├── IHostEnvironment.cs │ │ ├── IInjectionUrlHelper.cs │ │ ├── IMeetingUrlHelper.cs │ │ └── IStreamKeyGeneratorHelper.cs │ └── Persistance │ │ ├── ICallRepository.cs │ │ ├── IParticipantStreamRepository.cs │ │ ├── IRepository.cs │ │ ├── IServiceRepository.cs │ │ └── IStreamRepository.cs ├── Participants │ ├── Commands │ │ ├── AddParticipantStream.cs │ │ ├── HandleParticipantLeave.cs │ │ ├── UpdateBotStatus.cs │ │ └── UpdateParticipantMeetingStatus.cs │ ├── MappingProfile.cs │ ├── Queries │ │ └── GetParticipantPhoto.cs │ └── Specifications │ │ ├── ParticipantStreamGetFromCallSpecification.cs │ │ ├── ParticipantStreamsGetFromCallSpecification.cs │ │ └── ParticipantsStreamsGetFromCallSpecification.cs ├── Service │ ├── Commands │ │ ├── AddService.cs │ │ ├── DoEndCall.cs │ │ ├── DoInviteBot.cs │ │ ├── DoMuteBot.cs │ │ ├── DoStartServiceInfrastructure.cs │ │ ├── DoStopServiceInfrastructure.cs │ │ ├── DoUnmuteBot.cs │ │ ├── HandleEventGridServiceInfrastructureEvent.cs │ │ ├── ProcessNotification.cs │ │ ├── RegisterService.cs │ │ ├── RequestStartServiceInfrastructure.cs │ │ ├── RequestStopServiceInfrastructure.cs │ │ ├── SetBotServiceAsAvailable.cs │ │ └── UnregisterService.cs │ ├── Events │ │ └── StopServiceInfrastructureRequested.cs │ ├── MappingProfile.cs │ ├── Queries │ │ └── GetService.cs │ └── Specifications │ │ ├── ServiceGetAllSpecifications.cs │ │ ├── ServiceGetByCallIdSpecification.cs │ │ ├── ServiceGetByInfrastructureIdSpecification.cs │ │ └── ServiceGetByVirtualMachineNameSpecification.cs └── Stream │ ├── Commands │ ├── DoDisplayInjection.cs │ ├── DoHideInjection.cs │ ├── DoSetInjectionVolume.cs │ ├── DoStartExtraction.cs │ ├── DoStartInjection.cs │ ├── DoStopExtraction.cs │ ├── DoStopInjection.cs │ ├── RequestDisplayInjection.cs │ ├── RequestHideInjection.cs │ ├── RequestSetInjectionVolume.cs │ ├── RequestStartExtraction.cs │ ├── RequestStartInjection.cs │ ├── RequestStopExtraction.cs │ ├── RequestStopInjection.cs │ ├── UpdateStreamState.cs │ └── ValidateStreamKey.cs │ ├── MappingProfile.cs │ └── Specifications │ ├── StreamGetActiveFromCallSpecification.cs │ └── StreamsGetFromCallSpecification.cs ├── BotService ├── Application │ ├── Core │ │ ├── IMediaExtractor.cs │ │ ├── IMediaHandlerFactory.cs │ │ ├── IMediaInjector.cs │ │ ├── IMediaSocketPool.cs │ │ ├── ISwitchingMediaExtractor.cs │ │ ├── MediaExtractionSettings.cs │ │ ├── MediaInjectionSettings.cs │ │ └── ProtocolSettings.cs │ └── Participant │ │ └── MappingProfile.cs ├── BotService.csproj ├── Configuration │ ├── AppConfiguration.cs │ └── EndpointConfiguration.cs ├── Controllers │ └── BotController.cs ├── Infrastructure │ ├── Client │ │ ├── AuthenticationProvider.cs │ │ ├── GraphCommunicationsClientBuilder.cs │ │ └── IGraphCommunicationsClientBuilder.cs │ ├── Common │ │ ├── CloudRoleNameTelemetryInitializer.cs │ │ ├── EnvironmentPrefixSecretManager.cs │ │ ├── HeartbeatHandler.cs │ │ ├── JoinInfoHelper.cs │ │ └── Logging │ │ │ ├── PipelineBusObserver.cs │ │ │ ├── PipelineBusObserverUnsuscriber.cs │ │ │ └── SampleObserver.cs │ ├── Core │ │ ├── Bot.cs │ │ ├── CallHandler.cs │ │ ├── H264Helper.cs │ │ ├── MediaExtractor.cs │ │ ├── MediaHandlerFactory.cs │ │ ├── MediaInjector.cs │ │ ├── MediaSocketPool.cs │ │ ├── RtmpSettings.cs │ │ ├── SlateMediaInjector.cs │ │ ├── SrtSettings.cs │ │ ├── StreamVolume.cs │ │ └── SwitchingMediaExtractor.cs │ ├── Extensions │ │ ├── BotCertificateHelper.cs │ │ ├── BotConfigurationExtensions.cs │ │ ├── ConfigurationBuilderExtensions.cs │ │ ├── KestrelServerOptionsExtensions.cs │ │ ├── LoggerConfigurationHelper.cs │ │ ├── LoggerExtensions.cs │ │ ├── ParticipantExtensions.cs │ │ ├── SerializationExtensions.cs │ │ ├── StreamVolumeExtensions.cs │ │ ├── SupportedAudioExtensions.cs │ │ └── WebHostServiceExtensions.cs │ ├── Filters │ │ └── ApiExceptionFilterAttribute.cs │ ├── Pipelines │ │ ├── GstreamerClockProvider.cs │ │ ├── GstreamerCustomClock.cs │ │ ├── GstreamerMediaProcessor.cs │ │ ├── GstreamerMediaProcessorFactory.cs │ │ ├── IMediaExtractionPipeline.cs │ │ ├── IMediaInjectionPipeline.cs │ │ ├── IMediaProcessor.cs │ │ ├── IMediaProcessorFactory.cs │ │ ├── MediaInjectionPipeline.cs │ │ ├── RtmpCpuEncodingMediaPipeline.cs │ │ ├── SlateMediaInjectionPipeline.cs │ │ └── SrtCpuEncodingMediaPipeline.cs │ ├── Services │ │ ├── IMediatorService.cs │ │ └── MediatorService.cs │ └── WindowsService │ │ ├── HostService.cs │ │ ├── WindowsServiceState.cs │ │ └── WindowsServiceStatus.cs ├── Program.cs ├── Startup.cs ├── app.config ├── appSettings.json └── slate.png ├── Broadcaster.sln ├── Domain ├── Constants │ └── Constants.cs ├── Domain.csproj ├── Entities │ ├── Base │ │ └── CosmosDbEntity.cs │ ├── Call.cs │ ├── ParticipantStream.cs │ ├── Parts │ │ ├── Infrastructure.cs │ │ ├── ParticipantStreamDetails.cs │ │ ├── ParticipantStreamErrorDetails.cs │ │ ├── ProvisioningDetails.cs │ │ ├── StreamDetails.cs │ │ ├── StreamErrorDetails.cs │ │ └── StreamVolume.cs │ ├── Service.cs │ └── Stream.cs ├── Enums │ ├── BusMessageType.cs │ ├── CallState.cs │ ├── ContextPrivacy.cs │ ├── Enumeration.cs │ ├── KeyLengthValues.cs │ ├── MeetingType.cs │ ├── ParticipantStreamErrorType.cs │ ├── Protocol.cs │ ├── ProvisioningStateType.cs │ ├── ResourceType.cs │ ├── RtmpMode.cs │ ├── ServiceState.cs │ ├── SrtMode.cs │ ├── StreamErrorType.cs │ ├── StreamState.cs │ ├── StreamVolumeFormat.cs │ └── SupportedAudioFormat.cs └── Exceptions │ └── EntityNotFoundException.cs ├── Infrastructure.Core ├── Common │ ├── ExceptionHandler.cs │ ├── Extensions │ │ ├── ActionResultExtensions.cs │ │ ├── HttpExtensions.cs │ │ └── StreamExtensions.cs │ ├── ExtractionUrlHelper.cs │ ├── HostEnvironment.cs │ ├── InjectionUrlHelper.cs │ ├── MeetingUrlHelper.cs │ ├── Models │ │ ├── ErrorDetails.cs │ │ └── ValidationErrorDetails.cs │ └── StreamKeyGeneratorHelper.cs ├── CosmosDbData │ ├── CosmosDbContainerFactory.cs │ ├── CosmosDbSchema.cs │ ├── CosmosDbSetup.cs │ ├── CosmosDbSpecificationEvaluator.cs │ ├── Extensions │ │ └── IServiceCollectionExtensions.cs │ ├── Interfaces │ │ ├── ICosmosDbContainerFactory.cs │ │ └── ICosmosDbSetup.cs │ └── Repository │ │ ├── CallRepository.cs │ │ ├── CosmosDbRepository.cs │ │ ├── ParticipantStreamRepository.cs │ │ ├── ServiceRepository.cs │ │ └── StreamRepository.cs ├── Infrastructure.Core.csproj └── Services │ ├── AzService.cs │ ├── AzStorageHandler.cs │ ├── AzVirtualMachineService.cs │ ├── BotServiceAuthenticationProvider.cs │ ├── BotServiceClient.cs │ ├── CloudConfigurationService.cs │ ├── GraphAuthenticationProvider.cs │ └── MicrosoftGraphService.cs ├── ManagementApi ├── AppConfiguration.cs ├── Controllers │ ├── CallController.cs │ ├── ParticipantController.cs │ └── ServiceController.cs ├── Filters │ ├── AddBuildVersionHeaderFilter.cs │ └── ApiExceptionFilterAttribute.cs ├── ManagementApi.csproj ├── Program.cs ├── Startup.cs └── appsettings.json └── OrchestratorFunction ├── BotOrchestrator.csproj ├── FunctionAppConfiguration.cs ├── OrchestratorFunctions.cs ├── Properties ├── serviceDependencies.json └── serviceDependencies.local.json ├── Startup.cs └── host.json /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 2 | 3 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. 4 | 5 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 6 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 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 22 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | ## How to file issues and get help 4 | 5 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing issues before filing new issues to avoid duplicates. For new issues, file your bug or feature request as a new Issue. 6 | 7 | For help and questions about using this project, please refer to [our contributing guidelines](CONTRIBUTING.md). 8 | 9 | ## Microsoft Support Policy 10 | 11 | Support for this project is limited to the resources listed above. 12 | -------------------------------------------------------------------------------- /docs/common/customize_bdk_slate_image.md: -------------------------------------------------------------------------------- 1 | # Customize the Broadcast Development Kit Slate image 2 | 3 | ## Getting Started 4 | 5 | When the BDK is joined into a Microsoft Teams call, it starts rendering a "Slate" image on the bot spot in the Microsoft Teams client while no media content injection is active. 6 | 7 | By default, the `Slate` image rendered on the Microsoft client is an image provided in the BDK solution, placed on the BDK `BotService` root solution folder. Once the bot is joined into a meeting the following image is displayed on the Microsoft Teams client. 8 | 9 | |![BDK default slate image](images/default-slate-image.png)| 10 | |:--:| 11 | |*Slate Image displayed by the bot when joins into the meeting.*| 12 | 13 | ## Customizing the Slate image 14 | 15 | The `Slate` image rendered by the bot on the Microsoft Teams client can be customized. You only need to change the default image provided in the solution with one of your choosing. 16 | 17 | To do so, please go to the `BotService` solution folder, find the `PNG` file called `slate.png` and replace it with an image of your choosing. 18 | 19 | |![BDK default slate image route](images/default-slate-image-solution-route.png)| 20 | |:--:| 21 | |*Slate image provided on the `BotService` solution*| 22 | 23 | The `Slate` image you need to provide must have the following characteristics: 24 | 25 | - ***Format***: The image format must be PNG. 26 | - ***Name***: The image name must be named `slate`. 27 | - ***Width***: The image width must be 1920px. 28 | - ***Height***: The image height must be 1080px. 29 | 30 | > **NOTE**: The image provided in the solution is copied to the folder where the `BotService` is published. You can also change the image directly from the folder where the bot was published, you do not need to build and publish again the solution, every time you want to change the `Slate` image. 31 | -------------------------------------------------------------------------------- /docs/common/images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/architecture.png -------------------------------------------------------------------------------- /docs/common/images/cert-files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/cert-files.png -------------------------------------------------------------------------------- /docs/common/images/certificate_password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/certificate_password.png -------------------------------------------------------------------------------- /docs/common/images/certificate_personal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/certificate_personal.png -------------------------------------------------------------------------------- /docs/common/images/certificate_thumbprint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/certificate_thumbprint.png -------------------------------------------------------------------------------- /docs/common/images/default-slate-image-solution-route.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/default-slate-image-solution-route.png -------------------------------------------------------------------------------- /docs/common/images/default-slate-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/default-slate-image.png -------------------------------------------------------------------------------- /docs/common/images/import_certificate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/import_certificate.png -------------------------------------------------------------------------------- /docs/common/images/install_nginx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/install_nginx.png -------------------------------------------------------------------------------- /docs/common/images/nginx_as_windows_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/nginx_as_windows_service.png -------------------------------------------------------------------------------- /docs/common/images/nginx_device_monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/nginx_device_monitor.png -------------------------------------------------------------------------------- /docs/common/images/nginx_ffplay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/nginx_ffplay.png -------------------------------------------------------------------------------- /docs/common/images/nginx_repository.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/nginx_repository.png -------------------------------------------------------------------------------- /docs/common/images/nginx_using_gstreamer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/nginx_using_gstreamer.png -------------------------------------------------------------------------------- /docs/common/images/nginx_vlc_player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/nginx_vlc_player.png -------------------------------------------------------------------------------- /docs/common/images/nginx_wasapi_device.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/nginx_wasapi_device.png -------------------------------------------------------------------------------- /docs/common/images/open_nginx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/open_nginx.png -------------------------------------------------------------------------------- /docs/common/images/run_certificate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/common/images/run_certificate.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/app-service-plan.md: -------------------------------------------------------------------------------- 1 | # App Service Plan 2 | 3 | This App Service Plan will define the resources available to execute the Management API and Azure function. To create the App Service Plan, please review the following [Microsoft documentation](https://docs.microsoft.com/en-us/azure/app-service/app-service-plan-manage#create-an-app-service-plan) and use the following settings: 4 | 5 | - ***Resource Group:*** Select the resource group created for the main resources. 6 | - ***Name:*** A meaningful name. 7 | - ***Operating System:*** Windows. 8 | - ***Region:*** Same region as the rest of the resources. 9 | - ***Pricing Tier*** 10 | - ***Sku and size:*** Basic B1. 11 | > **NOTE**: The tier (Shared D1) can be used to reduce costs during the test. However note that this can cause issues, like the Azure Functions not processing the messages from the queues. 12 | 13 | [← Back to How to run the solution in Azure](README.md#provision-azure-resources) | [Next: Web App →](web-app.md#web-app) 14 | -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/application-insights.md: -------------------------------------------------------------------------------- 1 | # Application Insights 2 | 3 | This Application Insights instance will be used to log all the events happening in the solution. To create the Application Insights, please review the following [Microsoft documentation](https://docs.microsoft.com/en-us/azure/azure-monitor/app/create-workspace-resource), and use the following settings: 4 | 5 | - ***Resource Group:*** Select the resource group created for the main resources. 6 | - ***Name:*** A meaningful name. 7 | - ***Region:*** Same region as the rest of the resources. 8 | - ***Resource mode:*** Classic. 9 | 10 | Once the **Application Insights** has been created, within the **Overview** option on the left panel we can view the Instrumentation key. The **instrumentation key** identifies the resource that you want to associate your telemetry data with. You will need to copy the **instrumentation key** to use it later. 11 | 12 | [← Back to How to run the solution in Azure](README.md#provision-azure-resources) | [Next: App Service Plan →](app-service-plan.md#app-service-plan) 13 | -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/azure-sdk-app-registration.md: -------------------------------------------------------------------------------- 1 | # Azure SDK app registration 2 | 3 | This documents explains how to create and configure the Azure SDK app registration to enable the backend components to get access to Azure resources through Azure SDK. 4 | 5 | ## Creation of the app registration 6 | 7 | To create the app registrations, review the following [Microsoft documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app#register-an-application) that will explain how to do it, and consider the following settings: 8 | 9 | - ***Name:*** Meaningful name. 10 | - ***Supported account types:*** Accounts in this organizational directory only (`your-organization` only - Single tenant). 11 | 12 | ## Setup of the app registration 13 | 14 | ### Add a client secret 15 | 16 | Finally, you must [add a client secret](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app#add-a-client-secret), copy the value and add it to the key vault as a secret with the following name: 17 | `Settings--AzServicePrincipalConfiguration--ApplicationClientSecret`. 18 | 19 | ## Give access to the virtual machine 20 | 21 | In order to allow to the backend components to turn on/off the virtual machine through Azure SDK, you give the app registration access to the virtual machine with `Contributor Role` through **Access control (IAM)** menu of the virtual machine resource. 22 | 23 | [← Back to How to run the solution in Azure](README.md#app-registrations) | [Next: Security Group →](README.md#security-group) 24 | -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/cosmos-db.md: -------------------------------------------------------------------------------- 1 | # Cosmos DB 2 | 3 | The **Azure Cosmos DB** database will be used to store the `Broadcast Development Kit` data. To create the Azure Cosmos DB, please review the following [Microsoft documentation](https://docs.microsoft.com/en-us/azure/cosmos-db/create-cosmosdb-resources-portal#create-an-azure-cosmos-db-account), and use the following settings: 4 | 5 | - ***Select API option:*** choose Core (SQL). 6 | - ***Resource Group:*** Select the resource group created for the main resources. 7 | - ***Account Name***: a meaningful name. 8 | - ***Location***: same region as the rest of the resources. 9 | - ***Capacity mode***: Serverless. 10 | - ***Apply Free Tier Discount***: Apply only if there is no other Cosmos DB using it in the subscription. 11 | 12 | Leave the rest of the settings as-is. 13 | 14 | After creating the Cosmos DB account, navigate to the **Data Explorer** option on the resource blade you have on the left and create new database and the following containers ([How to add a database and a container](https://docs.microsoft.com/en-us/azure/cosmos-db/sql/create-cosmosdb-resources-portal#add-a-database-and-a-container)): 15 | 16 | - ***Call*** 17 | - Partition Key: /id 18 | - ***ParticipantStream*** 19 | - Partition Key: /id 20 | - ***Service*** 21 | - Partition Key: /id 22 | - ***Stream*** 23 | - Partition Key: /id 24 | 25 | Finally, navigate to the **Keys** option you have under the **Settings** section on the resource blade, take note of the `PRIMARY KEY` and add it to the key vault as a secret with the following name: 26 | `Settings--CosmosDbConfiguration--PrimaryKey`. 27 | 28 | [← Back to How to run the solution in Azure](README.md#provision-azure-resources) | [Next: Storage Account →](storage-account.md) 29 | -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/function-app.md: -------------------------------------------------------------------------------- 1 | # Function App 2 | 3 | To host the Bot Orchestrator function a Function App must be created in Azure. This document shows how to create the Function App for the Bot Orchestrator. To create the Function App and App Service Plan, please review the following Microsoft [documentation](https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-function-app-portal#create-a-function-app) and use the following settings: 4 | 5 | - ***Basic:*** 6 | - ***Resource Group:*** Select the resource group created for the main resources.the solution architecture. 7 | - ***Name:*** A meaningful name. 8 | - ***Publish:*** Code. 9 | - ***Runtime stack:*** .NET Core 3.1 (LTS). 10 | - ***Region:*** Same region as the rest of the resources. 11 | - ***Hosting:*** 12 | - ***Storage account:*** Select the first [Storage Account](storage_account.md) that was created in the previous steps. 13 | - ***Operative system:*** Windows. 14 | - ***Plan:*** 15 | - ***Plan type:*** App Service plan. 16 | - ***Windows Plan:*** Select the [App Service plan](service_plan.md) created in the previous steps. 17 | - ***Monitoring:*** Enable [application insights](application_insights.md) and select the instance that was created in a previous step. 18 | 19 | ## Enable Managed Identity 20 | 21 | To allow to the Azure Function App Service to get access to key vault (through Key Vault References), you have to enable a system assigned managed identity. To do so, please review the following [Microsoft Documentation](https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=portal%2Chttp#add-a-system-assigned-identity), and take note of the **Object (principal) ID**, you will need it in future steps to configure the Azure Key Vault. 22 | 23 | [← Back to How to run the solution in Azure](README.md#provision-azure-resources) | [Next: Virtual machine →](virtual-machine.md#virtual-machine) 24 | -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/add_graph_permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/add_graph_permissions.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/app_registration_add_client_application.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/app_registration_add_client_application.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/app_registration_add_client_application_blade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/app_registration_add_client_application_blade.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/appi_graph_permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/appi_graph_permissions.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/bot_service_client_enabled_permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/bot_service_client_enabled_permissions.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/configuration_to_publish_bot_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/configuration_to_publish_bot_service.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/configure_windows_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/configure_windows_service.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/create_role_bot_service_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/create_role_bot_service_api.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/create_role_management_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/create_role_management_api.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/deploy_function_app_sa_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/deploy_function_app_sa_check.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/deploy_function_app_sa_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/deploy_function_app_sa_config.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/deploy_function_app_sa_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/deploy_function_app_sa_select.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/deploy_function_app_sa_uncheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/deploy_function_app_sa_uncheck.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/deploy_function_app_select_azure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/deploy_function_app_select_azure.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/deploy_function_app_select_function_app_created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/deploy_function_app_select_function_app_created.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/deploy_function_app_select_specific_destination.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/deploy_function_app_select_specific_destination.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/deploy_web_app_select_azure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/deploy_web_app_select_azure.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/deploy_web_app_select_specific_destination.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/deploy_web_app_select_specific_destination.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/deploy_web_app_select_web_app_created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/deploy_web_app_select_web_app_created.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/function_app_configuration_application_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/function_app_configuration_application_settings.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/function_app_save_new_application_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/function_app_save_new_application_settings.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/function_app_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/function_app_search.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/management_api_add_scope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/management_api_add_scope.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/management_api_optional_claims_of_manifest copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/management_api_optional_claims_of_manifest copy.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/management_api_optional_claims_of_manifest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/management_api_optional_claims_of_manifest.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/manifest_botservice_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/manifest_botservice_api.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/permission_entry_bot_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/permission_entry_bot_service.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/postman_add_service_auth_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/postman_add_service_auth_header.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/postman_add_service_payload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/postman_add_service_payload.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/publish_bot_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/publish_bot_service.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/request_api_permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/request_api_permissions.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/save_publish_from_bot_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/save_publish_from_bot_service.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/search_api_permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/search_api_permissions.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/security_group_add_members.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/security_group_add_members.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/security_group_select_members.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/security_group_select_members.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/test_function_app_postman_send_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/test_function_app_postman_send_start.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/test_function_app_postman_send_state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/test_function_app_postman_send_state.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/test_function_app_postman_send_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/test_function_app_postman_send_stop.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/test_function_app_queues.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/test_function_app_queues.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/test_web_app_postman_add_service_auth_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/test_web_app_postman_add_service_auth_header.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/test_with_postman_web_app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/test_with_postman_web_app.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/web_app_configuration_application_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/web_app_configuration_application_settings.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/web_app_save_new_application_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/web_app_save_new_application_settings.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/images/web_app_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-in-azure/images/web_app_search.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/security-group.md: -------------------------------------------------------------------------------- 1 | # Security Group 2 | 3 | The Security Group will be used to grant access and permissions to predefined users to the application. 4 | 5 | To create the **Security Group** and **add members**, review the following [Microsoft documentation](https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal#create-a-basic-group-and-add-members), and consider the following settings: 6 | 7 | - ***GroupType:*** Select the group type **Security**. 8 | - ***Group name:*** A meaningful name. 9 | - ***Group description:*** A meaningful description (optional). 10 | - ***Membership type:*** Select **Assigned** membership for the group. 11 | 12 | > **NOTE:** You will need the `Group Id` later to configure the solution, so take note of it. 13 | 14 | Once the **Security Group** has been created, it is necessary to add the members of the group that will be able to operate the solution. To add members, it is suggested to carry out the following steps: 15 | 16 | 1. Enter the **Security Group** created and select the *Members* option on the left panel. 17 | ![Add Members](images/security_group_add_members.png) 18 | 2. Then click on the **+ Add members** button and start searching for members to add to your group, and click on the **Select** button to add them. 19 | ![Add Members](images/security_group_select_members.png) 20 | 21 | [← Back to How to run the solution in Azure](README.md#security-group) | [Next: Azure Bot →](README.md#azure-bot) 22 | -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-in-azure/storage-account.md: -------------------------------------------------------------------------------- 1 | # Storage Account 2 | 3 | The Storage Account will be used by the Azure function you are going to setup later. To create a Storage account in Azure, please review the following [Microsoft documentation](https://docs.microsoft.com/en-us/azure/storage/common/storage-account-create?tabs=azure-portal) and use the following settings: 4 | 5 | - ***Resource Group:*** Select the resource group created for the main resources. 6 | - ***Storage account Name***: A meaningful name. 7 | - ***Region***: Same region as the rest of the resources. 8 | - ***Performance***: Standard. 9 | - ***Redundancy***: Locally-redundant storage (LRS). 10 | 11 | Finally, navigate to the **Access keys** option you have under the **Settings** section on the resource blade, take note of the `Connection string` and add it to the key vault as a secret with the following name: 12 | `Settings--StorageConfiguration--ConnectionString`. 13 | 14 | [← Back to How to run the solution in Azure](README.md#provision-azure-resources) | [Next: Setup DNS for the virtual machine →](README.md#setup-dns-for-the-virtual-machine) 15 | -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/botservice_fails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/botservice_fails.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/cosmos_add_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/cosmos_add_service.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/cosmos_db_data_explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/cosmos_db_data_explorer.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/environment_variables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/environment_variables.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/environment_variables_option.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/environment_variables_option.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/environment_variables_path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/environment_variables_path.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/gstreamer_bin_path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/gstreamer_bin_path.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/gstreamer_installer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/gstreamer_installer.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/invite_link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/invite_link.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/ngrok_authtoken.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/ngrok_authtoken.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/ngrok_configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/ngrok_configuration.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/ngrok_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/ngrok_console.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/ngrok_create_config_file_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/ngrok_create_config_file_1.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/ngrok_create_config_file_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/ngrok_create_config_file_2.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/ngrok_create_config_file_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/ngrok_create_config_file_3.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/ngrok_create_config_file_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/ngrok_create_config_file_4.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/ngrok_create_config_file_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/ngrok_create_config_file_5.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/open_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/open_console.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/postman_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/postman_header.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/start.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/startup_projects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/startup_projects.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/test_with_postman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/test_with_postman.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/visual_set_startup_projects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/visual_set_startup_projects.png -------------------------------------------------------------------------------- /docs/how-to-run-the-solution-locally/images/vs_run_as_admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-run-the-solution-locally/images/vs_run_as_admin.png -------------------------------------------------------------------------------- /docs/how-to-use-the-solution/images/added_api_permission.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-use-the-solution/images/added_api_permission.png -------------------------------------------------------------------------------- /docs/how-to-use-the-solution/images/get_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-use-the-solution/images/get_token.png -------------------------------------------------------------------------------- /docs/how-to-use-the-solution/images/get_token_client_credentials.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-use-the-solution/images/get_token_client_credentials.png -------------------------------------------------------------------------------- /docs/how-to-use-the-solution/images/invite_link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-use-the-solution/images/invite_link.png -------------------------------------------------------------------------------- /docs/how-to-use-the-solution/images/management_access_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-use-the-solution/images/management_access_token.png -------------------------------------------------------------------------------- /docs/how-to-use-the-solution/images/management_api_swagger_ui.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-use-the-solution/images/management_api_swagger_ui.jpg -------------------------------------------------------------------------------- /docs/how-to-use-the-solution/images/request_api_permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-use-the-solution/images/request_api_permissions.png -------------------------------------------------------------------------------- /docs/how-to-use-the-solution/images/search_api_permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-use-the-solution/images/search_api_permissions.png -------------------------------------------------------------------------------- /docs/how-to-use-the-solution/images/use_bearer_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/how-to-use-the-solution/images/use_bearer_token.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/gst-play-example-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/gst-play-example-1.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/gst-play-example-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/gst-play-example-2.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/gst-play-example-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/gst-play-example-3.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/multiple-streams-example-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/multiple-streams-example-2.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/multiple-streams-example-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/multiple-streams-example-3.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/multiple-streams-example-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/multiple-streams-example-4.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/multiple-streams-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/multiple-streams-example.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/obs-example-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/obs-example-1.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/obs-example-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/obs-example-2.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/obs-example-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/obs-example-3.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/obs-example-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/obs-example-4.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/obs-example-reset-stream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/obs-example-reset-stream.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/obs-gst-play-comparison-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/obs-gst-play-comparison-2.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/obs-gst-play-comparison-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/obs-gst-play-comparison-3.png -------------------------------------------------------------------------------- /docs/media-synchronization/images/obs-gst-play-comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/docs/media-synchronization/images/obs-gst-play-comparison.png -------------------------------------------------------------------------------- /docs/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Purpose 2 | 3 | _Describe the problem or feature in addition to a link to the issues._ 4 | 5 | ## Approach 6 | 7 | _How does this change address the problem?_ 8 | 9 | ### Open Questions and Pre-Merge TODOs 10 | 11 | - [ ] Use github checklists. When solved, check the box and explain the answer. 12 | 13 | ## Optional 14 | 15 | ### Learning 16 | 17 | _Describe the research stage_ 18 | 19 | _Links to blog posts, patterns, libraries or addons used to solve this problem_ -------------------------------------------------------------------------------- /scripts/Add-GStreamer-Path.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [string] $GStreamerPath = "c:\gstreamer\1.0\mingw_x86_64\bin\" 3 | ) 4 | 5 | if (-not (Test-Path -Path $GStreamerPath)) 6 | { 7 | throw [System.IO.FileNotFoundException] "The GStreamer bin folder ""$GStreamerPath"" does not exist. Verify that GStreamer is installed and use -GStreamerPath parameter to specify the GStream bin path location (default $GStreamerPath)" 8 | } 9 | 10 | $RegexAddPath = [regex]::Escape($GStreamerPath) 11 | $UserPath = [Environment]::GetEnvironmentVariable("PATH", [EnvironmentVariableTarget]::User) 12 | $ArrPath = $UserPath -split ';' | Where-Object {$_ -notMatch "^$RegexAddPath\\?"} 13 | $NewPath = ($ArrPath + $GStreamerPath) -join ';' 14 | 15 | [Environment]::SetEnvironmentVariable("PATH", $NewPath, [EnvironmentVariableTarget]::User) 16 | 17 | Write-Host "Added '$GStreamerPath' to PATH environment variable" 18 | -------------------------------------------------------------------------------- /src/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # S1135: Track uses of "TODO" tags 4 | dotnet_diagnostic.S1135.severity = suggestion 5 | 6 | # S1075: URIs should not be hardcoded 7 | dotnet_diagnostic.S1075.severity = suggestion 8 | 9 | # SA1200: Using directives should be placed correctly 10 | dotnet_diagnostic.SA1200.severity = none 11 | 12 | # SA1600: Elements should be documented 13 | dotnet_diagnostic.SA1600.severity = none 14 | 15 | # SA1101: Prefix local calls with this 16 | dotnet_diagnostic.SA1101.severity = none 17 | 18 | # SA1309: Field names should not begin with underscore 19 | dotnet_diagnostic.SA1309.severity = none 20 | 21 | # SA1310: Field names should not contain underscore 22 | dotnet_diagnostic.SA1310.severity = none 23 | 24 | # SA1633: File should have header 25 | dotnet_diagnostic.SA1633.severity = none 26 | 27 | # SA1402: File may only contain a single type 28 | dotnet_diagnostic.SA1402.severity = none 29 | 30 | # SA1132: Do not combine fields 31 | dotnet_diagnostic.SA1132.severity = none 32 | 33 | # SA1602: Enumeration items should be documented 34 | dotnet_diagnostic.SA1602.severity = none 35 | 36 | # SA1314: Type parameter names should begin with T 37 | dotnet_diagnostic.SA1314.severity = none 38 | 39 | # SA1124: Do not use regions 40 | dotnet_diagnostic.SA1124.severity = none 41 | 42 | # SA0001: XML comment analysis disabled 43 | dotnet_diagnostic.SA0001.severity = none 44 | -------------------------------------------------------------------------------- /src/Application/Call/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Call.Commands; 4 | using Application.Common.Models; 5 | using AutoMapper; 6 | 7 | namespace Application.Call 8 | { 9 | /// 10 | /// Mapping Profile for AutoMapper. 11 | /// 12 | public class MappingProfile : Profile 13 | { 14 | public MappingProfile() 15 | { 16 | // Create 17 | CreateMap(); 18 | 19 | CreateMap(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Application/Call/Queries/GetActiveCalls.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Collections.Generic; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Application.Call.Specifications; 7 | using Application.Common.Models; 8 | using Application.Interfaces.Persistance; 9 | using AutoMapper; 10 | using MediatR; 11 | 12 | namespace Application.Call.Queries 13 | { 14 | public class GetActiveCalls 15 | { 16 | public class GetActiveCallsQuery : IRequest 17 | { 18 | } 19 | 20 | public class GetActiveCallsQueryResponse 21 | { 22 | public List Calls { get; set; } 23 | } 24 | 25 | public class GetActiveCallsQueryHandler : IRequestHandler 26 | { 27 | private readonly ICallRepository _callRespository; 28 | private readonly IMapper _mapper; 29 | 30 | public GetActiveCallsQueryHandler(ICallRepository callRespository, IMapper mapper) 31 | { 32 | _callRespository = callRespository; 33 | _mapper = mapper; 34 | } 35 | 36 | public async Task Handle(GetActiveCallsQuery query, CancellationToken cancellationToken) 37 | { 38 | GetActiveCallsQueryResponse response = new GetActiveCallsQueryResponse(); 39 | 40 | var specification = new CallGetActiveSpecification(); 41 | 42 | var calls = await _callRespository.GetItemsAsync(specification); 43 | 44 | var callModels = _mapper.Map, List>(calls); 45 | 46 | response.Calls = callModels; 47 | 48 | return response; 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Application/Call/Specifications/CallGetActiveSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | using Domain.Enums; 5 | 6 | namespace Application.Call.Specifications 7 | { 8 | public class CallGetActiveSpecification : Specification 9 | { 10 | public CallGetActiveSpecification() 11 | { 12 | Query.Where(x => x.State == CallState.Established) 13 | .OrderByDescending(x => x.CreatedAt); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Application/Call/Specifications/CallGetArchivedAggregationSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | using Domain.Enums; 5 | 6 | namespace Application.Call.Specifications 7 | { 8 | public class CallGetArchivedAggregationSpecification : Specification 9 | { 10 | public CallGetArchivedAggregationSpecification() 11 | { 12 | Query.Where(x => x.State == CallState.Terminated) 13 | .OrderByDescending(x => x.CreatedAt); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Application/Call/Specifications/CallGetArchivedSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | using Domain.Enums; 5 | 6 | namespace Application.Call.Specifications 7 | { 8 | public class CallGetArchivedSpecification : Specification 9 | { 10 | public CallGetArchivedSpecification(int pageNumber = 0, int pageSize = 50) 11 | { 12 | Query.Where(x => x.State == CallState.Terminated) 13 | .OrderByDescending(x => x.CreatedAt); 14 | 15 | // Pagination - Display all entries and disable pagination 16 | if (pageSize != -1) 17 | { 18 | Query.Skip(pageSize * (pageNumber - 1)).Take(pageSize); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Application/Call/Specifications/CallGetByMeetingIdSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Ardalis.Specification; 5 | using Domain.Enums; 6 | 7 | namespace Application.Call.Specifications 8 | { 9 | public class CallGetByMeetingIdSpecification : Specification 10 | { 11 | public CallGetByMeetingIdSpecification(string meetingId) 12 | { 13 | var today = DateTime.Today.Date; 14 | 15 | Query.Where(x => x.MeetingId == meetingId 16 | && (x.State == CallState.Establishing || x.State == CallState.Established) 17 | && x.CreatedAt > today).OrderByDescending(x => x.CreatedAt); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Application/Common/Config/AzServicePrincipalConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Common.Config 4 | { 5 | public class AzServicePrincipalConfiguration 6 | { 7 | public string ApplicationClientId { get; set; } 8 | 9 | public string ApplicationClientSecret { get; set; } 10 | 11 | public string TenantId { get; set; } 12 | 13 | public string SubscriptionId { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Application/Common/Config/AzStorageConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Common.Config 4 | { 5 | public class AzStorageConfiguration 6 | { 7 | public string ConnectionString { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/Application/Common/Config/AzureAdConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Common.Config 4 | { 5 | public class AzureAdConfiguration 6 | { 7 | public string Instance { get; set; } 8 | 9 | public string TenantId { get; set; } 10 | 11 | public string GroupId { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Application/Common/Config/BotServiceAuthenticationConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Application.Common.Config 8 | { 9 | public class BotServiceAuthenticationConfiguration 10 | { 11 | public string ClientId { get; set; } 12 | 13 | public string ClientSecret { get; set; } 14 | 15 | public string BotServiceApiClientId { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Application/Common/Config/CloudConfigSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Common.Config 4 | { 5 | public class CloudConfigSettings 6 | { 7 | public string StorageAccountName { get; set; } 8 | 9 | public string BlobContainerName { get; set; } 10 | 11 | public string AppSettingsFileName { get; set; } 12 | 13 | public string CertificateFileName { get; set; } 14 | 15 | public string SasToken { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Application/Common/Config/CosmosDbConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Common.Config 4 | { 5 | public class CosmosDbConfiguration 6 | { 7 | /// 8 | /// Gets or sets the CosmosDb Account - The Azure Cosmos DB endpoint. 9 | /// 10 | public string EndpointUrl { get; set; } 11 | 12 | /// 13 | /// Gets or sets the Key - The primary key for the Azure DocumentDB account. 14 | /// 15 | public string PrimaryKey { get; set; } 16 | 17 | /// 18 | /// Gets or sets the Database nam. 19 | /// 20 | public string DatabaseName { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /src/Application/Common/Config/DevelopmentConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Common.Config 4 | { 5 | public class DevelopmentConfiguration 6 | { 7 | public string DefaultBotApiBaseUrl { get; set; } = "localhost:9441"; 8 | } 9 | } -------------------------------------------------------------------------------- /src/Application/Common/Config/GraphClientConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Common.Config 4 | { 5 | public class GraphClientConfiguration 6 | { 7 | public string TenantId { get; set; } 8 | 9 | public string ClientId { get; set; } 10 | 11 | public string ClientSecret { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Application/Common/Config/HttpRouteConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Common.Config 4 | { 5 | public static class HttpRouteConstants 6 | { 7 | /// 8 | /// Route prefix for all incoming requests. 9 | /// 10 | public const string CallSignalingRoutePrefix = "api/bot"; 11 | 12 | /// 13 | /// Route for incoming call requests. 14 | /// 15 | public const string OnIncomingRequestRoute = "calling"; 16 | 17 | /// 18 | /// Route for incoming notification requests. 19 | /// 20 | public const string OnNotificationRequestRoute = "notification"; 21 | 22 | public const string JoinCall = "JoinCall"; 23 | public const string Logs = "logs/"; 24 | } 25 | } -------------------------------------------------------------------------------- /src/Application/Common/Config/IAppConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Config 6 | { 7 | public interface IAppConfiguration 8 | { 9 | string BuildVersion { get; set; } 10 | 11 | string KeyVaultName { get; set; } 12 | 13 | string KeyVaultEnv { get; set; } 14 | 15 | GraphClientConfiguration GraphClientConfiguration { get; } 16 | 17 | AzStorageConfiguration StorageConfiguration { get; } 18 | 19 | CosmosDbConfiguration CosmosDbConfiguration { get; } 20 | 21 | BotConfiguration BotConfiguration { get; } 22 | 23 | AzServicePrincipalConfiguration AzServicePrincipalConfiguration { get; } 24 | 25 | AzureAdConfiguration AzureAdConfiguration { get; } 26 | 27 | BotServiceAuthenticationConfiguration BotServiceAuthenticationConfiguration { get; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Application/Common/Converter/JsonCreationConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Linq; 6 | 7 | namespace Application.Common.Converter 8 | { 9 | public abstract class JsonCreationConverter : JsonConverter 10 | { 11 | public override bool CanWrite 12 | { 13 | get 14 | { 15 | return false; 16 | } 17 | } 18 | 19 | public override bool CanConvert(Type objectType) 20 | { 21 | return typeof(T).IsAssignableFrom(objectType); 22 | } 23 | 24 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 25 | { 26 | reader = reader ?? throw new ArgumentNullException(nameof(reader)); 27 | serializer = serializer ?? throw new ArgumentNullException(nameof(serializer)); 28 | if (reader.TokenType == JsonToken.Null) 29 | { 30 | return null; 31 | } 32 | 33 | JObject jObject = JObject.Load(reader); 34 | T target = Create(objectType, jObject); 35 | serializer.Populate(jObject.CreateReader(), target); 36 | return target; 37 | } 38 | 39 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 40 | { 41 | throw new NotImplementedException(); 42 | } 43 | 44 | protected abstract T Create(Type objectType, JObject jObject); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Application/Common/Converter/StartStreamExtractionBodyConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Application.Common.Models; 5 | using Domain.Enums; 6 | using Newtonsoft.Json.Linq; 7 | 8 | namespace Application.Common.Converter 9 | { 10 | public class StartStreamExtractionBodyConverter : JsonCreationConverter 11 | { 12 | protected override StartStreamExtractionBody Create(Type objectType, JObject jObject) 13 | { 14 | if (jObject == null) 15 | { 16 | throw new ArgumentNullException(nameof(jObject)); 17 | } 18 | 19 | var value = jObject["protocol"] == null ? jObject["Protocol"].ToString() : jObject["protocol"].ToString(); 20 | var protocol = (Protocol)Enum.Parse(typeof(Protocol), value); 21 | 22 | if (protocol == Protocol.RTMP) 23 | { 24 | return new RtmpStreamExtractionBody(); 25 | } 26 | else if (protocol == Protocol.SRT) 27 | { 28 | return new SrtStreamExtractionBody(); 29 | } 30 | else 31 | { 32 | return new StartStreamExtractionBody(); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Application/Common/Converter/StartStreamInjectionBodyConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Application.Common.Models; 5 | using Domain.Enums; 6 | using Newtonsoft.Json.Linq; 7 | 8 | namespace Application.Common.Converter 9 | { 10 | public class StartStreamInjectionBodyConverter : JsonCreationConverter 11 | { 12 | protected override StartStreamInjectionBody Create(Type objectType, JObject jObject) 13 | { 14 | jObject = jObject ?? throw new ArgumentNullException(nameof(jObject)); 15 | 16 | var value = jObject["protocol"] == null ? jObject["Protocol"].ToString() : jObject["protocol"].ToString(); 17 | var protocol = (Protocol)Enum.Parse(typeof(Protocol), value); 18 | 19 | if (protocol == Protocol.RTMP) 20 | { 21 | return new RtmpStreamInjectionBody(); 22 | } 23 | else if (protocol == Protocol.SRT) 24 | { 25 | return new SrtStreamInjectionBody(); 26 | } 27 | else 28 | { 29 | return new StartStreamInjectionBody(); 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Application/Common/Models/Api/SetInjectionVolumeRequest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Models.Api 6 | { 7 | public class SetInjectionVolumeRequest 8 | { 9 | public StreamVolumeFormat Format { get; set; } 10 | 11 | public double Value { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Application/Common/Models/CallModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Collections.Generic; 5 | using Domain.Enums; 6 | 7 | namespace Application.Common.Models 8 | { 9 | public class CallModel 10 | { 11 | public string Id { get; set; } 12 | 13 | public string MeetingUrl { get; set; } 14 | 15 | public string MeetingId { get; set; } 16 | 17 | public CallState State { get; set; } 18 | 19 | public DateTime CreatedAt { get; set; } 20 | 21 | public DateTime StartedAt { get; set; } 22 | 23 | public DateTime EndedAt { get; set; } 24 | 25 | public MeetingType MeetingType { get; set; } 26 | 27 | public string BotFqdn { get; set; } 28 | 29 | public string BotIp { get; set; } 30 | 31 | public string DefaultPassphrase { get; set; } 32 | 33 | public int DefaultLatency { get; set; } 34 | 35 | public string GraphId { get; set; } 36 | 37 | public bool IsBotMuted { get; set; } 38 | 39 | public List Streams { get; set; } = new List(); 40 | 41 | public StreamModel InjectionStream { get; set; } 42 | 43 | public Dictionary PublicContext { get; set; } = new Dictionary(); 44 | 45 | public Dictionary PrivateContext { get; set; } = new Dictionary(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Application/Common/Models/GetPublicCallForParticipantBody.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Models 6 | { 7 | public class GetPublicCallForParticipantBody 8 | { 9 | public ResourceType Type { get; set; } 10 | 11 | public string ParticipantAadId { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Application/Common/Models/InfrastructureModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Common.Models 4 | { 5 | public class InfrastructureModel 6 | { 7 | public string VirtualMachineName { get; set; } 8 | 9 | public string ResourceGroup { get; set; } 10 | 11 | public string SubscriptionId { get; set; } 12 | 13 | public string Id { get; set; } 14 | 15 | public string PowerState { get; set; } 16 | 17 | public string IpAddress { get; set; } 18 | 19 | public string Dns { get; set; } 20 | 21 | public ProvisioningDetailsModel ProvisioningDetails { get; set; } = new ProvisioningDetailsModel(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Application/Common/Models/JoinUrlContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Runtime.Serialization; 4 | 5 | namespace Application.Common.Models 6 | { 7 | /// 8 | /// Join URL context. 9 | /// 10 | [DataContract] 11 | public class JoinUrlContext 12 | { 13 | /// 14 | /// Gets or sets the Tenant Id. 15 | /// 16 | [DataMember] 17 | public string Tid { get; set; } 18 | 19 | /// 20 | /// Gets or sets the AAD object id of the user. 21 | /// 22 | [DataMember] 23 | public string Oid { get; set; } 24 | 25 | /// 26 | /// Gets or sets the chat message id. 27 | /// 28 | [DataMember] 29 | public string MessageId { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Application/Common/Models/PagedQueryResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Collections.Generic; 4 | 5 | namespace Application.Common.Models 6 | { 7 | public class PagedQueryResult 8 | { 9 | public int CurrentPage { get; set; } 10 | 11 | public int PageSize { get; set; } 12 | 13 | public int TotalPages { get; set; } 14 | 15 | public long TotalItems { get; set; } 16 | 17 | public IList Items { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Application/Common/Models/ParticipantStreamDetailsModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Domain.Enums; 5 | 6 | namespace Application.Common.Models 7 | { 8 | public class ParticipantStreamDetailsModel 9 | { 10 | public string StreamUrl { get; set; } 11 | 12 | public bool AudioDemuxed { get; set; } 13 | 14 | public string Passphrase { get; set; } 15 | 16 | public KeyLengthValues KeyLength { get; set; } 17 | 18 | public int Latency { get; set; } 19 | 20 | public string PreviewUrl { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /src/Application/Common/Models/ParticipantStreamModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Domain.Entities.Parts; 5 | using Domain.Enums; 6 | 7 | namespace Application.Common.Models 8 | { 9 | public class ParticipantStreamModel 10 | { 11 | public string Id { get; set; } 12 | 13 | public string AadId { get; set; } 14 | 15 | public string CallId { get; set; } 16 | 17 | public string ParticipantGraphId { get; set; } 18 | 19 | public string DisplayName { get; set; } 20 | 21 | public string PhotoUrl { get; set; } 22 | 23 | public ResourceType Type { get; set; } 24 | 25 | public StreamState State { get; set; } 26 | 27 | public bool IsHealthy { get; set; } 28 | 29 | public string HealthMessage { get; set; } 30 | 31 | public bool AudioMuted { get; set; } 32 | 33 | public bool IsSharingAudio { get; set; } 34 | 35 | public bool IsSharingVideo { get; set; } 36 | 37 | public bool IsSharingScreen { get; set; } 38 | 39 | public ParticipantStreamDetailsModel Details { get; set; } = new ParticipantStreamDetailsModel(); 40 | 41 | public DateTime CreatedAt { get; set; } 42 | 43 | public DateTime? LeftAt { get; set; } 44 | 45 | public StreamErrorDetails Error { get; set; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Application/Common/Models/ProvisioningDetailsModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Models 6 | { 7 | public class ProvisioningDetailsModel 8 | { 9 | public ProvisioningStateType State { get; set; } 10 | 11 | public string Message { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Application/Common/Models/PublicCallModelForParticipant.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Collections.Generic; 4 | using Domain.Enums; 5 | 6 | namespace Application.Common.Models 7 | { 8 | public class PublicCallModelForParticipant 9 | { 10 | public CallState State { get; set; } 11 | 12 | public StreamState StreamState { get; set; } 13 | 14 | public Dictionary PublicContext { get; set; } = new Dictionary(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Application/Common/Models/ResourceIdentity.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Application.Common.Models 5 | { 6 | public class ResourceIdentity 7 | { 8 | public string Id { get; set; } 9 | 10 | public string DisplayName { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Application/Common/Models/RtmpStreamExtractionBody.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Models 6 | { 7 | public class RtmpStreamExtractionBody : StartStreamExtractionBody 8 | { 9 | public RtmpMode Mode { get; set; } 10 | 11 | public bool EnableSsl { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Application/Common/Models/RtmpStreamInjectionBody.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Models 6 | { 7 | public class RtmpStreamInjectionBody : StartStreamInjectionBody 8 | { 9 | public bool EnableSsl { get; set; } 10 | 11 | public RtmpMode Mode { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Application/Common/Models/ServiceModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Domain.Enums; 5 | 6 | namespace Application.Common.Models 7 | { 8 | public class ServiceModel 9 | { 10 | public string Id { get; set; } 11 | 12 | public string CallId { get; set; } 13 | 14 | public string Name { get; set; } 15 | 16 | public ServiceState State { get; set; } 17 | 18 | public DateTime CreatedAt { get; set; } 19 | 20 | public InfrastructureModel Infrastructure { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Application/Common/Models/SrtStreamExtractionBody.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Models 6 | { 7 | public class SrtStreamExtractionBody : StartStreamExtractionBody 8 | { 9 | public int Latency { get; set; } 10 | 11 | public SrtMode Mode { get; set; } 12 | 13 | public KeyLengthValues KeyLength { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Application/Common/Models/SrtStreamInjectionBody.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Models 6 | { 7 | public class SrtStreamInjectionBody : StartStreamInjectionBody 8 | { 9 | public int Latency { get; set; } 10 | 11 | public SrtMode Mode { get; set; } 12 | 13 | public KeyLengthValues KeyLength { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Application/Common/Models/StartRtmpStreamExtractionResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Models 6 | { 7 | public class StartRtmpStreamExtractionResponse : StartStreamExtractionResponse 8 | { 9 | public RtmpMode Mode { get; set; } 10 | 11 | public bool EnableSsl { get; set; } 12 | 13 | public string StreamUrl { get; set; } 14 | 15 | public string StreamKey { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Application/Common/Models/StartSrtStreamExtractionResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Models 6 | { 7 | public class StartSrtStreamExtractionResponse : StartStreamExtractionResponse 8 | { 9 | public SrtMode Mode { get; set; } 10 | 11 | public string Url { get; set; } 12 | 13 | public string Passphrase { get; set; } 14 | 15 | public int Latency { get; set; } 16 | 17 | public KeyLengthValues KeyLength { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Application/Common/Models/StartStreamExtractionBody.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Common.Converter; 4 | using Domain.Enums; 5 | using Newtonsoft.Json; 6 | 7 | namespace Application.Common.Models 8 | { 9 | [JsonConverter(typeof(StartStreamExtractionBodyConverter))] 10 | public class StartStreamExtractionBody 11 | { 12 | public Protocol Protocol { get; set; } 13 | 14 | public ResourceType ResourceType { get; set; } 15 | 16 | public string CallId { get; set; } 17 | 18 | public string ParticipantId { get; set; } 19 | 20 | public string ParticipantGraphId { get; set; } 21 | 22 | public string StreamUrl { get; set; } 23 | 24 | public string StreamKey { get; set; } 25 | 26 | public bool TimeOverlay { get; set; } = true; 27 | 28 | public SupportedAudioFormat AudioFormat { get; set; } = SupportedAudioFormat.AAC_44100; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Application/Common/Models/StartStreamExtractionResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Models 6 | { 7 | public class StartStreamExtractionResponse 8 | { 9 | public Protocol Protocol { get; set; } 10 | 11 | public SupportedAudioFormat AudioFormat { get; set; } 12 | 13 | public bool TimeOverlay { get; set; } 14 | 15 | public int Port { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Application/Common/Models/StartStreamInjectionBody.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Common.Converter; 4 | using Application.Common.Models.Api; 5 | using Domain.Enums; 6 | using Newtonsoft.Json; 7 | 8 | namespace Application.Common.Models 9 | { 10 | [JsonConverter(typeof(StartStreamInjectionBodyConverter))] 11 | public class StartStreamInjectionBody 12 | { 13 | public string StreamId { get; set; } 14 | 15 | public string CallId { get; set; } 16 | 17 | public string StreamUrl { get; set; } 18 | 19 | public string StreamKey { get; set; } 20 | 21 | public Protocol Protocol { get; set; } 22 | 23 | public SetInjectionVolumeRequest StreamVolume { get; set; } = new SetInjectionVolumeRequest 24 | { 25 | Format = StreamVolumeFormat.Cubic, 26 | Value = 1.0, 27 | }; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Application/Common/Models/StopStreamExtractionBody.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Application.Common.Models 6 | { 7 | public class StopStreamExtractionBody 8 | { 9 | public string CallId { get; set; } 10 | 11 | public string ParticipantId { get; set; } 12 | 13 | public string ParticipantGraphId { get; set; } 14 | 15 | public ResourceType ResourceType { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Application/Common/Models/StopStreamExtractionResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Common.Models 4 | { 5 | public class StopStreamExtractionResponse 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Application/Common/Models/StreamModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Domain.Entities.Parts; 5 | using Domain.Enums; 6 | 7 | namespace Application.Common.Models 8 | { 9 | public class StreamModel 10 | { 11 | public string Id { get; set; } 12 | 13 | public string CallId { get; set; } 14 | 15 | public string InjectionUrl { get; set; } 16 | 17 | public string Passphrase { get; set; } 18 | 19 | public int Latency { get; set; } 20 | 21 | public KeyLengthValues KeyLength { get; set; } 22 | 23 | public StreamState State { get; set; } 24 | 25 | public DateTime StartingAt { get; set; } 26 | 27 | public DateTime StartedAt { get; set; } 28 | 29 | public DateTime EndingAt { get; set; } 30 | 31 | public DateTime EndedAt { get; set; } 32 | 33 | public Protocol Protocol { get; set; } 34 | 35 | public dynamic StreamMode { get; set; } 36 | 37 | public StreamVolume StreamVolume { get; set; } 38 | 39 | public bool VideoFeedOn { get; set; } 40 | 41 | public StreamErrorDetails Error { get; set; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Application/Common/ValidationBehaviour.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Application.Exceptions; 8 | using FluentValidation; 9 | using MediatR; 10 | 11 | namespace Application.Common 12 | { 13 | public class ValidationBehaviour : IPipelineBehavior 14 | where TRequest : IRequest 15 | { 16 | private readonly IEnumerable> _validators; 17 | 18 | public ValidationBehaviour(IEnumerable> validators) 19 | { 20 | _validators = validators; 21 | } 22 | 23 | public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next) 24 | { 25 | if (_validators.Any()) 26 | { 27 | var context = new ValidationContext(request); 28 | 29 | var validationResults = await Task.WhenAll(_validators.Select(v => v.ValidateAsync(context, cancellationToken))); 30 | var failures = validationResults.SelectMany(r => r.Errors).Where(f => f != null).ToList(); 31 | 32 | if (failures.Count != 0) 33 | { 34 | throw new ApiValidationException(failures); 35 | } 36 | } 37 | 38 | return await next(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Application/DependencyInjection.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Reflection; 4 | using Application.Common; 5 | using AutoMapper; 6 | using FluentValidation; 7 | using MediatR; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | namespace Application 11 | { 12 | public static class DependencyInjection 13 | { 14 | public static IServiceCollection AddApplication(this IServiceCollection services) 15 | { 16 | services.AddAutoMapper(Assembly.GetExecutingAssembly()); 17 | services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly()); 18 | services.AddMediatR(Assembly.GetExecutingAssembly()); 19 | services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>)); 20 | 21 | return services; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Application/Exceptions/ApiValidationException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Runtime.Serialization; 7 | using FluentValidation.Results; 8 | using Microsoft.AspNetCore.Mvc.ModelBinding; 9 | 10 | namespace Application.Exceptions 11 | { 12 | [Serializable] 13 | public class ApiValidationException : Exception 14 | { 15 | public ApiValidationException() 16 | : base("One or more validation failures have occurred.") 17 | { 18 | Errors = new Dictionary(); 19 | ModelState = new ModelStateDictionary(); 20 | } 21 | 22 | public ApiValidationException(IEnumerable failures) 23 | : this() 24 | { 25 | Errors = failures 26 | .GroupBy(e => e.PropertyName, e => e.ErrorMessage) 27 | .ToDictionary(failureGroup => failureGroup.Key, failureGroup => failureGroup.ToArray()); 28 | 29 | foreach (var failure in failures) 30 | { 31 | ModelState.AddModelError(failure.PropertyName, failure.ErrorMessage); 32 | } 33 | } 34 | 35 | protected ApiValidationException(SerializationInfo info, StreamingContext context) 36 | : base(info, context) 37 | { 38 | } 39 | 40 | public IDictionary Errors { get; } 41 | 42 | public ModelStateDictionary ModelState { get; } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Application/Exceptions/BotClientBaseUrlNotSetException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Application.Exceptions 7 | { 8 | [Serializable] 9 | public class BotClientBaseUrlNotSetException : Exception 10 | { 11 | public BotClientBaseUrlNotSetException() 12 | { 13 | } 14 | 15 | public BotClientBaseUrlNotSetException(string message) 16 | : base(message) 17 | { 18 | } 19 | 20 | protected BotClientBaseUrlNotSetException(SerializationInfo info, StreamingContext context) 21 | : base(info, context) 22 | { 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Application/Exceptions/CertificateNotFoundException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Application.Exceptions 7 | { 8 | [Serializable] 9 | public class CertificateNotFoundException : Exception 10 | { 11 | public CertificateNotFoundException() 12 | { 13 | } 14 | 15 | public CertificateNotFoundException(string message) 16 | : base(message) 17 | { 18 | } 19 | 20 | protected CertificateNotFoundException(SerializationInfo info, StreamingContext context) 21 | : base(info, context) 22 | { 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Application/Exceptions/CustomBaseException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Net; 5 | using System.Runtime.Serialization; 6 | 7 | namespace Application.Exceptions 8 | { 9 | [Serializable] 10 | public class CustomBaseException : Exception 11 | { 12 | public CustomBaseException(HttpStatusCode statusCode = HttpStatusCode.InternalServerError) 13 | : base("An error occurred while processing your request.") 14 | { 15 | StatusCode = statusCode; 16 | } 17 | 18 | public CustomBaseException(string message, HttpStatusCode statusCode = HttpStatusCode.InternalServerError) 19 | : base(message) 20 | { 21 | StatusCode = statusCode; 22 | } 23 | 24 | public CustomBaseException(string title, string message, HttpStatusCode statusCode = HttpStatusCode.InternalServerError) 25 | : base(message) 26 | { 27 | Title = title; 28 | StatusCode = statusCode; 29 | } 30 | 31 | protected CustomBaseException(SerializationInfo info, StreamingContext context) 32 | : base(info, context) 33 | { 34 | } 35 | 36 | public string Title { get; set; } 37 | 38 | public HttpStatusCode StatusCode { get; set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Application/Exceptions/GenerateStreamKeyException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Net; 5 | using System.Runtime.Serialization; 6 | 7 | namespace Application.Exceptions 8 | { 9 | [Serializable] 10 | public class GenerateStreamKeyException : CustomBaseException 11 | { 12 | public GenerateStreamKeyException(string title, string message) 13 | : base(message) 14 | { 15 | Title = title; 16 | StatusCode = HttpStatusCode.InternalServerError; 17 | } 18 | 19 | protected GenerateStreamKeyException(SerializationInfo info, StreamingContext context) 20 | : base(info, context) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Application/Exceptions/Models/ExceptionDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Exceptions.Models 4 | { 5 | public class ExceptionDetails 6 | { 7 | public int? Status { get; set; } 8 | 9 | public string Title { get; set; } 10 | 11 | public string InnerException { get; set; } 12 | 13 | public string Detail { get; set; } 14 | 15 | public string StackTrace { get; set; } 16 | 17 | public string Identifier { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Application/Exceptions/NotSuccessfulRequestException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Net; 5 | using System.Runtime.Serialization; 6 | using Application.Exceptions.Models; 7 | 8 | namespace Application.Exceptions 9 | { 10 | [Serializable] 11 | public class NotSuccessfulRequestException : Exception 12 | { 13 | public NotSuccessfulRequestException(HttpStatusCode statusCode, string message) 14 | : base(message) 15 | { 16 | StatusCode = statusCode; 17 | } 18 | 19 | public NotSuccessfulRequestException(HttpStatusCode statusCode, ExceptionDetails details) 20 | : base(details.Detail) 21 | { 22 | StatusCode = statusCode; 23 | RequestDetails = details; 24 | } 25 | 26 | protected NotSuccessfulRequestException(SerializationInfo info, StreamingContext context) 27 | : base(info, context) 28 | { 29 | } 30 | 31 | public ExceptionDetails RequestDetails { get; private set; } 32 | 33 | public HttpStatusCode StatusCode { get; set; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Application/Exceptions/NotValidStreamKeyException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Net; 5 | using System.Runtime.Serialization; 6 | 7 | namespace Application.Exceptions 8 | { 9 | [Serializable] 10 | public class NotValidStreamKeyException : CustomBaseException 11 | { 12 | public NotValidStreamKeyException(string title, string message) 13 | : base(message) 14 | { 15 | Title = title; 16 | StatusCode = HttpStatusCode.Unauthorized; 17 | } 18 | 19 | protected NotValidStreamKeyException(SerializationInfo info, StreamingContext context) 20 | : base(info, context) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Application/Exceptions/ServiceUnavailableException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Application.Exceptions 7 | { 8 | [Serializable] 9 | public class ServiceUnavailableException : Exception 10 | { 11 | public ServiceUnavailableException() 12 | { 13 | } 14 | 15 | public ServiceUnavailableException(string message) 16 | : base(message) 17 | { 18 | } 19 | 20 | protected ServiceUnavailableException(SerializationInfo info, StreamingContext context) 21 | : base(info, context) 22 | { 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Application/Exceptions/SetStreamVolumeException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Application.Exceptions 7 | { 8 | [Serializable] 9 | public class SetStreamVolumeException : CustomBaseException 10 | { 11 | public SetStreamVolumeException(string title, string message) 12 | : base(title, message) 13 | { 14 | } 15 | 16 | protected SetStreamVolumeException(SerializationInfo info, StreamingContext context) 17 | : base(info, context) 18 | { 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Application/Exceptions/StartStreamExtractionException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Application.Exceptions 7 | { 8 | [Serializable] 9 | public class StartStreamExtractionException : Exception 10 | { 11 | public StartStreamExtractionException() 12 | { 13 | } 14 | 15 | public StartStreamExtractionException(string message) 16 | : base(message) 17 | { 18 | } 19 | 20 | protected StartStreamExtractionException(SerializationInfo info, StreamingContext context) 21 | : base(info, context) 22 | { 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Application/Exceptions/StartStreamInjectionException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Application.Exceptions 7 | { 8 | [Serializable] 9 | public class StartStreamInjectionException : Exception 10 | { 11 | public StartStreamInjectionException() 12 | : base(null) 13 | { 14 | } 15 | 16 | public StartStreamInjectionException(string message) 17 | : base(message, null) 18 | { 19 | } 20 | 21 | public StartStreamInjectionException(string message, Exception innerException) 22 | : base(message, innerException) 23 | { 24 | } 25 | 26 | protected StartStreamInjectionException(SerializationInfo info, StreamingContext context) 27 | : base(info, context) 28 | { 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Application/Exceptions/StopStreamExtractionException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Application.Exceptions 7 | { 8 | [Serializable] 9 | public class StopStreamExtractionException : Exception 10 | { 11 | public StopStreamExtractionException() 12 | { 13 | } 14 | 15 | public StopStreamExtractionException(string message) 16 | : base(message) 17 | { 18 | } 19 | 20 | protected StopStreamExtractionException(SerializationInfo info, StreamingContext context) 21 | : base(info, context) 22 | { 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Application/Exceptions/StopStreamInjectionException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Application.Exceptions 7 | { 8 | [Serializable] 9 | public class StopStreamInjectionException : Exception 10 | { 11 | public StopStreamInjectionException() 12 | : base(null) 13 | { 14 | } 15 | 16 | public StopStreamInjectionException(string message) 17 | : base(message, null) 18 | { 19 | } 20 | 21 | public StopStreamInjectionException(string message, Exception innerException) 22 | : base(message, innerException) 23 | { 24 | } 25 | 26 | protected StopStreamInjectionException(SerializationInfo info, StreamingContext context) 27 | : base(info, context) 28 | { 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IAzService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Microsoft.Azure.Management.Fluent; 4 | 5 | namespace Application.Interfaces.Common 6 | { 7 | public interface IAzService 8 | { 9 | IAzure GetAzure(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IAzStorageHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Application.Interfaces.Common 10 | { 11 | public interface IAzStorageHandler 12 | { 13 | Task AddQueueMessageAsync(string queue, object message); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IAzVirtualMachineService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Threading.Tasks; 4 | using Ardalis.Result; 5 | using Microsoft.Azure.Management.Compute.Fluent; 6 | 7 | namespace Application.Interfaces.Common 8 | { 9 | public interface IAzVirtualMachineService 10 | { 11 | Task GetAsync(string subscriptionId, string resourceGroup, string name); 12 | 13 | Task GetByIdAsync(string id); 14 | 15 | Task> StartAsync(string resourceId); 16 | 17 | Task> StopAsync(string resourceId); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IBot.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Net.Http; 4 | using System.Threading.Tasks; 5 | using Application.Common.Models; 6 | using Application.Common.Models.Api; 7 | using static Application.Service.Commands.DoInviteBot; 8 | 9 | namespace Application.Interfaces.Common 10 | { 11 | public interface IBot 12 | { 13 | string Id { get; } 14 | 15 | string VirtualMachineName { get; set; } 16 | 17 | Task InviteBotAsync(DoInviteBotCommand command); 18 | 19 | Task ProcessNotificationAsync(HttpRequestMessage request); 20 | 21 | Task EndCallAsync(string callGraphId); 22 | 23 | void StartInjection(StartStreamInjectionBody startStreamInjectionBody); 24 | 25 | void StopInjection(); 26 | 27 | void SetInjectionVolume(SetInjectionVolumeRequest injectionVolumeRequest); 28 | 29 | void DisplayInjection(); 30 | 31 | void HideInjection(); 32 | 33 | StartStreamExtractionResponse StartExtraction(StartStreamExtractionBody streamBody); 34 | 35 | void StopExtraction(StopStreamExtractionBody streamBody); 36 | 37 | Task MuteBotAsync(); 38 | 39 | Task UnmuteBotAsync(); 40 | 41 | Task RegisterServiceAsync(string virtualMachineName); 42 | 43 | Task UnregisterServiceAsync(string virtualMachineName); 44 | } 45 | } -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IBotServiceAuthenticationProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Application.Interfaces.Common 10 | { 11 | public interface IBotServiceAuthenticationProvider 12 | { 13 | Task GetTokenAsync(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IBotServiceClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Net.Http; 4 | using System.Threading.Tasks; 5 | using Application.Common.Models.Api; 6 | using Application.Service.Commands; 7 | using Application.Stream.Commands; 8 | 9 | namespace Application.Interfaces.Common 10 | { 11 | public interface IBotServiceClient 12 | { 13 | Task InviteBotAsync(DoInviteBot.DoInviteBotCommand command); 14 | 15 | Task RemoveBotAsync(string callGraphId); 16 | 17 | Task StartInjectionAsync(DoStartInjection.DoStartInjectionCommand command); 18 | 19 | Task StoptInjectionAsync(DoStopInjection.DoStopInjectionCommand command); 20 | 21 | Task HideInjectionAsync(DoHideInjection.DoHideInjectionCommand command); 22 | 23 | Task DisplayInjectionAsync(DoDisplayInjection.DoDisplayInjectionCommand command); 24 | 25 | Task StartExtractionAsync(DoStartExtraction.DoStartExtractionCommand command); 26 | 27 | Task StopExtractionAsync(DoStopExtraction.DoStopExtractionCommand command); 28 | 29 | Task MuteBotAsync(string callId); 30 | 31 | Task UnmuteBotAsync(string callId); 32 | 33 | Task SetInjectionVolumeAsync(string callId, SetInjectionVolumeRequest setInjectionVolumeRequest); 34 | 35 | void SetBaseUrl(string baseUrl); 36 | } 37 | } -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/ICloudConfigurationService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Threading.Tasks; 4 | 5 | namespace Application.Interfaces.Common 6 | { 7 | public interface ICloudConfigurationService 8 | { 9 | System.IO.Stream GetCertificate(); 10 | 11 | Task GetCertificateAsync(); 12 | 13 | System.IO.Stream GetAppSettingsAsStream(); 14 | 15 | Task GetAppSettingsAsStreamAsync(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IExtractionUrlHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Common.Models; 4 | 5 | namespace Application.Interfaces.Common 6 | { 7 | public interface IExtractionUrlHelper 8 | { 9 | string GetSrtStreamUrl(StartSrtStreamExtractionResponse startSrtStreamExtractionResponse, string serviceDns); 10 | 11 | string GetRtmpStreamUrl(StartRtmpStreamExtractionResponse startRtmpStreamExtractionResponse, string callId, string serviceDns); 12 | } 13 | } -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IGraphService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Collections.Generic; 4 | using System.Threading.Tasks; 5 | using Microsoft.Graph; 6 | 7 | namespace Application.Interfaces.Common 8 | { 9 | public interface IGraphService 10 | { 11 | Task GetCallAsync(string callId); 12 | 13 | Task> GetCallParticipantsAsync(string callId); 14 | 15 | Task> GetUserPhotoAsync(string userId); 16 | 17 | Task GetParticipantPhotoAsync(string participantAadId); 18 | 19 | Task>> GetParticipantsPhotoAsync(IList participants); 20 | 21 | Task GetOnlineMeetingAsync(string meetingId); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IHostEnvironment.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Interfaces.Common 4 | { 5 | public interface IHostEnvironment 6 | { 7 | string EnvironmentName { get; } 8 | 9 | bool IsDevelopment(); 10 | 11 | bool IsProduction(); 12 | 13 | bool IsLocal(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IInjectionUrlHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Common.Models; 4 | 5 | namespace Application.Interfaces.Common 6 | { 7 | public interface IInjectionUrlHelper 8 | { 9 | string GetStreamUrl(StartStreamInjectionBody startStreamInjectionBody, string serviceDns = null); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IMeetingUrlHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Common.Models; 4 | 5 | namespace BotService.Infrastructure.Common 6 | { 7 | public interface IMeetingUrlHelper 8 | { 9 | JoinUrlContext GetContext(); 10 | 11 | string GetMeetingId(); 12 | 13 | string GetMessageId(); 14 | 15 | string GetThreadId(); 16 | 17 | void Init(string joinUrl); 18 | } 19 | } -------------------------------------------------------------------------------- /src/Application/Interfaces/Common/IStreamKeyGeneratorHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Interfaces.Common 4 | { 5 | public interface IStreamKeyGeneratorHelper 6 | { 7 | string GetNewStreamKey(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Persistance/ICallRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Entities; 4 | 5 | namespace Application.Interfaces.Persistance 6 | { 7 | public interface ICallRepository : IRepository 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Persistance/IParticipantStreamRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Interfaces.Persistance 4 | { 5 | public interface IParticipantStreamRepository : IRepository 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Persistance/IRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Collections.Generic; 4 | using System.Threading.Tasks; 5 | using Ardalis.Specification; 6 | using Domain.Entities.Base; 7 | 8 | namespace Application.Interfaces.Persistance 9 | { 10 | public interface IRepository 11 | where T : CosmosDbEntity 12 | { 13 | Task> GetItemsAsync(ISpecification specification); 14 | 15 | Task GetItemsCountAsync(ISpecification specification); 16 | 17 | Task GetItemAsync(string id); 18 | 19 | Task GetFirstItemAsync(ISpecification specification); 20 | 21 | Task AddItemAsync(T item); 22 | 23 | Task UpdateItemAsync(string id, T item); 24 | 25 | Task DeleteItemAsync(string id); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Persistance/IServiceRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Interfaces.Persistance 4 | { 5 | public interface IServiceRepository : IRepository 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Application/Interfaces/Persistance/IStreamRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Application.Interfaces.Persistance 4 | { 5 | public interface IStreamRepository : IRepository 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Application/Participants/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Common.Models; 4 | using AutoMapper; 5 | using Domain.Entities; 6 | using Domain.Entities.Parts; 7 | using static Application.Participant.Commands.UpdateParticipantMeetingStatus; 8 | 9 | namespace Application.Participants 10 | { 11 | /// 12 | /// Mapping Profile for AutoMapper. 13 | /// 14 | public class MappingProfile : Profile 15 | { 16 | public MappingProfile() 17 | { 18 | CreateMap().ReverseMap(); 19 | 20 | CreateMap() 21 | .ForPath(dest => dest.StreamKey, opts => opts.MapFrom(src => src.Passphrase)).ReverseMap(); 22 | 23 | CreateMap(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Application/Participants/Queries/GetParticipantPhoto.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Application.Interfaces.Common; 6 | using FluentValidation; 7 | using MediatR; 8 | 9 | namespace Application.Participants.Queries 10 | { 11 | public class GetParticipantPhoto 12 | { 13 | public class GetParticipantPhotoQuery : IRequest 14 | { 15 | public string ParticipantAadId { get; set; } 16 | } 17 | 18 | public class GetParticipantPhotoQueryResponse 19 | { 20 | public System.IO.Stream Photo { get; set; } 21 | } 22 | 23 | public class GetParticipantPhotoQueryValidator : AbstractValidator 24 | { 25 | public GetParticipantPhotoQueryValidator() 26 | { 27 | RuleFor(x => x.ParticipantAadId) 28 | .NotEmpty(); 29 | } 30 | } 31 | 32 | public class GetParticipantPhotoQueryHandler : IRequestHandler 33 | { 34 | private readonly IGraphService _graphService; 35 | 36 | public GetParticipantPhotoQueryHandler(IGraphService graphService) 37 | { 38 | _graphService = graphService; 39 | } 40 | 41 | public async Task Handle(GetParticipantPhotoQuery request, CancellationToken cancellationToken) 42 | { 43 | GetParticipantPhotoQueryResponse response = new GetParticipantPhotoQueryResponse(); 44 | 45 | var photo = await _graphService.GetParticipantPhotoAsync(request.ParticipantAadId); 46 | 47 | response.Photo = photo; 48 | 49 | return response; 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Application/Participants/Specifications/ParticipantStreamGetFromCallSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | 5 | namespace Application.Participants.Specifications 6 | { 7 | public class ParticipantStreamGetFromCallSpecification : Specification 8 | { 9 | public ParticipantStreamGetFromCallSpecification(string callId, string participantId) 10 | { 11 | Query.Where(x => 12 | x.CallId == callId && x.ParticipantGraphId == participantId); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Application/Participants/Specifications/ParticipantStreamsGetFromCallSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | using Domain.Enums; 5 | using static Domain.Constants.Constants; 6 | 7 | namespace Application.Participants.Specifications 8 | { 9 | public class ParticipantStreamsGetFromCallSpecification : Specification 10 | { 11 | public ParticipantStreamsGetFromCallSpecification(string callId, ResourceType type, string participantAadId) 12 | { 13 | switch (type) 14 | { 15 | case ResourceType.Participant: 16 | Query.Where(x => x.CallId == callId && x.Type == type && x.AadId == participantAadId && x.LeftAt == null); 17 | break; 18 | case ResourceType.PrimarySpeaker: 19 | Query.Where(x => x.CallId == callId && x.Type == type && x.DisplayName == DefaultParticipantsDisplayNames.PrimarySpeaker && x.LeftAt == null); 20 | break; 21 | case ResourceType.Vbss: 22 | Query.Where(x => x.CallId == callId && x.Type == type && x.DisplayName == DefaultParticipantsDisplayNames.ScreenShare && x.LeftAt == null); 23 | break; 24 | default: 25 | break; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Application/Participants/Specifications/ParticipantsStreamsGetFromCallSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | 5 | namespace Application.Participants.Specifications 6 | { 7 | public class ParticipantsStreamsGetFromCallSpecification : Specification 8 | { 9 | public ParticipantsStreamsGetFromCallSpecification(string callId, bool archived) 10 | { 11 | if (archived) 12 | { 13 | Query.Where(x => 14 | x.CallId == callId); 15 | } 16 | else 17 | { 18 | Query.Where(x => 19 | x.CallId == callId && x.LeftAt == null); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Application/Service/Commands/DoEndCall.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Application.Interfaces.Common; 6 | using FluentValidation; 7 | using MediatR; 8 | 9 | namespace Application.Service.Commands 10 | { 11 | public class DoEndCall 12 | { 13 | public class DoEndCallCommand : IRequest 14 | { 15 | public string GraphCallId { get; set; } 16 | } 17 | 18 | public class DoEndCallCommandResponse 19 | { 20 | public string Id { get; set; } 21 | } 22 | 23 | public class DoEndCallCommandValidator : AbstractValidator 24 | { 25 | public DoEndCallCommandValidator() 26 | { 27 | RuleFor(x => x.GraphCallId) 28 | .NotEmpty(); 29 | } 30 | } 31 | 32 | public class DoEndCallCommandHandler : IRequestHandler 33 | { 34 | private readonly IBot _bot; 35 | 36 | public DoEndCallCommandHandler(IBot bot) 37 | { 38 | _bot = bot; 39 | } 40 | 41 | public async Task Handle(DoEndCallCommand request, CancellationToken cancellationToken) 42 | { 43 | DoEndCallCommandResponse response = new DoEndCallCommandResponse(); 44 | 45 | await _bot.EndCallAsync(request.GraphCallId); 46 | 47 | response.Id = request.GraphCallId; 48 | 49 | return response; 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Application/Service/Commands/DoMuteBot.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Application.Interfaces.Common; 6 | using Application.Interfaces.Persistance; 7 | using Domain.Exceptions; 8 | using MediatR; 9 | 10 | namespace Application.Service.Commands 11 | { 12 | public class DoMuteBot 13 | { 14 | public class DoMuteBotCommand : IRequest 15 | { 16 | public string CallId { get; set; } 17 | } 18 | 19 | public class DoMuteBotCommandResponse 20 | { 21 | } 22 | 23 | public class DoMuteBotCommandHandler : IRequestHandler 24 | { 25 | private readonly IBot _bot; 26 | private readonly ICallRepository _callRepository; 27 | 28 | public DoMuteBotCommandHandler( 29 | IBot bot, 30 | ICallRepository callRepository) 31 | { 32 | _bot = bot; 33 | _callRepository = callRepository; 34 | } 35 | 36 | public async Task Handle(DoMuteBotCommand request, CancellationToken cancellationToken) 37 | { 38 | var call = await _callRepository.GetItemAsync(request.CallId); 39 | 40 | if (call == null) 41 | { 42 | throw new EntityNotFoundException(nameof(Call), request.CallId); 43 | } 44 | 45 | await _bot.MuteBotAsync(); 46 | 47 | call.IsBotMuted = true; 48 | 49 | await _callRepository.UpdateItemAsync(call.Id, call); 50 | 51 | return null; 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Application/Service/Commands/DoUnmuteBot.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Application.Interfaces.Common; 6 | using Application.Interfaces.Persistance; 7 | using Domain.Exceptions; 8 | using MediatR; 9 | 10 | namespace Application.Service.Commands 11 | { 12 | public class DoUnmuteBot 13 | { 14 | public class DoUnmuteBotCommand : IRequest 15 | { 16 | public string CallId { get; set; } 17 | } 18 | 19 | public class DoUnmuteBotCommandResponse 20 | { 21 | } 22 | 23 | public class DoUnmuteBotCommandHandler : IRequestHandler 24 | { 25 | private readonly IBot _bot; 26 | private readonly ICallRepository _callRepository; 27 | 28 | public DoUnmuteBotCommandHandler( 29 | IBot bot, 30 | ICallRepository callRepository) 31 | { 32 | _bot = bot; 33 | _callRepository = callRepository; 34 | } 35 | 36 | public async Task Handle(DoUnmuteBotCommand request, CancellationToken cancellationToken) 37 | { 38 | var call = await _callRepository.GetItemAsync(request.CallId); 39 | 40 | if (call == null) 41 | { 42 | throw new EntityNotFoundException(nameof(Call), request.CallId); 43 | } 44 | 45 | await _bot.UnmuteBotAsync(); 46 | 47 | call.IsBotMuted = false; 48 | 49 | await _callRepository.UpdateItemAsync(call.Id, call); 50 | 51 | return null; 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Application/Service/Commands/ProcessNotification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Net.Http; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Application.Interfaces.Common; 7 | using MediatR; 8 | 9 | namespace Application.Service.Commands 10 | { 11 | public class ProcessNotification 12 | { 13 | public class ProcessNotificationCommand : IRequest 14 | { 15 | public HttpRequestMessage HttpRequestMessage { get; set; } 16 | } 17 | 18 | public class ProcessNotificationCommandResponse 19 | { 20 | public string Id { get; set; } 21 | } 22 | 23 | public class ProcessNotificationCommandHandler : IRequestHandler 24 | { 25 | private readonly IBot _bot; 26 | 27 | public ProcessNotificationCommandHandler(IBot bot) 28 | { 29 | _bot = bot; 30 | } 31 | 32 | public async Task Handle(ProcessNotificationCommand request, CancellationToken cancellationToken) 33 | { 34 | var response = new ProcessNotificationCommandResponse(); 35 | 36 | await _bot.ProcessNotificationAsync(request.HttpRequestMessage); 37 | 38 | return response; 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Application/Service/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Common.Models; 4 | using AutoMapper; 5 | using static Application.Service.Commands.DoStartServiceInfrastructure; 6 | using static Application.Service.Commands.DoStopServiceInfrastructure; 7 | using static Application.Service.Commands.RequestStartServiceInfrastructure; 8 | using static Application.Service.Commands.RequestStopServiceInfrastructure; 9 | 10 | namespace Application.Service 11 | { 12 | /// 13 | /// Mapping Profile for AutoMapper. 14 | /// 15 | public class MappingProfile : Profile 16 | { 17 | public MappingProfile() 18 | { 19 | CreateMap(); 20 | CreateMap(); 21 | CreateMap(); 22 | CreateMap(); 23 | CreateMap(); 24 | CreateMap(); 25 | CreateMap(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Application/Service/Specifications/ServiceGetAllSpecifications.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | 5 | namespace Application.Service.Specifications 6 | { 7 | public class ServiceGetAllSpecifications : Specification 8 | { 9 | public ServiceGetAllSpecifications() 10 | { 11 | Query.OrderByDescending(x => x.CreatedAt); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Application/Service/Specifications/ServiceGetByCallIdSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | 5 | namespace Application.Service.Specifications 6 | { 7 | public class ServiceGetByCallIdSpecification : Specification 8 | { 9 | public ServiceGetByCallIdSpecification(string callId) 10 | { 11 | Query.Where(x => 12 | x.CallId == callId); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Application/Service/Specifications/ServiceGetByInfrastructureIdSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | 5 | namespace Application.Service.Specifications 6 | { 7 | public class ServiceGetByInfrastructureIdSpecification : Specification 8 | { 9 | public ServiceGetByInfrastructureIdSpecification(string id) 10 | { 11 | Query.Where(x => x.Infrastructure.Id == id.ToLower()); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Application/Service/Specifications/ServiceGetByVirtualMachineNameSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | 5 | namespace Application.Service.Specifications 6 | { 7 | public class ServiceGetByVirtualMachineNameSpecification : Specification 8 | { 9 | public ServiceGetByVirtualMachineNameSpecification(string virtualMachineName) 10 | { 11 | Query.Where(x => 12 | x.Infrastructure.VirtualMachineName == virtualMachineName); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Application/Stream/Specifications/StreamGetActiveFromCallSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | using Domain.Enums; 5 | 6 | namespace Application.Stream.Specifications 7 | { 8 | public class StreamGetActiveFromCallSpecification : Specification 9 | { 10 | public StreamGetActiveFromCallSpecification(string callId) 11 | { 12 | Query 13 | .Where(x => x.CallId == callId && (x.State == StreamState.Starting || x.State == StreamState.Ready || x.State == StreamState.Receiving || x.State == StreamState.NotReceiving)) 14 | .OrderByDescending(x => x.StartingAt); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Application/Stream/Specifications/StreamsGetFromCallSpecification.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | 5 | namespace Application.Stream.Specifications 6 | { 7 | public class StreamsGetFromCallSpecification : Specification 8 | { 9 | public StreamsGetFromCallSpecification(string callId) 10 | { 11 | Query.Where(x => x.CallId == callId); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/BotService/Application/Core/IMediaExtractor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | using Microsoft.Skype.Bots.Media; 5 | 6 | namespace BotService.Application.Core 7 | { 8 | public interface IMediaExtractor 9 | { 10 | Protocol Protocol { get; } 11 | 12 | IVideoSocket VideoSocket { get; } 13 | 14 | void Start(MediaExtractionSettings mediaStreamSettings); 15 | 16 | void Stop(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BotService/Application/Core/IMediaHandlerFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Microsoft.Skype.Bots.Media; 4 | 5 | namespace BotService.Application.Core 6 | { 7 | public interface IMediaHandlerFactory 8 | { 9 | IMediaExtractor CreateExtractor(IVideoSocket videoSocket, IAudioSocket audioSocket); 10 | 11 | ISwitchingMediaExtractor CreateSwitchingExtractor(IVideoSocket videoSocket, IMediaSocketPool mediaSocketPool, IAudioSocket audioSocket); 12 | 13 | IMediaInjector CreateInjector(IVideoSocket videoSocket, IAudioSocket audioSocket); 14 | 15 | IMediaInjector CreateSlateInjector(IVideoSocket videoSocket); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/BotService/Application/Core/IMediaInjector.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using BotService.Infrastructure.Core; 5 | using Microsoft.Skype.Bots.Media; 6 | 7 | namespace BotService.Application.Core 8 | { 9 | public interface IMediaInjector 10 | { 11 | IVideoSocket VideoSocket { get; } 12 | 13 | bool SourceConnected { get; } 14 | 15 | void Start(MediaInjectionSettings injectionSettings); 16 | 17 | void Stop(); 18 | 19 | void SetVolume(StreamVolume streamVolume); 20 | 21 | void SwitchContentStatus(bool shouldInject); 22 | 23 | void SetOnStreamStateChanged(Action onStreamStateChanged); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/BotService/Application/Core/IMediaSocketPool.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Microsoft.Skype.Bots.Media; 4 | 5 | namespace BotService.Application.Core 6 | { 7 | public interface IMediaSocketPool 8 | { 9 | IAudioSocket MainAudioSocket { get; } 10 | 11 | IVideoSocket InjectionSocket { get; } 12 | 13 | IVideoSocket GetScreenShareSocket(); 14 | 15 | IVideoSocket GetParticipantVideoSocket(); 16 | 17 | void ReleaseSocket(IVideoSocket socket); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/BotService/Application/Core/ISwitchingMediaExtractor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace BotService.Application.Core 4 | { 5 | public interface ISwitchingMediaExtractor : IMediaExtractor 6 | { 7 | void SwitchMediaSourceSafely(uint mediaSourceId); 8 | 9 | void SwitchMediaSourceForcefully(uint mediaSourceId); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/BotService/Application/Core/MediaExtractionSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Microsoft.Skype.Bots.Media; 4 | 5 | namespace BotService.Application.Core 6 | { 7 | public class MediaExtractionSettings 8 | { 9 | public MediaType MediaType { get; set; } 10 | 11 | public uint MediaSourceId { get; set; } 12 | 13 | public VideoResolution VideoResolution { get; set; } 14 | 15 | public ProtocolSettings ProtocolSettings { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/BotService/Application/Core/MediaInjectionSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using BotService.Infrastructure.Core; 4 | 5 | namespace BotService.Application.Core 6 | { 7 | public class MediaInjectionSettings 8 | { 9 | public string CallId { get; set; } 10 | 11 | public string StreamId { get; set; } 12 | 13 | public StreamVolume StreamVolume { get; set; } 14 | 15 | public ProtocolSettings ProtocolSettings { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/BotService/Application/Core/ProtocolSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace BotService.Application.Core 6 | { 7 | public abstract class ProtocolSettings 8 | { 9 | public Protocol Type { get; set; } 10 | 11 | public bool TimeOverlay { get; set; } = true; 12 | 13 | public SupportedAudioFormat AudioFormat { get; set; } = SupportedAudioFormat.AAC_44100; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/BotService/Configuration/AppConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Common.Config; 4 | 5 | namespace BotService.Configuration 6 | { 7 | public class AppConfiguration : IAppConfiguration 8 | { 9 | public string BuildVersion { get; set; } 10 | 11 | public string KeyVaultName { get; set; } 12 | 13 | public string KeyVaultEnv { get; set; } 14 | 15 | public GraphClientConfiguration GraphClientConfiguration { get; set; } = new GraphClientConfiguration(); 16 | 17 | public AzStorageConfiguration StorageConfiguration { get; set; } = new AzStorageConfiguration(); 18 | 19 | public CosmosDbConfiguration CosmosDbConfiguration { get; set; } = new CosmosDbConfiguration(); 20 | 21 | public BotConfiguration BotConfiguration { get; set; } = new BotConfiguration(); 22 | 23 | public AzServicePrincipalConfiguration AzServicePrincipalConfiguration { get; set; } = new AzServicePrincipalConfiguration(); 24 | 25 | public AzureAdConfiguration AzureAdConfiguration { get; set; } = new AzureAdConfiguration(); 26 | 27 | public BotServiceAuthenticationConfiguration BotServiceAuthenticationConfiguration { get; set; } = new BotServiceAuthenticationConfiguration(); 28 | } 29 | } -------------------------------------------------------------------------------- /src/BotService/Configuration/EndpointConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace BotService.Configuration 4 | { 5 | public class EndpointConfiguration 6 | { 7 | public string Host { get; set; } 8 | 9 | public int? Port { get; set; } 10 | 11 | public string Scheme { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Client/IGraphCommunicationsClientBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Microsoft.Graph.Communications.Client; 4 | 5 | namespace BotService.Infrastructure.Client 6 | { 7 | public interface IGraphCommunicationsClientBuilder 8 | { 9 | ICommunicationsClient Build(string name = null); 10 | } 11 | } -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Common/CloudRoleNameTelemetryInitializer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Microsoft.ApplicationInsights.Channel; 4 | using Microsoft.ApplicationInsights.Extensibility; 5 | 6 | namespace BotService.Infrastructure.Common 7 | { 8 | public class CloudRoleNameTelemetryInitializer : ITelemetryInitializer 9 | { 10 | public void Initialize(ITelemetry telemetry) 11 | { 12 | // set custom role name here 13 | telemetry.Context.Cloud.RoleName = "bot-service"; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Common/EnvironmentPrefixSecretManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Azure.Extensions.AspNetCore.Configuration.Secrets; 4 | using Azure.Security.KeyVault.Secrets; 5 | using Microsoft.Extensions.Configuration; 6 | 7 | namespace BotService.Infrastructure.Common 8 | { 9 | public class EnvironmentPrefixSecretManager : KeyVaultSecretManager 10 | { 11 | private readonly string _prefix; 12 | 13 | public EnvironmentPrefixSecretManager(string prefix) 14 | => _prefix = $"{prefix}-"; 15 | 16 | public override bool Load(SecretProperties properties) 17 | => properties.Name.StartsWith(_prefix); 18 | 19 | public override string GetKey(KeyVaultSecret secret) 20 | { 21 | var secretName = secret.Name.Remove(0, _prefix.Length).Replace("--", ConfigurationPath.KeyDelimiter); 22 | return secretName; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Common/JoinInfoHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Infrastructure.Core.Common; 4 | using Microsoft.Graph; 5 | 6 | namespace BotService.Infrastructure.Common 7 | { 8 | /// 9 | /// Gets the join information. 10 | /// 11 | public static class JoinInfoHelper 12 | { 13 | /// 14 | /// Parse Join URL into its components. 15 | /// 16 | /// Join URL from Team's meeting body. 17 | /// Parsed data. 18 | public static (ChatInfo, MeetingInfo) ParseJoinURL(string joinUrl) 19 | { 20 | var meetingUrlHelper = new MeetingUrlHelper(); 21 | meetingUrlHelper.Init(joinUrl); 22 | 23 | var context = meetingUrlHelper.GetContext(); 24 | var thread = meetingUrlHelper.GetThreadId(); 25 | var message = meetingUrlHelper.GetMessageId(); 26 | 27 | var chatInfo = new ChatInfo 28 | { 29 | ThreadId = thread, 30 | MessageId = message, 31 | ReplyChainMessageId = context.MessageId, 32 | }; 33 | 34 | var meetingInfo = new OrganizerMeetingInfo 35 | { 36 | Organizer = new IdentitySet 37 | { 38 | User = new Identity { Id = context.Oid }, 39 | }, 40 | }; 41 | 42 | meetingInfo.Organizer.User.SetTenantId(context.Tid); 43 | 44 | return (chatInfo, meetingInfo); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Common/Logging/PipelineBusObserverUnsuscriber.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | 5 | namespace BotService.Infrastructure.Common.Logging 6 | { 7 | public class PipelineBusObserverUnsuscriber : IDisposable 8 | { 9 | private IObserver _observer; 10 | 11 | public PipelineBusObserverUnsuscriber(IObserver observer) 12 | { 13 | _observer = observer; 14 | } 15 | 16 | public void Dispose() 17 | { 18 | Dispose(true); 19 | GC.SuppressFinalize(this); 20 | } 21 | 22 | protected virtual void Dispose(bool disposing) 23 | { 24 | if (disposing) 25 | { 26 | _observer = null; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Core/RtmpSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using BotService.Application.Core; 4 | using Domain.Enums; 5 | 6 | namespace BotService.Infrastructure.Core 7 | { 8 | public class RtmpSettings : ProtocolSettings 9 | { 10 | public RtmpSettings() 11 | { 12 | Type = Protocol.RTMP; 13 | } 14 | 15 | public RtmpMode Mode { get; set; } 16 | 17 | public int Port { get; set; } 18 | 19 | public string StreamUrl { get; set; } 20 | 21 | public string StreamKey { get; set; } 22 | 23 | public bool EnableSsl { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Core/SrtSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using BotService.Application.Core; 4 | using Domain.Enums; 5 | 6 | namespace BotService.Infrastructure.Core 7 | { 8 | public class SrtSettings : ProtocolSettings 9 | { 10 | public SrtSettings() 11 | { 12 | Type = Protocol.SRT; 13 | } 14 | 15 | public string Url { get; set; } 16 | 17 | public int Port { get; set; } 18 | 19 | public string Passphrase { get; set; } 20 | 21 | public KeyLengthValues KeyLength { get; set; } 22 | 23 | public int Latency { get; set; } 24 | 25 | public SrtMode Mode { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Core/StreamVolume.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace BotService.Infrastructure.Core 6 | { 7 | public class StreamVolume 8 | { 9 | public StreamVolumeFormat Format { get; set; } 10 | 11 | public double Value { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Extensions/BotConfigurationExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Net; 4 | using Application.Common.Config; 5 | using Microsoft.Skype.Bots.Media; 6 | 7 | namespace BotService.Infrastructure.Extensions 8 | { 9 | public static class BotConfigurationExtensions 10 | { 11 | public static MediaPlatformSettings GetMediaPlatformSettings(this BotConfiguration configuration) 12 | { 13 | int mediaInstanceInternalPort = configuration.InstanceInternalPort; 14 | int mediaInstancePublicPort = configuration.InstancePublicPort; 15 | 16 | IPAddress publicInstanceIpAddress = configuration.InstancePublicIPAddress; 17 | string serviceFqdn = configuration.ServiceFqdn; 18 | 19 | var mediaPlatformSettings = new MediaPlatformSettings() 20 | { 21 | MediaPlatformInstanceSettings = new MediaPlatformInstanceSettings() 22 | { 23 | CertificateThumbprint = configuration.CertificateThumbprint, 24 | InstanceInternalPort = mediaInstanceInternalPort, 25 | InstancePublicIPAddress = publicInstanceIpAddress, 26 | InstancePublicPort = mediaInstancePublicPort, 27 | ServiceFqdn = serviceFqdn, 28 | }, 29 | 30 | ApplicationId = configuration.AadAppId, 31 | }; 32 | 33 | return mediaPlatformSettings; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Extensions/LoggerConfigurationHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Microsoft.ApplicationInsights.Extensibility; 4 | using Microsoft.Extensions.Configuration; 5 | using Serilog; 6 | using Serilog.Events; 7 | 8 | namespace BotService.Infrastructure.Extensions 9 | { 10 | public static class LoggerConfigurationHelper 11 | { 12 | private const string AppInsightsInstrumentationKey = "APPINSIGHTS_INSTRUMENTATIONKEY"; 13 | 14 | public static ILogger GetLogger(IConfigurationRoot configuration) 15 | { 16 | var appInsightsKey = configuration[AppInsightsInstrumentationKey]; 17 | 18 | var defaultLoggerConfiguration = new LoggerConfiguration() 19 | .MinimumLevel.Override("Microsoft", LogEventLevel.Information) 20 | .Enrich.FromLogContext() 21 | .WriteTo.Console(); 22 | 23 | if (!string.IsNullOrEmpty(appInsightsKey)) 24 | { 25 | var telemetryConfiguration = TelemetryConfiguration 26 | .CreateDefault(); 27 | telemetryConfiguration.InstrumentationKey = appInsightsKey; 28 | defaultLoggerConfiguration.WriteTo.ApplicationInsights(telemetryConfiguration, TelemetryConverter.Traces); 29 | } 30 | 31 | var logger = defaultLoggerConfiguration.CreateLogger(); 32 | return logger; 33 | } 34 | 35 | public static ILogger GetConsoleLogger() 36 | { 37 | var logger = new LoggerConfiguration() 38 | .MinimumLevel.Override("Microsoft", LogEventLevel.Information) 39 | .Enrich.FromLogContext() 40 | .WriteTo.Console() 41 | .CreateLogger(); 42 | 43 | return logger; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Extensions/StreamVolumeExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Domain.Enums; 5 | using Gst.Audio; 6 | 7 | namespace BotService.Infrastructure.Extensions 8 | { 9 | public static class StreamVolumeExtensions 10 | { 11 | public static Gst.Audio.StreamVolumeFormat ToStreamVolumeFormat(this Domain.Enums.StreamVolumeFormat streamVolumeType) 12 | { 13 | var streamVoumeFormat = (Gst.Audio.StreamVolumeFormat)Enum.ToObject(typeof(Gst.Audio.StreamVolumeFormat), streamVolumeType); 14 | 15 | return streamVoumeFormat; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Extensions/SupportedAudioExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Domain.Enums; 5 | 6 | namespace BotService.Infrastructure.Extensions 7 | { 8 | public static class SupportedAudioExtensions 9 | { 10 | public static int ToAudioRate(this SupportedAudioFormat supportedAudio) 11 | { 12 | switch (supportedAudio) 13 | { 14 | case SupportedAudioFormat.AAC_44100: 15 | return 44100; 16 | case SupportedAudioFormat.AAC_48000: 17 | return 48000; 18 | default: 19 | throw new ArgumentOutOfRangeException(nameof(supportedAudio), "Unsupported audio"); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Pipelines/GstreamerClockProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace BotService.Infrastructure.Pipelines 4 | { 5 | public class GstreamerClockProvider 6 | { 7 | private ulong _baseTime; 8 | 9 | public GstreamerClockProvider() 10 | { 11 | Clock = new GstreamerCustomClock(); 12 | } 13 | 14 | public ulong BaseTime => GetBaseTime(); 15 | 16 | public GstreamerCustomClock Clock { get; } 17 | 18 | public void ResetBaseTime() 19 | { 20 | _baseTime = 0; 21 | } 22 | 23 | private ulong GetBaseTime() 24 | { 25 | if (_baseTime == 0) 26 | { 27 | _baseTime = (ulong)((System.DateTime.UtcNow - new System.DateTime(1900, 1, 1)).Ticks * 100); 28 | } 29 | 30 | return _baseTime; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Pipelines/GstreamerCustomClock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Gst; 4 | 5 | namespace BotService.Infrastructure.Pipelines 6 | { 7 | public class GstreamerCustomClock : SystemClock 8 | { 9 | private readonly ulong _baseTimestamp; 10 | 11 | public GstreamerCustomClock() 12 | { 13 | // Initial clock time, the system clock does not start from zero 14 | var initialTime = Time; 15 | 16 | // Calculate the current time sourced from 1900-01-01 00:00:00.0 17 | var currentTime = (ulong)((System.DateTime.UtcNow - new System.DateTime(1900, 1, 1)).Ticks * 100); 18 | _baseTimestamp = currentTime - initialTime; 19 | } 20 | 21 | protected override ulong OnGetInternalTime() 22 | { 23 | // It returns current time sourced from 1900-01-01 00:00:00.0 24 | return _baseTimestamp + base.OnGetInternalTime(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Pipelines/GstreamerMediaProcessorFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using BotService.Application.Core; 4 | using Microsoft.Extensions.Logging; 5 | 6 | namespace BotService.Infrastructure.Pipelines 7 | { 8 | public class GStreamerMediaProcessorFactory : IMediaProcessorFactory 9 | { 10 | private readonly ILoggerFactory _loggerFactory; 11 | private readonly GstreamerClockProvider _clockProvider; 12 | 13 | public GStreamerMediaProcessorFactory( 14 | ILoggerFactory loggerFactory, 15 | GstreamerClockProvider clockProvider) 16 | { 17 | _loggerFactory = loggerFactory; 18 | _clockProvider = clockProvider; 19 | } 20 | 21 | public IMediaProcessor CreateMediaProcessor(ProtocolSettings protocolSettings) 22 | { 23 | return new GstreamerMediaProcessor(protocolSettings, _loggerFactory, _clockProvider); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Pipelines/IMediaExtractionPipeline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Gst; 4 | 5 | namespace BotService.Infrastructure.Pipelines 6 | { 7 | public interface IMediaExtractionPipeline 8 | { 9 | Bus Bus { get; set; } 10 | 11 | StateChangeReturn Play(); 12 | 13 | StateChangeReturn Stop(); 14 | 15 | void PushAudioBuffer(byte[] buffer, long timestamp); 16 | 17 | void PushVideoBuffer(byte[] buffer, long timestamp, int width, int height); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Pipelines/IMediaInjectionPipeline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using BotService.Infrastructure.Common.Logging; 5 | using BotService.Infrastructure.Core; 6 | using Gst; 7 | using Gst.App; 8 | 9 | namespace BotService.Infrastructure.Pipelines 10 | { 11 | public interface IMediaInjectionPipeline 12 | { 13 | (State State, State NextState) GetState(); 14 | 15 | void Play(); 16 | 17 | void RemoveBufferReceivedHandler(Action onBufferReceived); 18 | 19 | void RemoveNewAudioSampleHandler(NewSampleHandler newAudioSampleHandler); 20 | 21 | void RemoveNewVideoSampleHandler(NewSampleHandler newVideoSampleHandler); 22 | 23 | void SetBufferReceivedHandler(Action onBufferReceived); 24 | 25 | void SetNewAudioSampleHandler(NewSampleHandler newAudioSampleHandler); 26 | 27 | void SetNewVideoSampleHandler(NewSampleHandler newVideoSampleHandler); 28 | 29 | void Stop(); 30 | 31 | void SetVolume(StreamVolume streamVolume); 32 | 33 | IDisposable Subscribe(IObserver observer); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Pipelines/IMediaProcessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using BotService.Infrastructure.Core; 5 | using Microsoft.Skype.Bots.Media; 6 | 7 | namespace BotService.Infrastructure.Pipelines 8 | { 9 | public interface IMediaProcessor : IDisposable 10 | { 11 | void Play(); 12 | 13 | void Stop(); 14 | 15 | void PushAudioBuffer(byte[] buffer, AudioFormat audioFormat, long timestamp, int rate); 16 | 17 | void PushVideoBuffer(byte[] buffer, VideoColorFormat videoFormat, long timestamp, int width, int height); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Pipelines/IMediaProcessorFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using BotService.Application.Core; 4 | 5 | namespace BotService.Infrastructure.Pipelines 6 | { 7 | public interface IMediaProcessorFactory 8 | { 9 | IMediaProcessor CreateMediaProcessor(ProtocolSettings protocolSettings); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/BotService/Infrastructure/Services/IMediatorService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Threading.Tasks; 4 | using Application.Call.Commands; 5 | using Application.Participant.Commands; 6 | using Application.Service.Commands; 7 | using Application.Stream.Commands; 8 | using Domain.Enums; 9 | using Microsoft.Graph.Communications.Calls; 10 | 11 | namespace BotService.Infrastructure.Services 12 | { 13 | public interface IMediatorService 14 | { 15 | Task AddParticipantStreamAsync(string callId, IParticipant participant); 16 | 17 | Task HandleParticipantLeaveAsync(string callId, string participantId); 18 | 19 | Task RegisterServiceAsync(string virtualMachineName); 20 | 21 | Task UnregisterServiceAsync(string virtualMachineName); 22 | 23 | Task SetBotServiceAsAvailableAsync(string callId); 24 | 25 | Task SetCallAsEstablishedAsync(string callId, string graphCallId); 26 | 27 | Task SetCallAsTerminatedAsync(string callId); 28 | 29 | Task UpdateParticipantMeetingStatusAsync(string callId, IParticipant participant); 30 | 31 | Task UpdateStreamStateAsync(string callId, StreamState state); 32 | 33 | Task UpdateBotStatusAsync(string callId, bool isMuted); 34 | } 35 | } -------------------------------------------------------------------------------- /src/BotService/Infrastructure/WindowsService/WindowsServiceState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace BotService.Infrastructure.Extensions 4 | { 5 | public enum WindowsServiceState 6 | { 7 | SERVICE_STOPPED = 0x00000001, 8 | SERVICE_START_PENDING = 0x00000002, 9 | SERVICE_STOP_PENDING = 0x00000003, 10 | SERVICE_RUNNING = 0x00000004, 11 | SERVICE_CONTINUE_PENDING = 0x00000005, 12 | SERVICE_PAUSE_PENDING = 0x00000006, 13 | SERVICE_PAUSED = 0x00000007, 14 | } 15 | } -------------------------------------------------------------------------------- /src/BotService/Infrastructure/WindowsService/WindowsServiceStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Runtime.InteropServices; 4 | 5 | #pragma warning disable SA1307 // We cannot change the name of the struct fields to match our naming conventions 6 | namespace BotService.Infrastructure.Extensions 7 | { 8 | [StructLayout(LayoutKind.Sequential)] 9 | public struct WindowsServiceStatus 10 | { 11 | public int dwServiceType; 12 | public WindowsServiceState dwCurrentState; 13 | public int dwControlsAccepted; 14 | public int dwWin32ExitCode; 15 | public int dwServiceSpecificExitCode; 16 | public int dwCheckPoint; 17 | public int dwWaitHint; 18 | } 19 | } 20 | #pragma warning restore SA1307 -------------------------------------------------------------------------------- /src/BotService/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/BotService/appSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /src/BotService/slate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Broadcast-Development-Kit/a7880443df6134e45dde95a4a3511979effd5705/src/BotService/slate.png -------------------------------------------------------------------------------- /src/Domain/Domain.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | netstandard2.0 7 | Copyright (c) Microsoft Corporation. 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | all 22 | runtime; build; native; contentfiles; analyzers; buildtransitive 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/Domain/Entities/Base/CosmosDbEntity.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Newtonsoft.Json; 4 | 5 | namespace Domain.Entities.Base 6 | { 7 | public abstract class CosmosDbEntity 8 | { 9 | [JsonProperty(PropertyName = "id")] 10 | public string Id { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Domain/Entities/Call.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Collections.Generic; 5 | using Domain.Entities.Base; 6 | using Domain.Enums; 7 | 8 | namespace Domain.Entities 9 | { 10 | public class Call : CosmosDbEntity 11 | { 12 | public string MeetingUrl { get; set; } 13 | 14 | public string MeetingId { get; set; } 15 | 16 | public CallState State { get; set; } 17 | 18 | public DateTime CreatedAt { get; set; } 19 | 20 | public DateTime StartedAt { get; set; } 21 | 22 | public DateTime EndedAt { get; set; } 23 | 24 | public MeetingType MeetingType { get; set; } 25 | 26 | public string BotFqdn { get; set; } 27 | 28 | public string BotIp { get; set; } 29 | 30 | public string DefaultPassphrase { get; set; } 31 | 32 | public int DefaultLatency { get; set; } 33 | 34 | public string GraphId { get; set; } 35 | 36 | public string ServiceId { get; set; } 37 | 38 | public bool IsBotMuted { get; set; } 39 | 40 | public Dictionary PublicContext { get; set; } = new Dictionary(); 41 | 42 | public Dictionary PrivateContext { get; set; } = new Dictionary(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Domain/Entities/ParticipantStream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Domain.Entities.Base; 5 | using Domain.Entities.Parts; 6 | using Domain.Enums; 7 | 8 | namespace Domain.Entities 9 | { 10 | public class ParticipantStream : CosmosDbEntity 11 | { 12 | public string AadId { get; set; } 13 | 14 | public string CallId { get; set; } 15 | 16 | public string ParticipantGraphId { get; set; } 17 | 18 | public string DisplayName { get; set; } 19 | 20 | public string PhotoUrl { get; set; } 21 | 22 | public ResourceType Type { get; set; } 23 | 24 | public StreamState State { get; set; } 25 | 26 | public bool IsHealthy { get; set; } 27 | 28 | public string HealthMessage { get; set; } 29 | 30 | public bool AudioMuted { get; set; } 31 | 32 | public bool IsSharingAudio { get; set; } 33 | 34 | public bool IsSharingVideo { get; set; } 35 | 36 | public bool IsSharingScreen { get; set; } 37 | 38 | public ParticipantStreamDetails Details { get; set; } = new ParticipantStreamDetails(); 39 | 40 | public DateTime CreatedAt { get; set; } 41 | 42 | public DateTime? LeftAt { get; set; } 43 | 44 | public StreamErrorDetails Error { get; set; } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Domain/Entities/Parts/Infrastructure.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Entities.Parts 4 | { 5 | public class Infrastructure 6 | { 7 | public string VirtualMachineName { get; set; } 8 | 9 | public string ResourceGroup { get; set; } 10 | 11 | public string SubscriptionId { get; set; } 12 | 13 | public string Id { get; set; } 14 | 15 | public string PowerState { get; set; } 16 | 17 | public string IpAddress { get; set; } 18 | 19 | public string Dns { get; set; } 20 | 21 | public ProvisioningDetails ProvisioningDetails { get; set; } = new ProvisioningDetails(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Domain/Entities/Parts/ParticipantStreamDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Domain.Entities.Parts 6 | { 7 | public class ParticipantStreamDetails 8 | { 9 | public string StreamUrl { get; set; } 10 | 11 | public bool AudioDemuxed { get; set; } 12 | 13 | public string StreamKey { get; set; } 14 | 15 | public KeyLengthValues KeyLength { get; set; } 16 | 17 | public int Latency { get; set; } 18 | 19 | public string PreviewUrl { get; set; } 20 | 21 | public SupportedAudioFormat AudioFormat { get; set; } 22 | 23 | public bool TimeOverlay { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Domain/Entities/Parts/ParticipantStreamErrorDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Domain.Entities.Parts 6 | { 7 | public class ParticipantStreamErrorDetails 8 | { 9 | public ParticipantStreamErrorDetails() 10 | { 11 | } 12 | 13 | public ParticipantStreamErrorDetails(ParticipantStreamErrorType type) 14 | { 15 | Type = type; 16 | Message = GetDefaultMessage(); 17 | } 18 | 19 | public ParticipantStreamErrorDetails(ParticipantStreamErrorType type, string message) 20 | { 21 | Type = type; 22 | Message = message; 23 | } 24 | 25 | public ParticipantStreamErrorType Type { get; set; } 26 | 27 | public string Message { get; set; } 28 | 29 | private string GetDefaultMessage() 30 | { 31 | var message = $"Error while trying to {Type}"; 32 | return message; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Domain/Entities/Parts/ProvisioningDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Domain.Entities.Parts 6 | { 7 | public class ProvisioningDetails 8 | { 9 | public string Message { get; set; } 10 | 11 | public ProvisioningStateType State { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Domain/Entities/Parts/StreamDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Domain.Entities.Parts 6 | { 7 | public class StreamDetails 8 | { 9 | public string StreamUrl { get; set; } 10 | 11 | public string StreamKey { get; set; } 12 | 13 | public KeyLengthValues KeyLength { get; set; } 14 | 15 | public int Latency { get; set; } 16 | 17 | public string PreviewUrl { get; set; } 18 | 19 | public Protocol Protocol { get; set; } 20 | 21 | public dynamic Mode { get; set; } 22 | 23 | public bool EnableSsl { get; set; } 24 | 25 | public StreamVolume StreamVolume { get; set; } 26 | 27 | public bool VideoFeedOn { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Domain/Entities/Parts/StreamErrorDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Domain.Entities.Parts 6 | { 7 | public class StreamErrorDetails 8 | { 9 | public StreamErrorDetails() 10 | { 11 | } 12 | 13 | public StreamErrorDetails(StreamErrorType type) 14 | { 15 | Type = type; 16 | Message = GetDefaultMessage(); 17 | } 18 | 19 | public StreamErrorDetails(StreamErrorType type, string message) 20 | { 21 | Type = type; 22 | Message = message; 23 | } 24 | 25 | public StreamErrorType Type { get; set; } 26 | 27 | public string Message { get; set; } 28 | 29 | private string GetDefaultMessage() 30 | { 31 | var message = $"Error while trying to {Type}"; 32 | return message; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Domain/Entities/Parts/StreamVolume.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Domain.Enums; 4 | 5 | namespace Domain.Entities.Parts 6 | { 7 | public class StreamVolume 8 | { 9 | public StreamVolumeFormat Format { get; set; } 10 | 11 | public double Value { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Domain/Entities/Service.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Domain.Entities.Base; 5 | using Domain.Entities.Parts; 6 | using Domain.Enums; 7 | 8 | namespace Domain.Entities 9 | { 10 | public class Service : CosmosDbEntity 11 | { 12 | public string CallId { get; set; } 13 | 14 | public string Name { get; set; } 15 | 16 | public ServiceState State { get; set; } 17 | 18 | public DateTime CreatedAt { get; set; } 19 | 20 | public Infrastructure Infrastructure { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Domain/Entities/Stream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Domain.Entities.Base; 5 | using Domain.Entities.Parts; 6 | using Domain.Enums; 7 | 8 | namespace Domain.Entities 9 | { 10 | public class Stream : CosmosDbEntity 11 | { 12 | public string CallId { get; set; } 13 | 14 | public StreamState State { get; set; } 15 | 16 | public DateTime StartingAt { get; set; } 17 | 18 | public DateTime StartedAt { get; set; } 19 | 20 | public DateTime EndingAt { get; set; } 21 | 22 | public DateTime EndedAt { get; set; } 23 | 24 | public StreamDetails Details { get; set; } = new StreamDetails(); 25 | 26 | public StreamErrorDetails Error { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Domain/Enums/BusMessageType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum BusMessageType 6 | { 7 | Unknown, 8 | Error, 9 | StateChanged, 10 | StreamStatus, 11 | Buffering, 12 | Qos, 13 | Eos, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Domain/Enums/CallState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum CallState 6 | { 7 | Establishing, 8 | Established, 9 | Terminating, 10 | Terminated, 11 | Error, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Domain/Enums/ContextPrivacy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum ContextPrivacy 6 | { 7 | Public = 1, 8 | Private = 2, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Domain/Enums/KeyLengthValues.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum KeyLengthValues 6 | { 7 | None = 0, 8 | SixteenBytes = 16, 9 | TwentyFourBytes = 24, 10 | ThirtyTwoBytes = 32, 11 | } 12 | } -------------------------------------------------------------------------------- /src/Domain/Enums/MeetingType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum MeetingType 6 | { 7 | Default, 8 | LiveEvent, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Domain/Enums/ParticipantStreamErrorType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum ParticipantStreamErrorType 6 | { 7 | StartExtraction, 8 | StopExtraction, 9 | Unknown, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Domain/Enums/Protocol.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum Protocol 6 | { 7 | SRT = 0, 8 | RTMP = 1, 9 | } 10 | } -------------------------------------------------------------------------------- /src/Domain/Enums/ProvisioningStateType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | /// 6 | /// An enumeration to encapsulate Enums in the solution. 7 | /// 8 | /// 9 | /// ProvisioningStateType type class should have a protected constructor to encapsulate known enum types 10 | /// this is currently not possible as Cosmos DB uses this constructor to map the document into the corresponding type. 11 | /// 12 | public class ProvisioningStateType : Enumeration 13 | { 14 | public static readonly ProvisioningStateType Provisioning = new ProvisioningStateType(0, nameof(Provisioning)); 15 | public static readonly ProvisioningStateType Provisioned = new ProvisioningStateType(1, nameof(Provisioned)); 16 | public static readonly ProvisioningStateType Deprovisioning = new ProvisioningStateType(2, nameof(Deprovisioning)); 17 | public static readonly ProvisioningStateType Deprovisioned = new ProvisioningStateType(3, nameof(Deprovisioned)); 18 | public static readonly ProvisioningStateType Error = new ProvisioningStateType(4, nameof(Error)); 19 | public static readonly ProvisioningStateType Unknown = new ProvisioningStateType(5, nameof(Unknown)); 20 | 21 | public ProvisioningStateType() 22 | { 23 | } 24 | 25 | public ProvisioningStateType(int id, string name) 26 | : base(id, name) 27 | { 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Domain/Enums/ResourceType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum ResourceType 6 | { 7 | Participant = 2, 8 | PrimarySpeaker = 1, 9 | Vbss = 0, 10 | TogetherMode = 3, 11 | LargeGallery = 4, 12 | LiveEvent = 5, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Domain/Enums/RtmpMode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum RtmpMode 6 | { 7 | Pull = 1, 8 | Push = 2, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Domain/Enums/ServiceState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum ServiceState 6 | { 7 | Unavailable = 0, 8 | Available = 1, 9 | Busy = 2, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Domain/Enums/SrtMode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum SrtMode 6 | { 7 | Caller = 1, 8 | Listener = 2, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Domain/Enums/StreamErrorType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum StreamErrorType 6 | { 7 | StartExtraction, 8 | StopExtraction, 9 | StartInjection, 10 | StopInjection, 11 | Unknown, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Domain/Enums/StreamState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum StreamState 6 | { 7 | Disconnected, 8 | Starting, 9 | Ready, 10 | Receiving, 11 | NotReceiving, 12 | Stopping, 13 | StartingError, 14 | StoppingError, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Domain/Enums/StreamVolumeFormat.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | namespace Domain.Enums 4 | { 5 | public enum StreamVolumeFormat 6 | { 7 | Linear = 0, 8 | Cubic = 1, 9 | Db = 2, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Domain/Enums/SupportedAudioFormat.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | 5 | namespace Domain.Enums 6 | { 7 | public enum SupportedAudioFormat 8 | { 9 | AAC_44100 = 0, 10 | AAC_48000 = 1, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Domain/Exceptions/EntityNotFoundException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Domain.Exceptions 7 | { 8 | [Serializable] 9 | public class EntityNotFoundException : Exception 10 | { 11 | public EntityNotFoundException() 12 | { 13 | } 14 | 15 | public EntityNotFoundException(string message) 16 | : base(message) 17 | { 18 | } 19 | 20 | public EntityNotFoundException(string message, Exception innerException) 21 | : base(message, innerException) 22 | { 23 | } 24 | 25 | public EntityNotFoundException(string name, string id) 26 | : base($"The entity {name} with key \"{id}\" was not found.") 27 | { 28 | } 29 | 30 | protected EntityNotFoundException(SerializationInfo info, StreamingContext context) 31 | : base(info, context) 32 | { 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/Common/Extensions/StreamExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.IO; 4 | 5 | namespace Infrastructure.Core.Common.Extensions 6 | { 7 | public static class StreamExtensions 8 | { 9 | public static byte[] ToByteArray(this Stream stream) 10 | { 11 | using (MemoryStream ms = new MemoryStream()) 12 | { 13 | stream.CopyTo(ms); 14 | return ms.ToArray(); 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/Common/ExtractionUrlHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Application.Common.Models; 5 | using Application.Interfaces.Common; 6 | using Domain.Constants; 7 | using Domain.Enums; 8 | 9 | namespace Infrastructure.Core.Common 10 | { 11 | public class ExtractionUrlHelper : IExtractionUrlHelper 12 | { 13 | public string GetSrtStreamUrl(StartSrtStreamExtractionResponse startSrtStreamExtractionResponse, string serviceDns) 14 | { 15 | var streamUrl = startSrtStreamExtractionResponse.Url; 16 | 17 | if (startSrtStreamExtractionResponse.Mode == SrtMode.Listener) 18 | { 19 | var template = Constants.MediaExtractionUrl.Srt.Listener.Client; 20 | 21 | streamUrl = string.Format(template, serviceDns, startSrtStreamExtractionResponse.Port); 22 | } 23 | 24 | return streamUrl; 25 | } 26 | 27 | public string GetRtmpStreamUrl(StartRtmpStreamExtractionResponse startRtmpStreamExtractionResponse, string callId, string serviceDns) 28 | { 29 | var streamUrl = startRtmpStreamExtractionResponse.StreamUrl; 30 | if (startRtmpStreamExtractionResponse.Mode == RtmpMode.Pull) 31 | { 32 | var template = startRtmpStreamExtractionResponse.EnableSsl ? Constants.MediaExtractionUrl.Rtmps.Pull.Client : Constants.MediaExtractionUrl.Rtmp.Pull.Client; 33 | 34 | streamUrl = string.Format(template, serviceDns, startRtmpStreamExtractionResponse.Port, startRtmpStreamExtractionResponse.StreamKey, callId); 35 | } 36 | 37 | return streamUrl; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/Common/HostEnvironment.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Application.Interfaces.Common; 5 | 6 | namespace Infrastructure.Core.Common 7 | { 8 | public class HostEnvironment : IHostEnvironment 9 | { 10 | private const string Development = "development"; 11 | private const string Production = "production"; 12 | private const string Local = "local"; 13 | private const string AspNetCoreEnvironmentVariableKey = "ASPNETCORE_ENVIRONMENT"; 14 | private const string AzureFunctionEnvironmentVariableKey = "AZURE_FUNCTIONS_ENVIRONMENT"; 15 | 16 | public HostEnvironment(bool isAzureFunction = false) 17 | { 18 | var environment = isAzureFunction ? 19 | Environment.GetEnvironmentVariable(AzureFunctionEnvironmentVariableKey) : 20 | Environment.GetEnvironmentVariable(AspNetCoreEnvironmentVariableKey); 21 | 22 | if (!string.IsNullOrEmpty(environment)) 23 | { 24 | EnvironmentName = environment; 25 | } 26 | } 27 | 28 | public string EnvironmentName { get; private set; } = Development; 29 | 30 | public bool IsDevelopment() 31 | { 32 | var result = EnvironmentName.ToLowerInvariant() == Development; 33 | return result; 34 | } 35 | 36 | public bool IsProduction() 37 | { 38 | var result = EnvironmentName.ToLowerInvariant() == Production; 39 | return result; 40 | } 41 | 42 | public bool IsLocal() 43 | { 44 | var result = EnvironmentName.ToLowerInvariant() == Local; 45 | return result; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/Common/Models/ErrorDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Microsoft.AspNetCore.Mvc; 4 | 5 | namespace Infrastructure.Core.Common.Models 6 | { 7 | public class ErrorDetails : ProblemDetails 8 | { 9 | public ErrorDetails() 10 | { 11 | } 12 | 13 | public string StackTrace { get; set; } 14 | 15 | public string InnerException { get; set; } 16 | 17 | public string Identifier { get; internal set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/Common/Models/ValidationErrorDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.AspNetCore.Mvc.ModelBinding; 5 | 6 | namespace Infrastructure.Core.Common.Models 7 | { 8 | public class ValidationErrorDetails : ValidationProblemDetails 9 | { 10 | public ValidationErrorDetails(ModelStateDictionary modelState) 11 | : base(modelState) 12 | { 13 | } 14 | 15 | public string StackTrace { get; set; } 16 | 17 | public string InnerException { get; set; } 18 | 19 | public string Identifier { get; internal set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/Common/StreamKeyGeneratorHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Application.Interfaces.Common; 5 | 6 | namespace Infrastructure.Core.Common 7 | { 8 | public class StreamKeyGeneratorHelper : IStreamKeyGeneratorHelper 9 | { 10 | public string GetNewStreamKey() 11 | { 12 | return GuidToBase64(); 13 | } 14 | 15 | private static string GuidToBase64() 16 | { 17 | var guid = Guid.NewGuid(); 18 | var streamKey = Convert.ToBase64String(guid.ToByteArray()) 19 | .Replace("/", string.Empty) 20 | .Replace("=", string.Empty) 21 | .Replace("+", string.Empty) 22 | .Replace("&", string.Empty); 23 | 24 | return streamKey; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/CosmosDbData/CosmosDbContainerFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Infrastructure.Core.CosmosDbData.Interfaces; 5 | using Microsoft.Azure.Cosmos; 6 | 7 | namespace Infrastructure.Core.CosmosDbData 8 | { 9 | public class CosmosDbContainerFactory : ICosmosDbContainerFactory 10 | { 11 | private readonly CosmosClient _cosmosClient; 12 | private readonly string _databaseName; 13 | 14 | public CosmosDbContainerFactory(CosmosClient cosmosClient, string databaseName) 15 | { 16 | _databaseName = databaseName ?? throw new ArgumentNullException(nameof(databaseName)); 17 | _cosmosClient = cosmosClient ?? throw new ArgumentNullException(nameof(cosmosClient)); 18 | } 19 | 20 | public Container GetContainer(string containerName) 21 | { 22 | if (!CosmosDbSchema.Containers.ContainsKey(containerName)) 23 | { 24 | throw new ArgumentException($"Unknown container: {containerName}", nameof(containerName)); 25 | } 26 | 27 | return _cosmosClient.GetContainer(_databaseName, containerName); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/CosmosDbData/CosmosDbSchema.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | 6 | namespace Infrastructure.Core.CosmosDbData 7 | { 8 | public static class CosmosDbSchema 9 | { 10 | public const string CallContainer = "Call"; 11 | public const string CallPartitionKey = "/id"; 12 | 13 | public const string StreamContainer = "Stream"; 14 | public const string StreamPartitionKey = "/id"; 15 | 16 | public const string ParticipantStreamContainer = "ParticipantStream"; 17 | public const string ParticipantStreamPartitionKey = "/id"; 18 | 19 | public const string ServiceContainer = "Service"; 20 | public const string ServicePartitionKey = "/id"; 21 | 22 | public static readonly ReadOnlyDictionary Containers = new ReadOnlyDictionary(new Dictionary 23 | { 24 | { CallContainer, CallPartitionKey }, 25 | { ParticipantStreamContainer, ParticipantStreamPartitionKey }, 26 | { StreamContainer, StreamPartitionKey }, 27 | { ServiceContainer, ServicePartitionKey }, 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/CosmosDbData/CosmosDbSetup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Threading.Tasks; 4 | using Infrastructure.Core.CosmosDbData.Interfaces; 5 | using Microsoft.Azure.Cosmos; 6 | 7 | namespace Infrastructure.Core.CosmosDbData 8 | { 9 | public class CosmosDbSetup : ICosmosDbSetup 10 | { 11 | private readonly CosmosClient _client; 12 | private readonly string _databaseName; 13 | 14 | public CosmosDbSetup(CosmosClient client, string databaseName) 15 | { 16 | _client = client; 17 | _databaseName = databaseName; 18 | } 19 | 20 | public async Task SetupDatabaseAsync() 21 | { 22 | DatabaseResponse database = await _client.CreateDatabaseIfNotExistsAsync(_databaseName); 23 | 24 | foreach (var container in CosmosDbSchema.Containers) 25 | { 26 | await database.Database.CreateContainerIfNotExistsAsync(container.Key, container.Value).ConfigureAwait(false); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/CosmosDbData/CosmosDbSpecificationEvaluator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Ardalis.Specification; 4 | using Domain.Entities.Base; 5 | 6 | namespace Infrastructure.Core.CosmosDbData 7 | { 8 | public class CosmosDbSpecificationEvaluator : SpecificationEvaluatorBase 9 | where T : CosmosDbEntity 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/CosmosDbData/Extensions/IServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Infrastructure.Core.CosmosDbData.Interfaces; 4 | using Microsoft.Azure.Cosmos; 5 | using Microsoft.Extensions.DependencyInjection; 6 | 7 | namespace Infrastructure.Core.CosmosDbData.Extensions 8 | { 9 | public static class IServiceCollectionExtensions 10 | { 11 | public static IServiceCollection AddCosmosDb( 12 | this IServiceCollection services, 13 | string endpointUrl, 14 | string primaryKey, 15 | string databaseName) 16 | { 17 | CosmosClient client = new CosmosClient(endpointUrl, primaryKey); 18 | 19 | CosmosDbSetup cosmosDbSetup = new CosmosDbSetup(client, databaseName); 20 | services.AddSingleton(cosmosDbSetup); 21 | 22 | CosmosDbContainerFactory cosmosDbClientFactory = new CosmosDbContainerFactory(client, databaseName); 23 | services.AddSingleton(cosmosDbClientFactory); 24 | 25 | return services; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/CosmosDbData/Interfaces/ICosmosDbContainerFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Threading.Tasks; 4 | using Microsoft.Azure.Cosmos; 5 | 6 | namespace Infrastructure.Core.CosmosDbData.Interfaces 7 | { 8 | public interface ICosmosDbContainerFactory 9 | { 10 | Container GetContainer(string containerName); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/CosmosDbData/Interfaces/ICosmosDbSetup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Threading.Tasks; 4 | 5 | namespace Infrastructure.Core.CosmosDbData.Interfaces 6 | { 7 | public interface ICosmosDbSetup 8 | { 9 | Task SetupDatabaseAsync(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/CosmosDbData/Repository/CallRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Application.Interfaces.Persistance; 5 | using Domain.Entities; 6 | using Infrastructure.Core.CosmosDbData.Interfaces; 7 | using Microsoft.Azure.Cosmos; 8 | 9 | namespace Infrastructure.Core.CosmosDbData.Repository 10 | { 11 | public class CallRepository : CosmosDbRepository, ICallRepository 12 | { 13 | public CallRepository(ICosmosDbContainerFactory factory) 14 | : base(factory) 15 | { 16 | } 17 | 18 | public override string ContainerName => CosmosDbSchema.CallContainer; 19 | 20 | public override string GenerateId(Call entity) => $"{Guid.NewGuid()}"; 21 | 22 | public override PartitionKey ResolvePartitionKey(string entityId) => new PartitionKey(entityId); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/CosmosDbData/Repository/ParticipantStreamRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Application.Interfaces.Persistance; 5 | using Domain.Entities; 6 | using Infrastructure.Core.CosmosDbData.Interfaces; 7 | using Microsoft.Azure.Cosmos; 8 | 9 | namespace Infrastructure.Core.CosmosDbData.Repository 10 | { 11 | public class ParticipantStreamRepository : CosmosDbRepository, IParticipantStreamRepository 12 | { 13 | public ParticipantStreamRepository(ICosmosDbContainerFactory factory) 14 | : base(factory) 15 | { 16 | } 17 | 18 | public override string ContainerName => CosmosDbSchema.ParticipantStreamContainer; 19 | 20 | public override string GenerateId(ParticipantStream entity) => $"{Guid.NewGuid()}"; 21 | 22 | public override PartitionKey ResolvePartitionKey(string entityId) => new PartitionKey(entityId); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/CosmosDbData/Repository/ServiceRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Application.Interfaces.Persistance; 5 | using Domain.Entities; 6 | using Infrastructure.Core.CosmosDbData.Interfaces; 7 | using Microsoft.Azure.Cosmos; 8 | 9 | namespace Infrastructure.Core.CosmosDbData.Repository 10 | { 11 | public class ServiceRepository : CosmosDbRepository, IServiceRepository 12 | { 13 | public ServiceRepository(ICosmosDbContainerFactory factory) 14 | : base(factory) 15 | { 16 | } 17 | 18 | public override string ContainerName => CosmosDbSchema.ServiceContainer; 19 | 20 | public override string GenerateId(Service entity) => Guid.NewGuid().ToString(); 21 | 22 | public override PartitionKey ResolvePartitionKey(string entityId) => new PartitionKey(entityId); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/CosmosDbData/Repository/StreamRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using Application.Interfaces.Persistance; 5 | using Domain.Entities; 6 | using Infrastructure.Core.CosmosDbData.Interfaces; 7 | using Microsoft.Azure.Cosmos; 8 | 9 | namespace Infrastructure.Core.CosmosDbData.Repository 10 | { 11 | public class StreamRepository : CosmosDbRepository, IStreamRepository 12 | { 13 | public StreamRepository(ICosmosDbContainerFactory factory) 14 | : base(factory) 15 | { 16 | } 17 | 18 | public override string ContainerName => CosmosDbSchema.StreamContainer; 19 | 20 | public override string GenerateId(Stream entity) => $"{Guid.NewGuid()}"; 21 | 22 | public override PartitionKey ResolvePartitionKey(string entityId) => new PartitionKey(entityId); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/Services/AzService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Common.Config; 4 | using Application.Interfaces.Common; 5 | using Microsoft.Azure.Management.Fluent; 6 | using Microsoft.Azure.Management.ResourceManager.Fluent; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace Infrastructure.Core.Services 10 | { 11 | public class AzService : IAzService 12 | { 13 | private readonly AzServicePrincipalConfiguration _config; 14 | 15 | public AzService(IAppConfiguration config) 16 | { 17 | _config = config.AzServicePrincipalConfiguration; 18 | } 19 | 20 | public IAzure GetAzure() 21 | { 22 | var azureCredentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(_config.ApplicationClientId, _config.ApplicationClientSecret, _config.TenantId, AzureEnvironment.AzureGlobalCloud); 23 | var azureConfiguration = Microsoft.Azure.Management.Fluent.Azure.Configure() 24 | .Authenticate(azureCredentials) 25 | .WithSubscription(_config.SubscriptionId); 26 | 27 | return azureConfiguration; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/Services/AzStorageHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System; 4 | using System.Threading.Tasks; 5 | using Application.Common.Config; 6 | using Application.Interfaces.Common; 7 | using Azure.Storage.Queues; 8 | using Newtonsoft.Json; 9 | 10 | namespace Infrastructure.Core.Services 11 | { 12 | public class AzStorageHandler : IAzStorageHandler 13 | { 14 | private readonly IAppConfiguration _configuration; 15 | 16 | public AzStorageHandler(IAppConfiguration configuration) 17 | { 18 | _configuration = configuration; 19 | } 20 | 21 | public async Task AddQueueMessageAsync(string queue, object message) 22 | { 23 | var plainText = JsonConvert.SerializeObject(message); 24 | var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText); 25 | var queueMessage = Convert.ToBase64String(plainTextBytes); 26 | 27 | var queueClient = new QueueClient(_configuration.StorageConfiguration.ConnectionString, queue); 28 | 29 | await queueClient.CreateIfNotExistsAsync(); 30 | await queueClient.SendMessageAsync(queueMessage); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Infrastructure.Core/Services/GraphAuthenticationProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using System.Net.Http; 4 | using System.Threading.Tasks; 5 | using Application.Common.Config; 6 | using Microsoft.Graph; 7 | using Microsoft.IdentityModel.Clients.ActiveDirectory; 8 | 9 | namespace Infrastructure.Core.Services 10 | { 11 | /// 12 | /// This class provides the required provider to instantiate a GraphServiceClient. 13 | /// 14 | public class GraphAuthenticationProvider : IAuthenticationProvider 15 | { 16 | private const string GraphUri = "https://graph.microsoft.com/"; 17 | private readonly GraphClientConfiguration _configuration; 18 | 19 | public GraphAuthenticationProvider(IAppConfiguration configuration) 20 | { 21 | _configuration = configuration.GraphClientConfiguration; 22 | } 23 | 24 | public async Task AuthenticateRequestAsync(HttpRequestMessage request) 25 | { 26 | AuthenticationContext authContext = new AuthenticationContext($"https://login.microsoftonline.com/{_configuration.TenantId}"); 27 | 28 | ClientCredential creds = new ClientCredential(_configuration.ClientId, _configuration.ClientSecret); 29 | 30 | AuthenticationResult authResult = await authContext.AcquireTokenAsync(GraphUri, creds); 31 | 32 | request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ManagementApi/AppConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Common.Config; 4 | 5 | namespace ManagementApi 6 | { 7 | public class AppConfiguration : IAppConfiguration 8 | { 9 | public string BuildVersion { get; set; } 10 | 11 | public string KeyVaultName { get; set; } 12 | 13 | public string KeyVaultEnv { get; set; } 14 | 15 | public GraphClientConfiguration GraphClientConfiguration { get; set; } = new GraphClientConfiguration(); 16 | 17 | public AzStorageConfiguration StorageConfiguration { get; set; } = new AzStorageConfiguration(); 18 | 19 | public CosmosDbConfiguration CosmosDbConfiguration { get; set; } = new CosmosDbConfiguration(); 20 | 21 | public BotConfiguration BotConfiguration { get; set; } = new BotConfiguration(); 22 | 23 | public AzServicePrincipalConfiguration AzServicePrincipalConfiguration { get; set; } = new AzServicePrincipalConfiguration(); 24 | 25 | public AzureAdConfiguration AzureAdConfiguration { get; set; } = new AzureAdConfiguration(); 26 | 27 | public BotServiceAuthenticationConfiguration BotServiceAuthenticationConfiguration { get; set; } = new BotServiceAuthenticationConfiguration(); 28 | } 29 | } -------------------------------------------------------------------------------- /src/ManagementApi/Filters/AddBuildVersionHeaderFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Application.Common.Config; 4 | using Microsoft.AspNetCore.Mvc.Filters; 5 | 6 | namespace ManagementApi.Filters 7 | { 8 | public class AddBuildVersionHeaderFilter : IResultFilter 9 | { 10 | private readonly string _buildVersion; 11 | 12 | public AddBuildVersionHeaderFilter(IAppConfiguration configuration) 13 | { 14 | _buildVersion = configuration.BuildVersion; 15 | } 16 | 17 | public void OnResultExecuted(ResultExecutedContext context) 18 | { 19 | //// do nothing 20 | } 21 | 22 | public void OnResultExecuting(ResultExecutingContext context) 23 | { 24 | context.HttpContext.Response.Headers.Add("X-build-version", _buildVersion); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/ManagementApi/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | using Microsoft.AspNetCore; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.Logging; 7 | using Serilog; 8 | using Serilog.Sinks.SystemConsole.Themes; 9 | 10 | namespace ManagementApi 11 | { 12 | public static class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateWebHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 20 | WebHost.CreateDefaultBuilder(args) 21 | .ConfigureKestrel((context, options) => 22 | { 23 | options.AllowSynchronousIO = true; 24 | }) 25 | .UseSerilog((hostingContext, loggerConfiguration) => 26 | { 27 | loggerConfiguration 28 | .Enrich.FromLogContext() 29 | .WriteTo.Console(theme: AnsiConsoleTheme.Code) 30 | .WriteTo.ApplicationInsights(hostingContext.Configuration.GetValue("APPINSIGHTS_INSTRUMENTATIONKEY"), TelemetryConverter.Traces); 31 | }) 32 | .ConfigureLogging(logging => 33 | { 34 | logging.ClearProviders(); 35 | logging.AddDebug(); 36 | logging.SetMinimumLevel(LogLevel.Trace); 37 | logging.AddAzureWebAppDiagnostics(); 38 | }) 39 | .UseStartup(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/ManagementApi/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "Settings": { 11 | "BuildVersion": "0.6.0-dev" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/OrchestratorFunction/Properties/serviceDependencies.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "storage1": { 4 | "type": "storage", 5 | "connectionId": "AzureWebJobsStorage" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /src/OrchestratorFunction/Properties/serviceDependencies.local.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "storage1": { 4 | "type": "storage.emulator", 5 | "connectionId": "AzureWebJobsStorage" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /src/OrchestratorFunction/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "logging": { 4 | "applicationInsights": { 5 | "samplingExcludedTypes": "Request", 6 | "samplingSettings": { 7 | "isEnabled": true 8 | } 9 | } 10 | } 11 | } --------------------------------------------------------------------------------