Merge branch 'feature/marketing-details-azure-function' into dev
# Conflicts: # docker-compose.vs.debug.yml # docker-compose.vs.release.yml # eShopOnContainers-ServicesAndWebApps.sln # src/Services/Location/Locations.API/Startup.cs # src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs # src/Services/Marketing/Marketing.API/Marketing.API.csproj # src/Services/Marketing/Marketing.API/Startup.cs # src/Web/WebMVC/appsettings.json # src/Web/WebSPA/AppSettings.cs # test/Services/FunctionalTests/Services/Marketing/MarketingScenarios.cs
This commit is contained in:
commit
06cbab4731
18
.env
18
.env
@ -5,4 +5,20 @@
|
|||||||
# The IP below should be swapped to your real IP or DNS name, like 192.168.88.248, etc. if testing from remote browsers or mobile devices
|
# The IP below should be swapped to your real IP or DNS name, like 192.168.88.248, etc. if testing from remote browsers or mobile devices
|
||||||
|
|
||||||
ESHOP_EXTERNAL_DNS_NAME_OR_IP=localhost
|
ESHOP_EXTERNAL_DNS_NAME_OR_IP=localhost
|
||||||
ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92
|
ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92
|
||||||
|
|
||||||
|
#ESHOP_AZURE_REDIS_BASKET_DB=
|
||||||
|
#ESHOP_AZURE_STORAGE_CATALOG=
|
||||||
|
#ESHOP_AZURE_STORAGE_MARKETING=
|
||||||
|
#ESHOP_AZURE_SERVICE_BUS=
|
||||||
|
#ESHOP_AZURE_COSMOSDB=
|
||||||
|
#ESHOP_AZURE_CATALOG_DB=
|
||||||
|
#ESHOP_AZURE_IDENTITY_DB=
|
||||||
|
#ESHOP_AZURE_ORDERING_DB=
|
||||||
|
#ESHOP_AZURE_MARKETING_DB=
|
||||||
|
#ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI=
|
||||||
|
#ESHOP_AZURE_STORAGE_CATALOG_NAME=
|
||||||
|
#ESHOP_AZURE_STORAGE_CATALOG_KEY=
|
||||||
|
#ESHOP_AZURE_STORAGE_MARKETING_NAME=
|
||||||
|
#ESHOP_AZURE_STORAGE_MARKETING_KEY=
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
<DockerLaunchBrowser>True</DockerLaunchBrowser>
|
<DockerLaunchBrowser>True</DockerLaunchBrowser>
|
||||||
<DockerServiceUrl>http://localhost:5100</DockerServiceUrl>
|
<DockerServiceUrl>http://localhost:5100</DockerServiceUrl>
|
||||||
<DockerServiceName>webmvc</DockerServiceName>
|
<DockerServiceName>webmvc</DockerServiceName>
|
||||||
|
<DockerTargetOS>Linux</DockerTargetOS>
|
||||||
|
<ProjectVersion>2.0</ProjectVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="docker-compose.ci.build.yml" />
|
<None Include="docker-compose.ci.build.yml" />
|
||||||
@ -14,12 +16,6 @@
|
|||||||
<None Include="docker-compose.prod.yml">
|
<None Include="docker-compose.prod.yml">
|
||||||
<DependentUpon>docker-compose.yml</DependentUpon>
|
<DependentUpon>docker-compose.yml</DependentUpon>
|
||||||
</None>
|
</None>
|
||||||
<None Include="docker-compose.vs.debug.yml">
|
|
||||||
<DependentUpon>docker-compose.yml</DependentUpon>
|
|
||||||
</None>
|
|
||||||
<None Include="docker-compose.vs.release.yml">
|
|
||||||
<DependentUpon>docker-compose.yml</DependentUpon>
|
|
||||||
</None>
|
|
||||||
<None Include="docker-compose.yml" />
|
<None Include="docker-compose.yml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -9,15 +9,17 @@ version: '2.1'
|
|||||||
services:
|
services:
|
||||||
graceperiodmanager:
|
graceperiodmanager:
|
||||||
environment:
|
environment:
|
||||||
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||||
- EventBusConnection=rabbitmq
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
|
|
||||||
basket.api:
|
basket.api:
|
||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- ConnectionString=${ESHOP_AZURE_REDIS:-basket.data}
|
- ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basket.data}
|
||||||
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
ports:
|
ports:
|
||||||
- "5103:80"
|
- "5103:80"
|
||||||
@ -26,8 +28,8 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
- ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word}
|
||||||
- PicBaseUrl=${ESHOP_AZURE_STORAGE_ACCOUNT:-http://localhost:5101/api/v1/pic/} #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
- PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG:-http://localhost:5101/api/v1/pic/} #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
- AzureStorageAccountName=${ESHOP_AZURE_STORAGE_ACCOUNT_NAME}
|
- AzureStorageAccountName=${ESHOP_AZURE_STORAGE_ACCOUNT_NAME}
|
||||||
- AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_ACCOUNT_KEY}
|
- AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_ACCOUNT_KEY}
|
||||||
@ -41,8 +43,8 @@ services:
|
|||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- SpaClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5104
|
- SpaClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5104
|
||||||
- XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback #localhost do not work for UWP login, so we have to use "external" IP always
|
- XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback #localhost do not work for UWP login, so we have to use "external" IP always
|
||||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
- ConnectionStrings__DefaultConnection=${ESHOP_AZURE_IDENTITY_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word}
|
||||||
- MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5105.
|
- MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
- UseCustomizationData=True
|
- UseCustomizationData=True
|
||||||
ports:
|
ports:
|
||||||
- "5105:80"
|
- "5105:80"
|
||||||
@ -51,8 +53,8 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
- ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word}
|
||||||
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
- UseCustomizationData=True
|
- UseCustomizationData=True
|
||||||
ports:
|
ports:
|
||||||
@ -62,15 +64,18 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word
|
- ConnectionString=${ESHOP_AZURE_MARKETING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word}
|
||||||
- MongoConnectionString=mongodb://nosql.data
|
- MongoConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data}
|
||||||
- MongoDatabase=MarketingDb
|
- MongoDatabase=MarketingDb
|
||||||
- EventBusConnection=rabbitmq
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
- ExternalCatalogBaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5110 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
- CampaignDetailFunctionUri=${ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI}
|
||||||
|
- PicBaseUrl=${ESHOP_AZURE_STORAGE_MARKETING:-http://localhost:5110/api/v1/pic/}
|
||||||
|
- AzureStorageAccountName=${ESHOP_AZURE_STORAGE_MARKETING_NAME}
|
||||||
|
- AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_MARKETING_KEY}
|
||||||
ports:
|
ports:
|
||||||
- "5110:80"
|
- "5110:80"
|
||||||
|
|
||||||
webspa:
|
webspa:
|
||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
@ -133,7 +138,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
- ASPNETCORE_URLS=http://0.0.0.0:5108
|
- ASPNETCORE_URLS=http://0.0.0.0:5108
|
||||||
- EventBusConnection=rabbitmq
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
ports:
|
ports:
|
||||||
- "5108:80"
|
- "5108:80"
|
||||||
|
|
||||||
@ -141,9 +146,9 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- ConnectionString=mongodb://nosql.data
|
- ConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data}
|
||||||
- Database=LocationsDb
|
- Database=LocationsDb
|
||||||
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
- EventBusConnection=rabbitmq
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
ports:
|
ports:
|
||||||
- "5109:80"
|
- "5109:80"
|
||||||
|
@ -12,13 +12,19 @@ version: '2.1'
|
|||||||
# docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
# docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
graceperiodmanager:
|
||||||
|
environment:
|
||||||
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
|
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||||
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
|
|
||||||
basket.api:
|
basket.api:
|
||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Production
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- ConnectionString=${ESHOP_AZURE_REDIS:-basket.data}
|
- ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basket.data}
|
||||||
- identityUrl=http://identity.api #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
ports:
|
ports:
|
||||||
- "5103:80"
|
- "5103:80"
|
||||||
@ -26,10 +32,13 @@ services:
|
|||||||
catalog.api:
|
catalog.api:
|
||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Production
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
|
- ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word}
|
||||||
- ExternalCatalogBaseUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
- PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG:-http://localhost:5101/api/v1/pic/} #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
|
- AzureStorageAccountName=${ESHOP_AZURE_STORAGE_ACCOUNT_NAME}
|
||||||
|
- AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_ACCOUNT_KEY}
|
||||||
|
- UseCustomizationData=True
|
||||||
ports:
|
ports:
|
||||||
- "5101:80"
|
- "5101:80"
|
||||||
|
|
||||||
@ -38,9 +47,10 @@ services:
|
|||||||
- ASPNETCORE_ENVIRONMENT=Production
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- SpaClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5104
|
- SpaClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5104
|
||||||
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
|
- ConnectionStrings__DefaultConnection=${ESHOP_AZURE_IDENTITY_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word}
|
||||||
- MvcClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your host's firewall at range 5100-5105.
|
- MvcClient=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your host's firewall at range 5100-5110.
|
||||||
- XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback
|
- XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback
|
||||||
|
- UseCustomizationData=True
|
||||||
ports:
|
ports:
|
||||||
- "5105:80"
|
- "5105:80"
|
||||||
|
|
||||||
@ -48,9 +58,10 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Production
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
- ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word}
|
||||||
- identityUrl=http://identity.api #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
|
- UseCustomizationData=True
|
||||||
ports:
|
ports:
|
||||||
- "5102:80"
|
- "5102:80"
|
||||||
|
|
||||||
@ -58,11 +69,15 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Production
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word
|
- ConnectionString=${ESHOP_AZURE_MARKETING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word}
|
||||||
- MongoConnectionString=mongodb://nosql.data
|
- MongoConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data}
|
||||||
- MongoDatabase=MarketingDb
|
- MongoDatabase=MarketingDb
|
||||||
- EventBusConnection=rabbitmq
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
|
- CampaignDetailFunctionUri=${ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI}
|
||||||
|
- PicBaseUrl=${ESHOP_AZURE_STORAGE_MARKETING:-http://localhost:5110/api/v1/pic/}
|
||||||
|
- AzureStorageAccountName=${ESHOP_AZURE_STORAGE_MARKETING_NAME}
|
||||||
|
- AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_MARKETING_KEY}
|
||||||
ports:
|
ports:
|
||||||
- "5110:80"
|
- "5110:80"
|
||||||
|
|
||||||
@ -72,12 +87,14 @@ services:
|
|||||||
- ASPNETCORE_URLS=http://0.0.0.0:80
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
- CatalogUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101
|
- CatalogUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101
|
||||||
- OrderingUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102
|
- OrderingUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5102
|
||||||
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
|
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your host's firewall at range 5100-5110.
|
||||||
- BasketUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103
|
- BasketUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5103
|
||||||
- CatalogUrlHC=http://catalog.api/hc
|
- CatalogUrlHC=http://catalog.api/hc
|
||||||
- OrderingUrlHC=http://ordering.api/hc
|
- OrderingUrlHC=http://ordering.api/hc
|
||||||
- IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
- IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||||
- BasketUrlHC=http://basket.api/hc
|
- BasketUrlHC=http://basket.api/hc
|
||||||
|
- MarketingUrlHC=http://marketing.api/hc
|
||||||
|
- UseCustomizationData=True
|
||||||
ports:
|
ports:
|
||||||
- "5104:80"
|
- "5104:80"
|
||||||
|
|
||||||
@ -89,6 +106,7 @@ services:
|
|||||||
- OrderingUrl=http://ordering.api
|
- OrderingUrl=http://ordering.api
|
||||||
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||||
- BasketUrl=http://basket.api
|
- BasketUrl=http://basket.api
|
||||||
|
- MarketingUrl=http://marketing.api
|
||||||
ports:
|
ports:
|
||||||
- "5100:80"
|
- "5100:80"
|
||||||
|
|
||||||
@ -99,6 +117,10 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "5433:1433"
|
- "5433:1433"
|
||||||
|
|
||||||
|
nosql.data:
|
||||||
|
ports:
|
||||||
|
- "27017:27017"
|
||||||
|
|
||||||
webstatus:
|
webstatus:
|
||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Production
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
@ -106,9 +128,30 @@ services:
|
|||||||
- CatalogUrl=http://catalog.api/hc
|
- CatalogUrl=http://catalog.api/hc
|
||||||
- OrderingUrl=http://ordering.api/hc
|
- OrderingUrl=http://ordering.api/hc
|
||||||
- BasketUrl=http://basket.api/hc
|
- BasketUrl=http://basket.api/hc
|
||||||
- IdentityUrl=http://identity.api/hc
|
- IdentityUrl=http://identity.api/hc
|
||||||
|
- LocationsUrl=http://locations.api/hc
|
||||||
|
- MarketingUrl=http://marketing.api/hc
|
||||||
- mvc=http://webmvc/hc
|
- mvc=http://webmvc/hc
|
||||||
- spa=http://webspa/hc
|
- spa=http://webspa/hc
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
- "5107:80"
|
- "5107:80"
|
||||||
|
|
||||||
|
payment.api:
|
||||||
|
environment:
|
||||||
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
|
- ASPNETCORE_URLS=http://0.0.0.0:5108
|
||||||
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
|
ports:
|
||||||
|
- "5108:80"
|
||||||
|
|
||||||
|
locations.api:
|
||||||
|
environment:
|
||||||
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
|
- ConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data}
|
||||||
|
- Database=LocationsDb
|
||||||
|
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
|
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
|
||||||
|
ports:
|
||||||
|
- "5109:80"
|
96
eShopOnContainers-AzureFunctions.sln
Normal file
96
eShopOnContainers-AzureFunctions.sln
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.26608.5
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Infrastructure", "Infrastructure", "{5B1011EC-CEE5-47AA-B336-99381D573679}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AzureFunctions", "AzureFunctions", "{106B787C-2CFF-4484-8C07-D14589859E94}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "marketing-functions", "src\Services\Marketing\Infrastructure\AzureFunctions\marketing-functions.csproj", "{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
|
||||||
|
Ad-Hoc|ARM = Ad-Hoc|ARM
|
||||||
|
Ad-Hoc|iPhone = Ad-Hoc|iPhone
|
||||||
|
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
|
||||||
|
Ad-Hoc|x64 = Ad-Hoc|x64
|
||||||
|
Ad-Hoc|x86 = Ad-Hoc|x86
|
||||||
|
AppStore|Any CPU = AppStore|Any CPU
|
||||||
|
AppStore|ARM = AppStore|ARM
|
||||||
|
AppStore|iPhone = AppStore|iPhone
|
||||||
|
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
|
||||||
|
AppStore|x64 = AppStore|x64
|
||||||
|
AppStore|x86 = AppStore|x86
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|ARM = Debug|ARM
|
||||||
|
Debug|iPhone = Debug|iPhone
|
||||||
|
Debug|iPhoneSimulator = Debug|iPhoneSimulator
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|ARM = Release|ARM
|
||||||
|
Release|iPhone = Release|iPhone
|
||||||
|
Release|iPhoneSimulator = Release|iPhoneSimulator
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|x64.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.AppStore|x86.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|iPhone.Build.0 = Release|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{106B787C-2CFF-4484-8C07-D14589859E94} = {5B1011EC-CEE5-47AA-B336-99381D573679}
|
||||||
|
{B363EF31-DD1A-46C8-ADDF-CD30A756E97B} = {106B787C-2CFF-4484-8C07-D14589859E94}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
@ -82,10 +82,10 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
|||||||
{
|
{
|
||||||
services.AddSingleton<IServiceBusPersisterConnection>(sp =>
|
services.AddSingleton<IServiceBusPersisterConnection>(sp =>
|
||||||
{
|
{
|
||||||
var settings = sp.GetRequiredService<IOptions<BasketSettings>>().Value;
|
|
||||||
var logger = sp.GetRequiredService<ILogger<DefaultServiceBusPersisterConnection>>();
|
var logger = sp.GetRequiredService<ILogger<DefaultServiceBusPersisterConnection>>();
|
||||||
|
|
||||||
var serviceBusConnection = new ServiceBusConnectionStringBuilder(settings.EventBusConnection);
|
var serviceBusConnectionString = Configuration["EventBusConnection"];
|
||||||
|
var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString);
|
||||||
|
|
||||||
return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger);
|
return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger);
|
||||||
});
|
});
|
||||||
@ -94,17 +94,19 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
|||||||
{
|
{
|
||||||
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
||||||
{
|
{
|
||||||
var settings = sp.GetRequiredService<IOptions<BasketSettings>>().Value;
|
|
||||||
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
||||||
|
|
||||||
var factory = new ConnectionFactory()
|
var factory = new ConnectionFactory()
|
||||||
{
|
{
|
||||||
HostName = settings.EventBusConnection
|
HostName = Configuration["EventBusConnection"]
|
||||||
};
|
};
|
||||||
|
|
||||||
return new DefaultRabbitMQPersistentConnection(factory, logger);
|
return new DefaultRabbitMQPersistentConnection(factory, logger);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RegisterEventBus(services);
|
||||||
|
|
||||||
|
|
||||||
services.AddSwaggerGen(options =>
|
services.AddSwaggerGen(options =>
|
||||||
{
|
{
|
||||||
@ -130,7 +132,6 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
|||||||
services.AddTransient<IBasketRepository, RedisBasketRepository>();
|
services.AddTransient<IBasketRepository, RedisBasketRepository>();
|
||||||
services.AddTransient<IIdentityService, IdentityService>();
|
services.AddTransient<IIdentityService, IdentityService>();
|
||||||
|
|
||||||
RegisterEventBus(services);
|
|
||||||
services.AddOptions();
|
services.AddOptions();
|
||||||
|
|
||||||
var container = new ContainerBuilder();
|
var container = new ContainerBuilder();
|
||||||
|
@ -239,14 +239,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
||||||
services.AddTransient<IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent>,
|
services.AddTransient<OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
|
||||||
OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
|
services.AddTransient<OrderStatusChangedToPaidIntegrationEventHandler>();
|
||||||
services.AddTransient<IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent>,
|
|
||||||
OrderStatusChangedToPaidIntegrationEventHandler>();
|
|
||||||
}
|
}
|
||||||
protected virtual void ConfigureEventBus(IApplicationBuilder app)
|
protected virtual void ConfigureEventBus(IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
|
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
|
||||||
|
eventBus.Subscribe<OrderStatusChangedToAwaitingValidationIntegrationEvent, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
|
||||||
|
eventBus.Subscribe<OrderStatusChangedToPaidIntegrationEvent, OrderStatusChangedToPaidIntegrationEventHandler>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AzureServiceBusEnabled": false,
|
"AzureServiceBusEnabled": false,
|
||||||
"AzureStorageEnabled": true,
|
"AzureStorageEnabled": false,
|
||||||
"SubscriptionClientName": "Catalog"
|
"SubscriptionClientName": "Catalog"
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" />
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" />
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj" />
|
||||||
<ProjectReference Include="..\..\Ordering\Ordering.Infrastructure\Ordering.Infrastructure.csproj" />
|
<ProjectReference Include="..\..\Ordering\Ordering.Infrastructure\Ordering.Infrastructure.csproj" />
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using RabbitMQ.Client;
|
using RabbitMQ.Client;
|
||||||
using Services;
|
using Services;
|
||||||
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus;
|
||||||
|
using Microsoft.Azure.ServiceBus;
|
||||||
|
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
@ -58,20 +60,36 @@
|
|||||||
services.AddLogging()
|
services.AddLogging()
|
||||||
.AddOptions()
|
.AddOptions()
|
||||||
.Configure<ManagerSettings>(Configuration)
|
.Configure<ManagerSettings>(Configuration)
|
||||||
.AddSingleton<IManagerService, ManagerService>()
|
.AddSingleton<IManagerService, ManagerService>();
|
||||||
.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
|
||||||
|
if (Configuration.GetValue<bool>("AzureServiceBusEnabled"))
|
||||||
|
{
|
||||||
|
services.AddSingleton<IServiceBusPersisterConnection>(sp =>
|
||||||
|
{
|
||||||
|
var logger = sp.GetRequiredService<ILogger<DefaultServiceBusPersisterConnection>>();
|
||||||
|
|
||||||
|
var serviceBusConnectionString = Configuration["EventBusConnection"];
|
||||||
|
var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString);
|
||||||
|
|
||||||
|
return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
||||||
{
|
{
|
||||||
var settings = sp.GetRequiredService<IOptions<ManagerSettings>>().Value;
|
|
||||||
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
||||||
|
|
||||||
var factory = new ConnectionFactory()
|
var factory = new ConnectionFactory()
|
||||||
{
|
{
|
||||||
HostName = settings.EventBusConnection
|
HostName = Configuration["EventBusConnection"]
|
||||||
};
|
};
|
||||||
|
|
||||||
return new DefaultRabbitMQPersistentConnection(factory, logger);
|
return new DefaultRabbitMQPersistentConnection(factory, logger);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
RegisterEventBus(services);
|
RegisterEventBus(services);
|
||||||
|
|
||||||
var container = new ContainerBuilder();
|
var container = new ContainerBuilder();
|
||||||
container.Populate(services);
|
container.Populate(services);
|
||||||
@ -87,7 +105,25 @@
|
|||||||
|
|
||||||
private static void RegisterEventBus(IServiceCollection services)
|
private static void RegisterEventBus(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
if (Configuration.GetValue<bool>("AzureServiceBusEnabled"))
|
||||||
|
{
|
||||||
|
services.AddSingleton<IEventBus, EventBusServiceBus>(sp =>
|
||||||
|
{
|
||||||
|
var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
|
||||||
|
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>();
|
||||||
|
var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
|
||||||
|
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
|
||||||
|
var subscriptionClientName = Configuration["SubscriptionClientName"];
|
||||||
|
|
||||||
|
return new EventBusServiceBus(serviceBusPersisterConnection, logger,
|
||||||
|
eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
||||||
|
}
|
||||||
|
|
||||||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,7 @@
|
|||||||
},
|
},
|
||||||
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;",
|
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;",
|
||||||
"GracePeriodTime": "1",
|
"GracePeriodTime": "1",
|
||||||
"CheckUpdateTime": "30000"
|
"CheckUpdateTime": "30000",
|
||||||
|
"AzureServiceBusEnabled": false,
|
||||||
|
"SubscriptionClientName": "GracePeriod"
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,21 @@ namespace Identity.API.Configuration
|
|||||||
"locations",
|
"locations",
|
||||||
"marketing"
|
"marketing"
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
new Client
|
||||||
|
{
|
||||||
|
ClientId = "swaggerui",
|
||||||
|
ClientName = "Swagger UI",
|
||||||
|
AllowedGrantTypes = GrantTypes.Implicit,
|
||||||
|
AllowAccessTokensViaBrowser = true,
|
||||||
|
|
||||||
|
RedirectUris = { "http://localhost:5109/swagger/o2c.html" },
|
||||||
|
PostLogoutRedirectUris = { "http://localhost:5109/swagger/" },
|
||||||
|
|
||||||
|
AllowedScopes =
|
||||||
|
{
|
||||||
|
"locations"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ namespace Locations.API.Controllers
|
|||||||
var location = await _locationsService.GetLocation(locationId);
|
var location = await _locationsService.GetLocation(locationId);
|
||||||
return Ok(location);
|
return Ok(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
//POST api/v1/[controller]/
|
//POST api/v1/[controller]/
|
||||||
[Route("")]
|
[Route("")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Swashbuckle.AspNetCore.Swagger;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Filters
|
||||||
|
{
|
||||||
|
internal class AuthorizeCheckOperationFilter : IOperationFilter
|
||||||
|
{
|
||||||
|
public void Apply(Operation operation, OperationFilterContext context)
|
||||||
|
{
|
||||||
|
// Check for authorize attribute
|
||||||
|
var hasAuthorize = context.ApiDescription.ControllerAttributes().OfType<AuthorizeAttribute>().Any() ||
|
||||||
|
context.ApiDescription.ActionAttributes().OfType<AuthorizeAttribute>().Any();
|
||||||
|
|
||||||
|
if (hasAuthorize)
|
||||||
|
{
|
||||||
|
operation.Responses.Add("401", new Response { Description = "Unauthorized" });
|
||||||
|
operation.Responses.Add("403", new Response { Description = "Forbidden" });
|
||||||
|
|
||||||
|
operation.Security = new List<IDictionary<string, IEnumerable<string>>>();
|
||||||
|
operation.Security.Add(new Dictionary<string, IEnumerable<string>>
|
||||||
|
{
|
||||||
|
{ "oauth2", new [] { "api1" } }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Repositories
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Repositories
|
||||||
{
|
{
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
|
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using MongoDB.Bson;
|
using MongoDB.Bson;
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services
|
|
||||||
{
|
{
|
||||||
public interface IIdentityService
|
public interface IIdentityService
|
||||||
{
|
{
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services
|
||||||
{
|
{
|
||||||
public class IdentityService : IIdentityService
|
public class IdentityService : IIdentityService
|
||||||
{
|
{
|
||||||
private IHttpContextAccessor _context;
|
private readonly IHttpContextAccessor _context;
|
||||||
|
|
||||||
public IdentityService(IHttpContextAccessor context)
|
public IdentityService(IHttpContextAccessor context)
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services
|
||||||
{
|
{
|
||||||
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Repositories;
|
|
||||||
using Microsoft.eShopOnContainers.Services.Locations.API.ViewModel;
|
|
||||||
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
|
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Exceptions;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
|
||||||
using Microsoft.eShopOnContainers.Services.Locations.API.IntegrationEvents.Events;
|
using Microsoft.eShopOnContainers.Services.Locations.API.IntegrationEvents.Events;
|
||||||
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Exceptions;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Repositories;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Locations.API.ViewModel;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public class LocationsService : ILocationsService
|
public class LocationsService : ILocationsService
|
||||||
{
|
{
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Locations.API.IntegrationEvents.Events
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.IntegrationEvents.Events
|
||||||
{
|
{
|
||||||
|
using Locations.API.Model;
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||||
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public class UserLocationUpdatedIntegrationEvent : IntegrationEvent
|
public class UserLocationUpdatedIntegrationEvent : IntegrationEvent
|
||||||
{
|
{
|
||||||
public string UserId { get; private set; }
|
public string UserId { get; set; }
|
||||||
public List<UserLocationDetails> LocationList { get; private set; }
|
public List<UserLocationDetails> LocationList { get; set; }
|
||||||
|
|
||||||
public UserLocationUpdatedIntegrationEvent(string userId, List<UserLocationDetails> locationList)
|
public UserLocationUpdatedIntegrationEvent(string userId, List<UserLocationDetails> locationList)
|
||||||
{
|
{
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" />
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" />
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" />
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.Model
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Services.Locations.API.Model
|
|
||||||
{
|
{
|
||||||
public class UserLocationDetails
|
public class UserLocationDetails
|
||||||
{
|
{
|
||||||
@ -11,4 +6,4 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API.Model
|
|||||||
public string Code { get; set; }
|
public string Code { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,6 +16,10 @@ using Microsoft.Extensions.Logging;
|
|||||||
using RabbitMQ.Client;
|
using RabbitMQ.Client;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System;
|
using System;
|
||||||
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus;
|
||||||
|
using Microsoft.Azure.ServiceBus;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Swashbuckle.AspNetCore.Swagger;
|
||||||
using Microsoft.Extensions.HealthChecks;
|
using Microsoft.Extensions.HealthChecks;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -53,24 +57,39 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API
|
|||||||
|
|
||||||
services.Configure<LocationSettings>(Configuration);
|
services.Configure<LocationSettings>(Configuration);
|
||||||
|
|
||||||
services.AddHealthChecks(checks =>
|
if (Configuration.GetValue<bool>("AzureServiceBusEnabled"))
|
||||||
|
{
|
||||||
|
services.AddSingleton<IServiceBusPersisterConnection>(sp =>
|
||||||
|
{
|
||||||
|
var logger = sp.GetRequiredService<ILogger<DefaultServiceBusPersisterConnection>>();
|
||||||
|
|
||||||
|
var serviceBusConnectionString = Configuration["EventBusConnection"];
|
||||||
|
var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString);
|
||||||
|
|
||||||
|
return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
||||||
|
{
|
||||||
|
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
||||||
|
|
||||||
|
var factory = new ConnectionFactory
|
||||||
|
{
|
||||||
|
HostName = Configuration["EventBusConnection"]
|
||||||
|
};
|
||||||
|
|
||||||
|
return new DefaultRabbitMQPersistentConnection(factory, logger);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
services.AddHealthChecks(checks =>
|
||||||
{
|
{
|
||||||
checks.AddValueTaskCheck("HTTP Endpoint", () => new ValueTask<IHealthCheckResult>(HealthCheckResult.Healthy("Ok")));
|
checks.AddValueTaskCheck("HTTP Endpoint", () => new ValueTask<IHealthCheckResult>(HealthCheckResult.Healthy("Ok")));
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
RegisterEventBus(services);
|
||||||
{
|
|
||||||
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
|
||||||
|
|
||||||
var factory = new ConnectionFactory()
|
|
||||||
{
|
|
||||||
HostName = Configuration["EventBusConnection"]
|
|
||||||
};
|
|
||||||
|
|
||||||
return new DefaultRabbitMQPersistentConnection(factory, logger);
|
|
||||||
});
|
|
||||||
|
|
||||||
RegisterServiceBus(services);
|
|
||||||
|
|
||||||
// Add framework services.
|
// Add framework services.
|
||||||
services.AddSwaggerGen(options =>
|
services.AddSwaggerGen(options =>
|
||||||
@ -83,6 +102,21 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API
|
|||||||
Description = "The Location Microservice HTTP API. This is a Data-Driven/CRUD microservice sample",
|
Description = "The Location Microservice HTTP API. This is a Data-Driven/CRUD microservice sample",
|
||||||
TermsOfService = "Terms Of Service"
|
TermsOfService = "Terms Of Service"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
options.AddSecurityDefinition("oauth2", new OAuth2Scheme
|
||||||
|
{
|
||||||
|
Type = "oauth2",
|
||||||
|
Flow = "implicit",
|
||||||
|
AuthorizationUrl = "http://localhost:5105/connect/authorize",
|
||||||
|
TokenUrl = "http://localhost:5105/connect/token",
|
||||||
|
Scopes = new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{ "locations", "Locations API" }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
options.OperationFilter<AuthorizeCheckOperationFilter>();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddCors(options =>
|
services.AddCors(options =>
|
||||||
@ -124,6 +158,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API
|
|||||||
.UseSwaggerUI(c =>
|
.UseSwaggerUI(c =>
|
||||||
{
|
{
|
||||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
|
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
|
||||||
|
c.ConfigureOAuth2("swaggerui", "", "", "Swagger UI");
|
||||||
});
|
});
|
||||||
|
|
||||||
LocationsContextSeed.SeedAsync(app, loggerFactory)
|
LocationsContextSeed.SeedAsync(app, loggerFactory)
|
||||||
@ -141,10 +176,28 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterServiceBus(IServiceCollection services)
|
private void RegisterEventBus(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
if (Configuration.GetValue<bool>("AzureServiceBusEnabled"))
|
||||||
|
{
|
||||||
|
services.AddSingleton<IEventBus, EventBusServiceBus>(sp =>
|
||||||
|
{
|
||||||
|
var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
|
||||||
|
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>();
|
||||||
|
var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
|
||||||
|
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
|
||||||
|
var subscriptionClientName = Configuration["SubscriptionClientName"];
|
||||||
|
|
||||||
|
return new EventBusServiceBus(serviceBusPersisterConnection, logger,
|
||||||
|
eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
||||||
|
}
|
||||||
|
|
||||||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,7 @@
|
|||||||
"System": "Information",
|
"System": "Information",
|
||||||
"Microsoft": "Information"
|
"Microsoft": "Information"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"AzureServiceBusEnabled": false,
|
||||||
|
"SubscriptionClientName": "Locations"
|
||||||
}
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"bindings": [
|
||||||
|
{
|
||||||
|
"authLevel": "function",
|
||||||
|
"name": "req",
|
||||||
|
"type": "httpTrigger",
|
||||||
|
"direction": "in"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "$return",
|
||||||
|
"type": "http",
|
||||||
|
"direction": "out"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"disabled": false
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
|
||||||
|
"frameworks": {
|
||||||
|
|
||||||
|
"net46":{
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
|
||||||
|
"Dapper": "1.50.2",
|
||||||
|
|
||||||
|
"System.Data.SqlClient":"4.1.0",
|
||||||
|
|
||||||
|
"Microsoft.WindowsAzure.ConfigurationManager":"3.2.1"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
using System.Net;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Configuration;
|
||||||
|
using Dapper;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
|
||||||
|
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
|
||||||
|
{
|
||||||
|
log.Info($"Campaign HTTP trigger function processed a request. RequestUri={req.RequestUri}");
|
||||||
|
|
||||||
|
string htmlResponse = string.Empty;
|
||||||
|
|
||||||
|
// parse query parameter
|
||||||
|
string campaignId = req.GetQueryNameValuePairs()
|
||||||
|
.FirstOrDefault(q => string.Compare(q.Key, "campaignId", true) == 0)
|
||||||
|
.Value;
|
||||||
|
|
||||||
|
string userId = req.GetQueryNameValuePairs()
|
||||||
|
.FirstOrDefault(q => string.Compare(q.Key, "userId", true) == 0)
|
||||||
|
.Value;
|
||||||
|
|
||||||
|
var cnnString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString;
|
||||||
|
|
||||||
|
using (var conn = new SqlConnection(cnnString))
|
||||||
|
{
|
||||||
|
await conn.OpenAsync();
|
||||||
|
var sql = "SELECT * FROM [dbo].[Campaign] WHERE Id = @CampaignId;";
|
||||||
|
var campaign = (await conn.QueryAsync<Campaign>(sql, new { CampaignId = campaignId })).FirstOrDefault();
|
||||||
|
htmlResponse = BuildHtmlResponse(campaign);
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = new HttpResponseMessage(HttpStatusCode.OK);
|
||||||
|
response.Content = new ByteArrayContent(System.Text.Encoding.UTF8.GetBytes(htmlResponse));
|
||||||
|
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string BuildHtmlResponse(Campaign campaign)
|
||||||
|
{
|
||||||
|
var marketingStorageUri = ConfigurationManager.AppSettings["MarketingStorageUri"];
|
||||||
|
|
||||||
|
return string.Format(@"
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css' rel='stylesheet'>
|
||||||
|
</head>
|
||||||
|
<header>
|
||||||
|
<title>Campaign Details</title>
|
||||||
|
</header>
|
||||||
|
<body>
|
||||||
|
<div class='container'>
|
||||||
|
</br>
|
||||||
|
<div class='card-deck'>
|
||||||
|
<div class='card text-center'>
|
||||||
|
<img class='card-img-top' src='{0}' alt='Card image cap'>
|
||||||
|
<div class='card-block'>
|
||||||
|
<h4 class='card-title'>{1}</h4>
|
||||||
|
<p class='card-text'>{2}</p>
|
||||||
|
<div class='card-footer'>
|
||||||
|
<small class='text-muted'>From {3} until {4}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>",
|
||||||
|
$"{marketingStorageUri}{campaign.PictureName}",
|
||||||
|
campaign.Name,
|
||||||
|
campaign.Description,
|
||||||
|
campaign.From.ToString("MMMM dd, yyyy"),
|
||||||
|
campaign.From.ToString("MMMM dd, yyyy"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Campaign
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public DateTime From { get; set; }
|
||||||
|
|
||||||
|
public DateTime To { get; set; }
|
||||||
|
|
||||||
|
public string PictureUri { get; set; }
|
||||||
|
|
||||||
|
public string PictureName { get; set; }
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
{}
|
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"IsEncrypted": false,
|
||||||
|
"Value": {
|
||||||
|
"APPSETTING_FUNCTIONS_EXTENSION_VERSION": "~1",
|
||||||
|
"APPSETTING_ScmType": "None",
|
||||||
|
"APPSETTING_WEBSITE_AUTH_ENABLED": "False",
|
||||||
|
"APPSETTING_REMOTEDEBUGGINGVERSION": "11.0.611103.400",
|
||||||
|
"APPSETTING_AzureWebJobsDashboard": "",
|
||||||
|
"APPSETTING_MarketingStorageUri": "",
|
||||||
|
"APPSETTING_WEBSITE_NODE_DEFAULT_VERSION": "6.5.0",
|
||||||
|
"APPSETTING_WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "",
|
||||||
|
"APPSETTING_WEBSITE_CONTENTSHARE": "",
|
||||||
|
"APPSETTING_WEBSITE_SLOT_NAME": "",
|
||||||
|
"APPSETTING_AzureWebJobsStorage": "",
|
||||||
|
"APPSETTING_WEBSITE_SITE_NAME": ""
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net461</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Azure.WebJobs" Version="2.1.0-beta1" />
|
||||||
|
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="1.0.0-beta1" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.0-alpha5" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="host.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="MarketingDetailsHttpTrigger/function.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="MarketingDetailsHttpTrigger/project.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="MarketingDetailsHttpTrigger/project.lock.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="MarketingDetailsHttpTrigger/run.csx">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="local.settings.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -15,6 +15,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
|
|||||||
using AspNetCore.Authorization;
|
using AspNetCore.Authorization;
|
||||||
using Extensions.Options;
|
using Extensions.Options;
|
||||||
using Microsoft.eShopOnContainers.Services.Marketing.API.ViewModel;
|
using Microsoft.eShopOnContainers.Services.Marketing.API.ViewModel;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
[Route("api/v1/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
@ -182,15 +183,23 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
|
|||||||
|
|
||||||
private CampaignDTO MapCampaignModelToDto(Campaign campaign)
|
private CampaignDTO MapCampaignModelToDto(Campaign campaign)
|
||||||
{
|
{
|
||||||
return new CampaignDTO
|
var userId = _identityService.GetUserIdentity();
|
||||||
|
var dto = new CampaignDTO
|
||||||
{
|
{
|
||||||
Id = campaign.Id,
|
Id = campaign.Id,
|
||||||
Name = campaign.Name,
|
Name = campaign.Name,
|
||||||
Description = campaign.Description,
|
Description = campaign.Description,
|
||||||
From = campaign.From,
|
From = campaign.From,
|
||||||
To = campaign.To,
|
To = campaign.To,
|
||||||
PictureUri = GetUriPlaceholder(campaign.PictureUri)
|
PictureUri = GetUriPlaceholder(campaign),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(_settings.CampaignDetailFunctionUri))
|
||||||
|
{
|
||||||
|
dto.DetailsUri = $"{_settings.CampaignDetailFunctionUri}&campaignId={campaign.Id}&userId={userId}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Campaign MapCampaignDtoToModel(CampaignDTO campaignDto)
|
private Campaign MapCampaignDtoToModel(CampaignDTO campaignDto)
|
||||||
@ -206,13 +215,13 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetUriPlaceholder(string campaignUri)
|
private string GetUriPlaceholder(Campaign campaign)
|
||||||
{
|
{
|
||||||
var baseUri = _settings.ExternalCatalogBaseUrl;
|
var baseUri = _settings.PicBaseUrl;
|
||||||
|
|
||||||
campaignUri = campaignUri.Replace("http://externalcatalogbaseurltobereplaced", baseUri);
|
return _settings.AzureStorageEnabled
|
||||||
|
? baseUri + campaign.PictureName
|
||||||
return campaignUri;
|
: baseUri + campaign.Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,5 +15,6 @@
|
|||||||
public DateTime To { get; set; }
|
public DateTime To { get; set; }
|
||||||
|
|
||||||
public string PictureUri { get; set; }
|
public string PictureUri { get; set; }
|
||||||
|
public string DetailsUri { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -38,6 +38,7 @@
|
|||||||
From = DateTime.Now,
|
From = DateTime.Now,
|
||||||
To = DateTime.Now.AddDays(7),
|
To = DateTime.Now.AddDays(7),
|
||||||
PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/campaigns/1/pic",
|
PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/campaigns/1/pic",
|
||||||
|
PictureName = "1.png",
|
||||||
Rules = new List<Rule>
|
Rules = new List<Rule>
|
||||||
{
|
{
|
||||||
new UserLocationRule
|
new UserLocationRule
|
||||||
@ -54,6 +55,7 @@
|
|||||||
From = DateTime.Now.AddDays(-7),
|
From = DateTime.Now.AddDays(-7),
|
||||||
To = DateTime.Now.AddDays(14),
|
To = DateTime.Now.AddDays(14),
|
||||||
PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/campaigns/2/pic",
|
PictureUri = "http://externalcatalogbaseurltobereplaced/api/v1/campaigns/2/pic",
|
||||||
|
PictureName = "2.png",
|
||||||
Rules = new List<Rule>
|
Rules = new List<Rule>
|
||||||
{
|
{
|
||||||
new UserLocationRule
|
new UserLocationRule
|
||||||
|
@ -0,0 +1,121 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.MarketingMigrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(MarketingContext))]
|
||||||
|
[Migration("20170629102516_added-campaign-details")]
|
||||||
|
partial class addedcampaigndetails
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "1.1.2")
|
||||||
|
.HasAnnotation("SqlServer:Sequence:.campaign_hilo", "'campaign_hilo', '', '1', '10', '', '', 'Int64', 'False'")
|
||||||
|
.HasAnnotation("SqlServer:Sequence:.rule_hilo", "'rule_hilo', '', '1', '10', '', '', 'Int64', 'False'")
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Marketing.API.Model.Campaign", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:HiLoSequenceName", "campaign_hilo")
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnName("Description");
|
||||||
|
|
||||||
|
b.Property<string>("DetailsUri");
|
||||||
|
|
||||||
|
b.Property<DateTime>("From")
|
||||||
|
.HasColumnName("From");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnName("Name");
|
||||||
|
|
||||||
|
b.Property<string>("PictureName");
|
||||||
|
|
||||||
|
b.Property<string>("PictureUri")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnName("PictureUri");
|
||||||
|
|
||||||
|
b.Property<DateTime>("To")
|
||||||
|
.HasColumnName("To");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Campaign");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Marketing.API.Model.Rule", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("SqlServer:HiLoSequenceName", "rule_hilo")
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
|
||||||
|
|
||||||
|
b.Property<int>("CampaignId");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnName("Description");
|
||||||
|
|
||||||
|
b.Property<int>("RuleTypeId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CampaignId");
|
||||||
|
|
||||||
|
b.ToTable("Rule");
|
||||||
|
|
||||||
|
b.HasDiscriminator<int>("RuleTypeId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Marketing.API.Model.PurchaseHistoryRule", b =>
|
||||||
|
{
|
||||||
|
b.HasBaseType("Microsoft.eShopOnContainers.Services.Marketing.API.Model.Rule");
|
||||||
|
|
||||||
|
|
||||||
|
b.ToTable("PurchaseHistoryRule");
|
||||||
|
|
||||||
|
b.HasDiscriminator().HasValue(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Marketing.API.Model.UserLocationRule", b =>
|
||||||
|
{
|
||||||
|
b.HasBaseType("Microsoft.eShopOnContainers.Services.Marketing.API.Model.Rule");
|
||||||
|
|
||||||
|
b.Property<int>("LocationId")
|
||||||
|
.HasColumnName("LocationId");
|
||||||
|
|
||||||
|
b.ToTable("UserLocationRule");
|
||||||
|
|
||||||
|
b.HasDiscriminator().HasValue(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Marketing.API.Model.UserProfileRule", b =>
|
||||||
|
{
|
||||||
|
b.HasBaseType("Microsoft.eShopOnContainers.Services.Marketing.API.Model.Rule");
|
||||||
|
|
||||||
|
|
||||||
|
b.ToTable("UserProfileRule");
|
||||||
|
|
||||||
|
b.HasDiscriminator().HasValue(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Marketing.API.Model.Rule", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.eShopOnContainers.Services.Marketing.API.Model.Campaign", "Campaign")
|
||||||
|
.WithMany("Rules")
|
||||||
|
.HasForeignKey("CampaignId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.MarketingMigrations
|
||||||
|
{
|
||||||
|
public partial class addedcampaigndetails : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "DetailsUri",
|
||||||
|
table: "Campaign",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "PictureName",
|
||||||
|
table: "Campaign",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "DetailsUri",
|
||||||
|
table: "Campaign");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "PictureName",
|
||||||
|
table: "Campaign");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,8 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Mark
|
|||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnName("Description");
|
.HasColumnName("Description");
|
||||||
|
|
||||||
|
b.Property<string>("DetailsUri");
|
||||||
|
|
||||||
b.Property<DateTime>("From")
|
b.Property<DateTime>("From")
|
||||||
.HasColumnName("From");
|
.HasColumnName("From");
|
||||||
|
|
||||||
@ -36,6 +38,8 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Mark
|
|||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnName("Name");
|
.HasColumnName("Name");
|
||||||
|
|
||||||
|
b.Property<string>("PictureName");
|
||||||
|
|
||||||
b.Property<string>("PictureUri")
|
b.Property<string>("PictureUri")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnName("PictureUri");
|
.HasColumnName("PictureUri");
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services
|
|
||||||
{
|
{
|
||||||
public interface IIdentityService
|
public interface IIdentityService
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services
|
|
||||||
{
|
{
|
||||||
|
using AspNetCore.Http;
|
||||||
|
using System;
|
||||||
|
|
||||||
public class IdentityService : IIdentityService
|
public class IdentityService : IIdentityService
|
||||||
{
|
{
|
||||||
private IHttpContextAccessor _context;
|
private IHttpContextAccessor _context;
|
||||||
@ -20,4 +17,4 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Serv
|
|||||||
return _context.HttpContext.User.FindFirst("sub").Value;
|
return _context.HttpContext.User.FindFirst("sub").Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,13 +1,13 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Marketing.API.IntegrationEvents.Events
|
namespace Microsoft.eShopOnContainers.Services.Marketing.API.IntegrationEvents.Events
|
||||||
{
|
{
|
||||||
using Model;
|
using Marketing.API.Model;
|
||||||
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using BuildingBlocks.EventBus.Events;
|
|
||||||
|
|
||||||
public class UserLocationUpdatedIntegrationEvent : IntegrationEvent
|
public class UserLocationUpdatedIntegrationEvent : IntegrationEvent
|
||||||
{
|
{
|
||||||
public string UserId { get; private set; }
|
public string UserId { get; set; }
|
||||||
public List<UserLocationDetails> LocationList { get; private set; }
|
public List<UserLocationDetails> LocationList { get; set; }
|
||||||
|
|
||||||
public UserLocationUpdatedIntegrationEvent(string userId, List<UserLocationDetails> locationList)
|
public UserLocationUpdatedIntegrationEvent(string userId, List<UserLocationDetails> locationList)
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Marketing.API.IntegrationEvents.Handlers
|
namespace Microsoft.eShopOnContainers.Services.Marketing.API.IntegrationEvents.Handlers
|
||||||
{
|
{
|
||||||
using BuildingBlocks.EventBus.Abstractions;
|
using Marketing.API.IntegrationEvents.Events;
|
||||||
using System.Threading.Tasks;
|
using Marketing.API.Model;
|
||||||
using Events;
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Repositories;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Marketing.API.Model;
|
||||||
using System;
|
using System;
|
||||||
using Infrastructure.Repositories;
|
|
||||||
using Model;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public class UserLocationUpdatedIntegrationEventHandler
|
public class UserLocationUpdatedIntegrationEventHandler
|
||||||
: IIntegrationEventHandler<UserLocationUpdatedIntegrationEvent>
|
: IIntegrationEventHandler<UserLocationUpdatedIntegrationEvent>
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -6,5 +6,8 @@
|
|||||||
public string MongoConnectionString { get; set; }
|
public string MongoConnectionString { get; set; }
|
||||||
public string MongoDatabase { get; set; }
|
public string MongoDatabase { get; set; }
|
||||||
public string ExternalCatalogBaseUrl { get; set; }
|
public string ExternalCatalogBaseUrl { get; set; }
|
||||||
|
public string CampaignDetailFunctionUri { get; set; }
|
||||||
|
public string PicBaseUrl { get; set; }
|
||||||
|
public bool AzureStorageEnabled { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,12 @@
|
|||||||
|
|
||||||
public DateTime To { get; set; }
|
public DateTime To { get; set; }
|
||||||
|
|
||||||
|
public string PictureName { get; set; }
|
||||||
|
|
||||||
public string PictureUri { get; set; }
|
public string PictureUri { get; set; }
|
||||||
|
|
||||||
|
public string DetailsUri { get; set; }
|
||||||
|
|
||||||
public List<Rule> Rules { get; set; }
|
public List<Rule> Rules { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Marketing.API
|
namespace Microsoft.eShopOnContainers.Services.Marketing.API
|
||||||
{
|
{
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
|
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
|
@ -1,32 +1,34 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
namespace Microsoft.eShopOnContainers.Services.Marketing.API
|
||||||
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Services.Marketing.API
|
|
||||||
{
|
{
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System.Reflection;
|
|
||||||
using System;
|
|
||||||
using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Filters;
|
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
|
|
||||||
using RabbitMQ.Client;
|
|
||||||
using BuildingBlocks.EventBus.Abstractions;
|
|
||||||
using BuildingBlocks.EventBus;
|
|
||||||
using IntegrationEvents.Events;
|
|
||||||
using IntegrationEvents.Handlers;
|
|
||||||
using Infrastructure.Repositories;
|
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Autofac.Extensions.DependencyInjection;
|
using Autofac.Extensions.DependencyInjection;
|
||||||
|
using IntegrationEvents.Events;
|
||||||
|
using AspNetCore.Builder;
|
||||||
|
using AspNetCore.Hosting;
|
||||||
|
using AspNetCore.Http;
|
||||||
|
using Azure.ServiceBus;
|
||||||
|
using EntityFrameworkCore;
|
||||||
|
using EntityFrameworkCore.Infrastructure;
|
||||||
|
using BuildingBlocks.EventBus;
|
||||||
|
using BuildingBlocks.EventBus.Abstractions;
|
||||||
|
using BuildingBlocks.EventBusRabbitMQ;
|
||||||
|
using BuildingBlocks.EventBusServiceBus;
|
||||||
|
using Infrastructure;
|
||||||
|
using Infrastructure.Filters;
|
||||||
|
using Infrastructure.Repositories;
|
||||||
|
using Locations.API.Infrastructure.Services;
|
||||||
|
using Extensions.Configuration;
|
||||||
|
using Extensions.DependencyInjection;
|
||||||
|
using Extensions.Logging;
|
||||||
using Polly;
|
using Polly;
|
||||||
using System.Threading.Tasks;
|
using RabbitMQ.Client;
|
||||||
|
using System;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
using Microsoft.Extensions.HealthChecks;
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Extensions.HealthChecks;
|
||||||
|
using Marketing.API.IntegrationEvents.Handlers;
|
||||||
|
|
||||||
|
|
||||||
public class Startup
|
public class Startup
|
||||||
{
|
{
|
||||||
@ -82,19 +84,32 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API
|
|||||||
//Check Client vs. Server evaluation: https://docs.microsoft.com/en-us/ef/core/querying/client-eval
|
//Check Client vs. Server evaluation: https://docs.microsoft.com/en-us/ef/core/querying/client-eval
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
if (Configuration.GetValue<bool>("AzureServiceBusEnabled"))
|
||||||
{
|
{
|
||||||
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
services.AddSingleton<IServiceBusPersisterConnection>(sp =>
|
||||||
|
|
||||||
var factory = new ConnectionFactory()
|
|
||||||
{
|
{
|
||||||
HostName = Configuration["EventBusConnection"]
|
var logger = sp.GetRequiredService<ILogger<DefaultServiceBusPersisterConnection>>();
|
||||||
};
|
|
||||||
|
|
||||||
return new DefaultRabbitMQPersistentConnection(factory, logger);
|
var serviceBusConnectionString = Configuration["EventBusConnection"];
|
||||||
});
|
var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString);
|
||||||
|
|
||||||
RegisterServiceBus(services);
|
return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
||||||
|
{
|
||||||
|
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
||||||
|
|
||||||
|
var factory = new ConnectionFactory()
|
||||||
|
{
|
||||||
|
HostName = Configuration["EventBusConnection"]
|
||||||
|
};
|
||||||
|
|
||||||
|
return new DefaultRabbitMQPersistentConnection(factory, logger);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Add framework services.
|
// Add framework services.
|
||||||
services.AddSwaggerGen(options =>
|
services.AddSwaggerGen(options =>
|
||||||
@ -118,10 +133,14 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API
|
|||||||
.AllowCredentials());
|
.AllowCredentials());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RegisterEventBus(services);
|
||||||
|
|
||||||
services.AddTransient<IMarketingDataRepository, MarketingDataRepository>();
|
services.AddTransient<IMarketingDataRepository, MarketingDataRepository>();
|
||||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||||
services.AddTransient<IIdentityService, IdentityService>();
|
services.AddTransient<IIdentityService, IdentityService>();
|
||||||
|
|
||||||
|
services.AddOptions();
|
||||||
|
|
||||||
//configure autofac
|
//configure autofac
|
||||||
var container = new ContainerBuilder();
|
var container = new ContainerBuilder();
|
||||||
container.Populate(services);
|
container.Populate(services);
|
||||||
@ -145,7 +164,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API
|
|||||||
.UseSwaggerUI(c =>
|
.UseSwaggerUI(c =>
|
||||||
{
|
{
|
||||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
|
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
|
||||||
});
|
});
|
||||||
|
|
||||||
var context = (MarketingContext)app
|
var context = (MarketingContext)app
|
||||||
.ApplicationServices.GetService(typeof(MarketingContext));
|
.ApplicationServices.GetService(typeof(MarketingContext));
|
||||||
@ -166,21 +185,35 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterServiceBus(IServiceCollection services)
|
private void RegisterEventBus(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
if (Configuration.GetValue<bool>("AzureServiceBusEnabled"))
|
||||||
services.AddSingleton<IEventBusSubscriptionsManager,
|
{
|
||||||
InMemoryEventBusSubscriptionsManager>();
|
services.AddSingleton<IEventBus, EventBusServiceBus>(sp =>
|
||||||
|
{
|
||||||
|
var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
|
||||||
|
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>();
|
||||||
|
var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
|
||||||
|
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
|
||||||
|
var subscriptionClientName = Configuration["SubscriptionClientName"];
|
||||||
|
|
||||||
services.AddTransient<IIntegrationEventHandler<UserLocationUpdatedIntegrationEvent>,
|
return new EventBusServiceBus(serviceBusPersisterConnection, logger,
|
||||||
UserLocationUpdatedIntegrationEventHandler>();
|
eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
||||||
|
}
|
||||||
|
|
||||||
|
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
||||||
|
services.AddTransient<UserLocationUpdatedIntegrationEventHandler>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConfigureEventBus(IApplicationBuilder app)
|
private void ConfigureEventBus(IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
|
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
|
||||||
eventBus.Subscribe<UserLocationUpdatedIntegrationEvent,
|
eventBus.Subscribe<UserLocationUpdatedIntegrationEvent, UserLocationUpdatedIntegrationEventHandler>();
|
||||||
IIntegrationEventHandler<UserLocationUpdatedIntegrationEvent>>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task WaitForSqlAvailabilityAsync(MarketingContext ctx, ILoggerFactory loggerFactory, IApplicationBuilder app, int retries = 0)
|
private async Task WaitForSqlAvailabilityAsync(MarketingContext ctx, ILoggerFactory loggerFactory, IApplicationBuilder app, int retries = 0)
|
||||||
|
@ -9,5 +9,8 @@
|
|||||||
"MongoConnectionString": "mongodb://nosql.data",
|
"MongoConnectionString": "mongodb://nosql.data",
|
||||||
"MongoDatabase": "MarketingDb",
|
"MongoDatabase": "MarketingDb",
|
||||||
"IdentityUrl": "http://localhost:5105",
|
"IdentityUrl": "http://localhost:5105",
|
||||||
"ExternalCatalogBaseUrl": "http://localhost:5110"
|
"ExternalCatalogBaseUrl": "http://localhost:5110",
|
||||||
|
"AzureServiceBusEnabled": false,
|
||||||
|
"SubscriptionClientName": "Marketing",
|
||||||
|
"AzureStorageEnabled": false
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,8 @@
|
|||||||
using Autofac;
|
using Autofac;
|
||||||
using Autofac.Extensions.DependencyInjection;
|
using Autofac.Extensions.DependencyInjection;
|
||||||
using global::Ordering.API.Application.IntegrationEvents;
|
using global::Ordering.API.Application.IntegrationEvents;
|
||||||
using global::Ordering.API.Application.IntegrationEvents.EventHandling;
|
|
||||||
using global::Ordering.API.Application.IntegrationEvents.Events;
|
using global::Ordering.API.Application.IntegrationEvents.Events;
|
||||||
using global::Ordering.API.Infrastructure.Middlewares;
|
|
||||||
using Infrastructure;
|
using Infrastructure;
|
||||||
using Infrastructure.Auth;
|
|
||||||
using Infrastructure.AutofacModules;
|
using Infrastructure.AutofacModules;
|
||||||
using Infrastructure.Filters;
|
using Infrastructure.Filters;
|
||||||
using Infrastructure.Services;
|
using Infrastructure.Services;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" />
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" />
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj" />
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
|
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
|
||||||
|
@ -12,6 +12,8 @@ using RabbitMQ.Client;
|
|||||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
|
||||||
using Payment.API.IntegrationEvents.Events;
|
using Payment.API.IntegrationEvents.Events;
|
||||||
using Payment.API.IntegrationEvents.EventHandling;
|
using Payment.API.IntegrationEvents.EventHandling;
|
||||||
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus;
|
||||||
|
using Microsoft.Azure.ServiceBus;
|
||||||
|
|
||||||
namespace Payment.API
|
namespace Payment.API
|
||||||
{
|
{
|
||||||
@ -35,19 +37,34 @@ namespace Payment.API
|
|||||||
// Add framework services.
|
// Add framework services.
|
||||||
services.AddMvc();
|
services.AddMvc();
|
||||||
services.Configure<PaymentSettings>(Configuration);
|
services.Configure<PaymentSettings>(Configuration);
|
||||||
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
if (Configuration.GetValue<bool>("AzureServiceBusEnabled"))
|
||||||
{
|
{
|
||||||
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
services.AddSingleton<IServiceBusPersisterConnection>(sp =>
|
||||||
|
|
||||||
var factory = new ConnectionFactory()
|
|
||||||
{
|
{
|
||||||
HostName = Configuration["EventBusConnection"]
|
var logger = sp.GetRequiredService<ILogger<DefaultServiceBusPersisterConnection>>();
|
||||||
};
|
|
||||||
|
|
||||||
return new DefaultRabbitMQPersistentConnection(factory, logger);
|
var serviceBusConnectionString = Configuration["EventBusConnection"];
|
||||||
});
|
var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString);
|
||||||
|
|
||||||
RegisterServiceBus(services);
|
return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
||||||
|
{
|
||||||
|
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
||||||
|
|
||||||
|
var factory = new ConnectionFactory()
|
||||||
|
{
|
||||||
|
HostName = Configuration["EventBusConnection"]
|
||||||
|
};
|
||||||
|
|
||||||
|
return new DefaultRabbitMQPersistentConnection(factory, logger);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterEventBus(services);
|
||||||
|
|
||||||
services.AddSwaggerGen(options =>
|
services.AddSwaggerGen(options =>
|
||||||
{
|
{
|
||||||
@ -84,20 +101,35 @@ namespace Payment.API
|
|||||||
ConfigureEventBus(app);
|
ConfigureEventBus(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterServiceBus(IServiceCollection services)
|
private void RegisterEventBus(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
if (Configuration.GetValue<bool>("AzureServiceBusEnabled"))
|
||||||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
{
|
||||||
|
services.AddSingleton<IEventBus, EventBusServiceBus>(sp =>
|
||||||
|
{
|
||||||
|
var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
|
||||||
|
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>();
|
||||||
|
var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
|
||||||
|
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
|
||||||
|
var subscriptionClientName = Configuration["SubscriptionClientName"];
|
||||||
|
|
||||||
services.AddTransient<IIntegrationEventHandler<OrderStatusChangedToStockConfirmedIntegrationEvent>,
|
return new EventBusServiceBus(serviceBusPersisterConnection, logger,
|
||||||
OrderStatusChangedToStockConfirmedIntegrationEventHandler>();
|
eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
||||||
|
}
|
||||||
|
|
||||||
|
services.AddTransient<OrderStatusChangedToStockConfirmedIntegrationEventHandler>();
|
||||||
|
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConfigureEventBus(IApplicationBuilder app)
|
private void ConfigureEventBus(IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
|
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
|
||||||
eventBus.Subscribe<OrderStatusChangedToStockConfirmedIntegrationEvent,
|
eventBus.Subscribe<OrderStatusChangedToStockConfirmedIntegrationEvent, OrderStatusChangedToStockConfirmedIntegrationEventHandler>();
|
||||||
IIntegrationEventHandler<OrderStatusChangedToStockConfirmedIntegrationEvent>>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,5 +5,7 @@
|
|||||||
"Default": "Warning"
|
"Default": "Warning"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"PaymentSucceded": "true"
|
"PaymentSucceded": true,
|
||||||
|
"AzureServiceBusEnabled": false,
|
||||||
|
"SubscriptionClientName": "Payment"
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
|||||||
public string OrderingUrl { get; set; }
|
public string OrderingUrl { get; set; }
|
||||||
public string BasketUrl { get; set; }
|
public string BasketUrl { get; set; }
|
||||||
public string MarketingUrl { get; set; }
|
public string MarketingUrl { get; set; }
|
||||||
|
public bool ActivateCampaignDetailFunction { get; set; }
|
||||||
public Logging Logging { get; set; }
|
public Logging Logging { get; set; }
|
||||||
public bool UseCustomizationData { get; set; }
|
public bool UseCustomizationData { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -11,19 +11,29 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
|||||||
using System;
|
using System;
|
||||||
using ViewModels.Pagination;
|
using ViewModels.Pagination;
|
||||||
using global::WebMVC.ViewModels;
|
using global::WebMVC.ViewModels;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class CampaignsController : Controller
|
public class CampaignsController : Controller
|
||||||
{
|
{
|
||||||
private readonly ICampaignService _campaignService;
|
private readonly ICampaignService _campaignService;
|
||||||
|
private readonly AppSettings _settings;
|
||||||
|
|
||||||
public CampaignsController(ICampaignService campaignService) =>
|
public CampaignsController(ICampaignService campaignService, IOptionsSnapshot<AppSettings> settings)
|
||||||
|
{
|
||||||
_campaignService = campaignService;
|
_campaignService = campaignService;
|
||||||
|
_settings = settings.Value;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> Index(int page = 0, int pageSize = 10)
|
public async Task<IActionResult> Index(int page = 0, int pageSize = 10)
|
||||||
{
|
{
|
||||||
var campaignList = await _campaignService.GetCampaigns(pageSize, page);
|
var campaignList = await _campaignService.GetCampaigns(pageSize, page);
|
||||||
|
|
||||||
|
if(campaignList is null)
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
var totalPages = (int) Math.Ceiling((decimal) campaignList.Count / pageSize);
|
var totalPages = (int) Math.Ceiling((decimal) campaignList.Count / pageSize);
|
||||||
|
|
||||||
var vm = new CampaignViewModel
|
var vm = new CampaignViewModel
|
||||||
@ -40,6 +50,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ViewBag.IsCampaignDetailFunctionActive = _settings.ActivateCampaignDetailFunction;
|
||||||
|
|
||||||
return View(vm);
|
return View(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,5 +15,6 @@
|
|||||||
public DateTime To { get; set; }
|
public DateTime To { get; set; }
|
||||||
|
|
||||||
public string PictureUri { get; set; }
|
public string PictureUri { get; set; }
|
||||||
|
public string DetailsUri { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,10 +13,8 @@
|
|||||||
new Header() { Controller = "Catalog", Text = "Back to catalog" } })
|
new Header() { Controller = "Catalog", Text = "Back to catalog" } })
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@if (Model.CampaignItems != null && Model.CampaignItems.Any())
|
@if(Model != null && Model.CampaignItems.Any())
|
||||||
{
|
{
|
||||||
@Html.Partial("_pagination", Model.PaginationInfo)
|
|
||||||
|
|
||||||
<div class="card-group esh-campaigns-items row">
|
<div class="card-group esh-campaigns-items row">
|
||||||
@foreach (var catalogItem in Model.CampaignItems)
|
@foreach (var catalogItem in Model.CampaignItems)
|
||||||
{
|
{
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
@model CampaignItem
|
@model CampaignItem
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<form asp-controller="Campaigns" asp-action="Details" asp-route-id="@Model.Id">
|
<form asp-controller="Campaigns" asp-action="Details" asp-route-id="@Model.Id">
|
||||||
<div class="card-block">
|
<div class="card-block">
|
||||||
<h4 class="card-title esh-campaigns-name">@Model.Name</h4>
|
<h4 class="card-title esh-campaigns-name">@Model.Name</h4>
|
||||||
<img class="card-img-top esh-campaigns-thumbnail" src="@Model.PictureUri" alt="@Model.Name">
|
<img class="card-img-top esh-campaigns-thumbnail" src="@Model.PictureUri" alt="@Model.Name">
|
||||||
<input class="esh-campaigns-button" type="submit" value="More details">
|
@if (ViewBag.IsCampaignDetailFunctionActive == true)
|
||||||
|
{
|
||||||
|
<input type="button" value="More Details" class="btn esh-campaigns-button" onClick="window.open('@Model.DetailsUri')">
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<input class="esh-campaigns-button" type="submit" value="More details">
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
|
|
||||||
<small class="text-muted">
|
<small class="text-muted">
|
||||||
From @Model.From.ToString("MMMM dd, yyyy") until @Model.To.ToString("MMMM dd, yyyy")
|
From @Model.From.ToString("MMMM dd, yyyy") until @Model.To.ToString("MMMM dd, yyyy")
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
<section class="esh-orders-title col-xs-2">Status</section>
|
<section class="esh-orders-title col-xs-2">Status</section>
|
||||||
<section class="esh-orders-title col-xs-2"></section>
|
<section class="esh-orders-title col-xs-2"></section>
|
||||||
</article>
|
</article>
|
||||||
|
@if (Model != null && Model.Any())
|
||||||
|
{
|
||||||
@foreach (var item in Model)
|
@foreach (var item in Model)
|
||||||
{
|
{
|
||||||
<article class="esh-orders-items row">
|
<article class="esh-orders-items row">
|
||||||
@ -38,6 +39,7 @@
|
|||||||
</section>
|
</section>
|
||||||
</article>
|
</article>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
"CallBackUrl": "http://localhost:5100/",
|
"CallBackUrl": "http://localhost:5100/",
|
||||||
"IsClusterEnv": "False",
|
"IsClusterEnv": "False",
|
||||||
"UseResilientHttp": "True",
|
"UseResilientHttp": "True",
|
||||||
|
"ActivateCampaignDetailFunction": "True",
|
||||||
"UseCustomizationData": true,
|
"UseCustomizationData": true,
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"IncludeScopes": false,
|
"IncludeScopes": false,
|
||||||
|
@ -13,6 +13,7 @@ namespace eShopOnContainers.WebSPA
|
|||||||
public string IdentityUrl { get; set; }
|
public string IdentityUrl { get; set; }
|
||||||
public string BasketUrl { get; set; }
|
public string BasketUrl { get; set; }
|
||||||
public string MarketingUrl { get; set; }
|
public string MarketingUrl { get; set; }
|
||||||
|
public string ActivateCampaignDetailFunction { get; set; }
|
||||||
public bool UseCustomizationData { get; set; }
|
public bool UseCustomizationData { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
<esh-header url="/catalog">Back to catalog</esh-header>
|
<esh-header url="/catalog">Back to catalog</esh-header>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div *ngIf="campaigns?.data?.length > 0">
|
<div *ngIf="campaigns?.data?.length > 0">
|
||||||
<esh-pager [model]="paginationInfo" (changed)="onPageChanged($event)"></esh-pager>
|
<esh-pager [model]="paginationInfo" (changed)="onPageChanged($event)"></esh-pager>
|
||||||
|
|
||||||
<div class="card-group esh-campaign-items row">
|
<div class="card-group esh-campaign-items row">
|
||||||
<div class="esh-campaign-item col-md-4"
|
<div class="esh-campaign-item col-md-4"
|
||||||
*ngFor="let item of campaigns.data">
|
*ngFor="let item of campaigns.data">
|
||||||
@ -10,10 +9,12 @@
|
|||||||
<div class="card-block">
|
<div class="card-block">
|
||||||
<h4 class="card-title esh-campaign-name">{{item.name}}</h4>
|
<h4 class="card-title esh-campaign-name">{{item.name}}</h4>
|
||||||
<img class="card-img-top esh-campaign-thumbnail" src="{{item.pictureUri}}" alt="{{item.name}}">
|
<img class="card-img-top esh-campaign-thumbnail" src="{{item.pictureUri}}" alt="{{item.name}}">
|
||||||
<input [ngClass]="{'esh-campaign-button': true}" type="submit" value="More details" routerLink="/campaigns/{{item.id}}">
|
<button *ngIf="isCampaignDetailFunctionEnabled; else showDefaultDetailsLink" [ngClass]="{'esh-campaigns-button': true}" (click)="onNavigateToDetails(item.detailsUri)">More details</button>
|
||||||
|
<ng-template #showDefaultDetailsLink>
|
||||||
|
<input [ngClass]="{'esh-campaign-button': true}" type="submit" value="More details" routerLink="/campaigns/{{item.id}}">
|
||||||
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
|
|
||||||
<small class="text-muted">
|
<small class="text-muted">
|
||||||
From {{item.from | date }} To {{item.to | date }}
|
From {{item.from | date }} To {{item.to | date }}
|
||||||
</small>
|
</small>
|
||||||
|
@ -13,6 +13,7 @@ export class CampaignsComponent implements OnInit {
|
|||||||
private interval = null;
|
private interval = null;
|
||||||
paginationInfo: IPager;
|
paginationInfo: IPager;
|
||||||
campaigns: ICampaign;
|
campaigns: ICampaign;
|
||||||
|
isCampaignDetailFunctionEnabled: boolean = false;
|
||||||
|
|
||||||
constructor(private service: CampaignsService, private configurationService: ConfigurationService) { }
|
constructor(private service: CampaignsService, private configurationService: ConfigurationService) { }
|
||||||
|
|
||||||
@ -23,7 +24,9 @@ export class CampaignsComponent implements OnInit {
|
|||||||
this.configurationService.settingsLoaded$.subscribe(x => {
|
this.configurationService.settingsLoaded$.subscribe(x => {
|
||||||
this.getCampaigns(9, 0);
|
this.getCampaigns(9, 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.isCampaignDetailFunctionEnabled = this.configurationService.serverSettings.activateCampaignDetailFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
onPageChanged(value: any) {
|
onPageChanged(value: any) {
|
||||||
@ -45,5 +48,9 @@ export class CampaignsComponent implements OnInit {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onNavigateToDetails(uri: string) {
|
||||||
|
window.open(uri, "_blank");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,4 +5,5 @@
|
|||||||
from: Date;
|
from: Date;
|
||||||
to: Date;
|
to: Date;
|
||||||
pictureUri: string;
|
pictureUri: string;
|
||||||
|
detailsUri: string;
|
||||||
}
|
}
|
@ -3,5 +3,6 @@ export interface IConfiguration {
|
|||||||
orderingUrl: string,
|
orderingUrl: string,
|
||||||
identityUrl: string,
|
identityUrl: string,
|
||||||
basketUrl: string,
|
basketUrl: string,
|
||||||
marketingUrl: string
|
marketingUrl: string,
|
||||||
|
activateCampaignDetailFunction: boolean
|
||||||
}
|
}
|
@ -33,6 +33,7 @@ export class ConfigurationService {
|
|||||||
this.storageService.store('identityUrl', this.serverSettings.identityUrl);
|
this.storageService.store('identityUrl', this.serverSettings.identityUrl);
|
||||||
this.storageService.store('orderingUrl', this.serverSettings.orderingUrl);
|
this.storageService.store('orderingUrl', this.serverSettings.orderingUrl);
|
||||||
this.storageService.store('marketingUrl', this.serverSettings.marketingUrl);
|
this.storageService.store('marketingUrl', this.serverSettings.marketingUrl);
|
||||||
|
this.storageService.store('activateCampaignDetailFunction', this.serverSettings.activateCampaignDetailFunction);
|
||||||
this.isReady = true;
|
this.isReady = true;
|
||||||
this.settingsLoadedSource.next();
|
this.settingsLoadedSource.next();
|
||||||
});
|
});
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
"CallBackUrl": "http://localhost:5104/",
|
"CallBackUrl": "http://localhost:5104/",
|
||||||
"UseCustomizationData": true,
|
"UseCustomizationData": true,
|
||||||
"IsClusterEnv": "False",
|
"IsClusterEnv": "False",
|
||||||
|
"ActivateCampaignDetailFunction": true,
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"IncludeScopes": false,
|
"IncludeScopes": false,
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
var responseBody = await userLocationCampaignResponse.Content.ReadAsStringAsync();
|
var responseBody = await userLocationCampaignResponse.Content.ReadAsStringAsync();
|
||||||
var userLocationCampaigns = JsonConvert.DeserializeObject<PaginatedItemsViewModel<CampaignDTO>>(responseBody);
|
var userLocationCampaigns = JsonConvert.DeserializeObject<PaginatedItemsViewModel<CampaignDTO>>(responseBody);
|
||||||
|
|
||||||
Assert.True(userLocationCampaigns.Data != null);
|
Assert.True(userLocationCampaigns.Count > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,7 @@
|
|||||||
"MongoDatabase": "MarketingDb",
|
"MongoDatabase": "MarketingDb",
|
||||||
"IdentityUrl": "http://localhost:5105",
|
"IdentityUrl": "http://localhost:5105",
|
||||||
"isTest": "true",
|
"isTest": "true",
|
||||||
"EventBusConnection": "localhost"
|
"EventBusConnection": "localhost",
|
||||||
|
"AzureServiceBusEnabled": false,
|
||||||
|
"SubscriptionClientName": "Marketing"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user