@ -0,0 +1,9 @@ | |||
<?xml version="1.0" encoding="utf-8" ?> | |||
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric"> | |||
<!-- Add your custom configuration sections and parameters here --> | |||
<!-- | |||
<Section Name="MyConfigSection"> | |||
<Parameter Name="MyParameter" Value="Value1" /> | |||
</Section> | |||
--> | |||
</Settings> |
@ -0,0 +1,48 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<ServiceManifest Name="OrderingBackgroundPkg" | |||
Version="1.0.0" | |||
xmlns="http://schemas.microsoft.com/2011/01/fabric" | |||
xmlns:xsd="http://www.w3.org/2001/XMLSchema" | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |||
<ServiceTypes> | |||
<!-- This is the name of your ServiceType. | |||
The UseImplicitHost attribute indicates this is a guest service. --> | |||
<StatelessServiceType ServiceTypeName="OrderingBackgroundType" UseImplicitHost="true" /> | |||
</ServiceTypes> | |||
<!-- Code package is your service executable. --> | |||
<CodePackage Name="Code" Version="1.0.0"> | |||
<EntryPoint> | |||
<!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers --> | |||
<ContainerHost> | |||
<ImageName>eshop/ordering.backgroundtasks</ImageName> | |||
</ContainerHost> | |||
</EntryPoint> | |||
<!-- Pass environment variables to your container: --> | |||
<EnvironmentVariables> | |||
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="Development"/> | |||
<EnvironmentVariable Name="ASPNETCORE_URLS" Value="http://0.0.0.0:80"/> | |||
<EnvironmentVariable Name="ConnectionString" Value="Data Source=sqlserver.eshoponservicefabricsql,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word"/> | |||
<EnvironmentVariable Name="EventBusConnection" Value="rabbitmq.eshoponservicefabricbus"/> | |||
<EnvironmentVariable Name="AzureServiceBusEnabled" Value="False"/> | |||
<EnvironmentVariable Name="GracePeriodTime" Value="1"/> | |||
<EnvironmentVariable Name="CheckUpdateTime" Value="30000"/> | |||
<EnvironmentVariable Name="ApplicationInsights__InstrumentationKey" Value=""/> | |||
<EnvironmentVariable Name="OrchestratorType" Value="SF"/> | |||
<EnvironmentVariable Name="UseLoadTest" Value="True"/> | |||
</EnvironmentVariables> | |||
</CodePackage> | |||
<!-- Config package is the contents of the Config directoy under PackageRoot that contains an | |||
independently-updateable and versioned set of custom configuration settings for your service. --> | |||
<ConfigPackage Name="Config" Version="1.0.0" /> | |||
<Resources> | |||
<Endpoints> | |||
<!-- This endpoint is used by the communication listener to obtain the port on which to | |||
listen. Please note that if your service is partitioned, this port is shared with | |||
replicas of different partitions that are placed in your code. --> | |||
<Endpoint Name="OrderingBackgroundTypeEndpoint" Port="5111" UriScheme="http"/> | |||
</Endpoints> | |||
</Resources> | |||
</ServiceManifest> |
@ -0,0 +1,9 @@ | |||
<?xml version="1.0" encoding="utf-8" ?> | |||
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric"> | |||
<!-- Add your custom configuration sections and parameters here --> | |||
<!-- | |||
<Section Name="MyConfigSection"> | |||
<Parameter Name="MyParameter" Value="Value1" /> | |||
</Section> | |||
--> | |||
</Settings> |
@ -0,0 +1,50 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<ServiceManifest Name="OrderingBackgroundPkg" | |||
Version="1.0.0" | |||
xmlns="http://schemas.microsoft.com/2011/01/fabric" | |||
xmlns:xsd="http://www.w3.org/2001/XMLSchema" | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |||
<ServiceTypes> | |||
<!-- This is the name of your ServiceType. | |||
The UseImplicitHost attribute indicates this is a guest service. --> | |||
<StatelessServiceType ServiceTypeName="OrderingBackgroundType" UseImplicitHost="true" /> | |||
</ServiceTypes> | |||
<!-- Code package is your service executable. --> | |||
<CodePackage Name="Code" Version="1.0.0"> | |||
<EntryPoint> | |||
<!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers --> | |||
<ContainerHost> | |||
<ImageName>eshop/ordering.backgroundtasks-win</ImageName> | |||
</ContainerHost> | |||
</EntryPoint> | |||
<!-- Pass environment variables to your container: --> | |||
<EnvironmentVariables> | |||
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="Development"/> | |||
<EnvironmentVariable Name="ASPNETCORE_URLS" Value="http://0.0.0.0:80"/> | |||
<EnvironmentVariable Name="ConnectionString" Value="Data Source=sqlserver.eshoponservicefabricsql,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word"/> | |||
<EnvironmentVariable Name="EventBusConnection" Value="rabbitmq.eshoponservicefabricbus"/> | |||
<EnvironmentVariable Name="AzureServiceBusEnabled" Value="False"/> | |||
<EnvironmentVariable Name="GracePeriodTime" Value="1"/> | |||
<EnvironmentVariable Name="CheckUpdateTime" Value="30000"/> | |||
<EnvironmentVariable Name="EventBusUserName" Value="admin"/> | |||
<EnvironmentVariable Name="EventBusPassword" Value="password"/> | |||
<EnvironmentVariable Name="ApplicationInsights:InstrumentationKey" Value=""/> | |||
<EnvironmentVariable Name="OrchestratorType" Value="SF"/> | |||
<EnvironmentVariable Name="UseLoadTest" Value="False"/> | |||
</EnvironmentVariables> | |||
</CodePackage> | |||
<!-- Config package is the contents of the Config directoy under PackageRoot that contains an | |||
independently-updateable and versioned set of custom configuration settings for your service. --> | |||
<ConfigPackage Name="Config" Version="1.0.0" /> | |||
<Resources> | |||
<Endpoints> | |||
<!-- This endpoint is used by the communication listener to obtain the port on which to | |||
listen. Please note that if your service is partitioned, this port is shared with | |||
replicas of different partitions that are placed in your code. --> | |||
<Endpoint Name="OrderingBackgroundTasksTypeEndpoint" Port="5111" UriScheme="http" PathSuffix="eShopOnServiceFabric/OrderingBackgroundTasks"/> | |||
</Endpoints> | |||
</Resources> | |||
</ServiceManifest> |
@ -0,0 +1,13 @@ | |||
| |||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||
# Visual Studio 15 | |||
VisualStudioVersion = 15.0.27323.2 | |||
MinimumVisualStudioVersion = 10.0.40219.1 | |||
Global | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
EndGlobalSection | |||
GlobalSection(ExtensibilityGlobals) = postSolution | |||
SolutionGuid = {04B6E659-060F-4550-A5CA-70B9E9D8F010} | |||
EndGlobalSection | |||
EndGlobal |
@ -0,0 +1,3 @@ | |||
kubectl patch deployment -n ingress-nginx nginx-ingress-controller --type=json --patch="$(cat nginx-ingress\publish-service-patch.yaml)" | |||
kubectl apply -f nginx-ingress\azure\service.yaml | |||
kubectl apply -f nginx-ingress\patch-service-without-rbac.yaml |
@ -0,0 +1,12 @@ | |||
kubectl apply -f ingress.yaml | |||
# Deploy nginx-ingress core files | |||
kubectl apply -f nginx-ingress\namespace.yaml | |||
kubectl apply -f nginx-ingress\default-backend.yaml | |||
kubectl apply -f nginx-ingress\configmap.yaml | |||
kubectl apply -f nginx-ingress\tcp-services-configmap.yaml | |||
kubectl apply -f nginx-ingress\udp-services-configmap.yaml | |||
kubectl apply -f nginx-ingress\without-rbac.yaml | |||
@ -0,0 +1,55 @@ | |||
apiVersion: extensions/v1beta1 | |||
kind: Ingress | |||
metadata: | |||
labels: | |||
app: eshop | |||
component: frontend | |||
name: eshop-ingress | |||
annotations: | |||
ingress.kubernetes.io/ssl-redirect: "false" | |||
spec: | |||
rules: | |||
- http: | |||
paths: | |||
- path: /basket-api | |||
backend: | |||
serviceName: basket | |||
servicePort: 80 | |||
- path: /catalog-api | |||
backend: | |||
serviceName: catalog | |||
servicePort: 80 | |||
- path: /identity | |||
backend: | |||
serviceName: identity | |||
servicePort: 80 | |||
- path: /ordering-api | |||
backend: | |||
serviceName: ordering | |||
servicePort: 80 | |||
- path: /webmvc | |||
backend: | |||
serviceName: webmvc | |||
servicePort: 80 | |||
- path: /webstatus | |||
backend: | |||
serviceName: webstatus | |||
servicePort: 80 | |||
- path: /marketing-api | |||
backend: | |||
serviceName: marketing | |||
servicePort: 80 | |||
- path: /payment-api | |||
backend: | |||
serviceName: payment | |||
servicePort: 80 | |||
- path: /locations-api | |||
backend: | |||
serviceName: locations | |||
servicePort: 80 | |||
- path: / | |||
backend: | |||
serviceName: webspa | |||
servicePort: 80 | |||
@ -0,0 +1,19 @@ | |||
kind: Service | |||
apiVersion: v1 | |||
metadata: | |||
name: ingress-nginx | |||
namespace: ingress-nginx | |||
labels: | |||
app: ingress-nginx | |||
spec: | |||
externalTrafficPolicy: Local | |||
type: LoadBalancer | |||
selector: | |||
app: ingress-nginx | |||
ports: | |||
- name: http | |||
port: 80 | |||
targetPort: http | |||
- name: https | |||
port: 443 | |||
targetPort: https |
@ -0,0 +1,11 @@ | |||
kind: ConfigMap | |||
apiVersion: v1 | |||
metadata: | |||
name: nginx-configuration | |||
namespace: ingress-nginx | |||
labels: | |||
app: ingress-nginx | |||
data: | |||
ssl-redirect: "false" | |||
proxy-buffer-size: "128k" | |||
proxy-buffers: "4 256k" |
@ -0,0 +1,52 @@ | |||
apiVersion: extensions/v1beta1 | |||
kind: Deployment | |||
metadata: | |||
name: default-http-backend | |||
labels: | |||
app: default-http-backend | |||
namespace: ingress-nginx | |||
spec: | |||
replicas: 1 | |||
template: | |||
metadata: | |||
labels: | |||
app: default-http-backend | |||
spec: | |||
terminationGracePeriodSeconds: 60 | |||
containers: | |||
- name: default-http-backend | |||
# Any image is permissable as long as: | |||
# 1. It serves a 404 page at / | |||
# 2. It serves 200 on a /healthz endpoint | |||
image: gcr.io/google_containers/defaultbackend:1.4 | |||
livenessProbe: | |||
httpGet: | |||
path: /healthz | |||
port: 8080 | |||
scheme: HTTP | |||
initialDelaySeconds: 30 | |||
timeoutSeconds: 5 | |||
ports: | |||
- containerPort: 8080 | |||
resources: | |||
limits: | |||
cpu: 10m | |||
memory: 20Mi | |||
requests: | |||
cpu: 10m | |||
memory: 20Mi | |||
--- | |||
apiVersion: v1 | |||
kind: Service | |||
metadata: | |||
name: default-http-backend | |||
namespace: ingress-nginx | |||
labels: | |||
app: default-http-backend | |||
spec: | |||
ports: | |||
- port: 80 | |||
targetPort: 8080 | |||
selector: | |||
app: default-http-backend |
@ -0,0 +1,4 @@ | |||
apiVersion: v1 | |||
kind: Namespace | |||
metadata: | |||
name: ingress-nginx |
@ -0,0 +1,40 @@ | |||
apiVersion: extensions/v1beta1 | |||
kind: Deployment | |||
metadata: | |||
name: nginx-ingress-controller | |||
namespace: ingress-nginx | |||
spec: | |||
replicas: 1 | |||
selector: | |||
matchLabels: | |||
app: ingress-nginx | |||
template: | |||
metadata: | |||
labels: | |||
app: ingress-nginx | |||
spec: | |||
containers: | |||
- name: nginx-ingress-controller | |||
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.9.0 | |||
args: | |||
- /nginx-ingress-controller | |||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend | |||
- --configmap=$(POD_NAMESPACE)/nginx-configuration | |||
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services | |||
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services | |||
- --publish-service=$(POD_NAMESPACE)/ingress-nginx | |||
- --annotations-prefix=nginx.ingress.kubernetes.io | |||
env: | |||
- name: POD_NAME | |||
valueFrom: | |||
fieldRef: | |||
fieldPath: metadata.name | |||
- name: POD_NAMESPACE | |||
valueFrom: | |||
fieldRef: | |||
fieldPath: metadata.namespace | |||
ports: | |||
- name: http | |||
containerPort: 80 | |||
- name: https | |||
containerPort: 443 |
@ -0,0 +1,7 @@ | |||
[ | |||
{ | |||
'op': 'add', | |||
'path': '/spec/template/spec/containers/0/args/-', | |||
'value': '--publish-service=$(POD_NAMESPACE)/ingress-nginx' | |||
} | |||
] |
@ -0,0 +1,5 @@ | |||
kind: ConfigMap | |||
apiVersion: v1 | |||
metadata: | |||
name: tcp-services | |||
namespace: ingress-nginx |
@ -0,0 +1,5 @@ | |||
kind: ConfigMap | |||
apiVersion: v1 | |||
metadata: | |||
name: udp-services | |||
namespace: ingress-nginx |
@ -0,0 +1,61 @@ | |||
apiVersion: extensions/v1beta1 | |||
kind: Deployment | |||
metadata: | |||
name: nginx-ingress-controller | |||
namespace: ingress-nginx | |||
spec: | |||
replicas: 1 | |||
selector: | |||
matchLabels: | |||
app: ingress-nginx | |||
template: | |||
metadata: | |||
labels: | |||
app: ingress-nginx | |||
annotations: | |||
prometheus.io/port: '10254' | |||
prometheus.io/scrape: 'true' | |||
spec: | |||
containers: | |||
- name: nginx-ingress-controller | |||
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.9.0 | |||
args: | |||
- /nginx-ingress-controller | |||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend | |||
- --configmap=$(POD_NAMESPACE)/nginx-configuration | |||
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services | |||
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services | |||
- --annotations-prefix=nginx.ingress.kubernetes.io | |||
env: | |||
- name: POD_NAME | |||
valueFrom: | |||
fieldRef: | |||
fieldPath: metadata.name | |||
- name: POD_NAMESPACE | |||
valueFrom: | |||
fieldRef: | |||
fieldPath: metadata.namespace | |||
ports: | |||
- name: http | |||
containerPort: 80 | |||
- name: https | |||
containerPort: 443 | |||
livenessProbe: | |||
failureThreshold: 3 | |||
httpGet: | |||
path: /healthz | |||
port: 10254 | |||
scheme: HTTP | |||
initialDelaySeconds: 10 | |||
periodSeconds: 10 | |||
successThreshold: 1 | |||
timeoutSeconds: 1 | |||
readinessProbe: | |||
failureThreshold: 3 | |||
httpGet: | |||
path: /healthz | |||
port: 10254 | |||
scheme: HTTP | |||
periodSeconds: 10 | |||
successThreshold: 1 | |||
timeoutSeconds: 1 |
@ -1,98 +0,0 @@ | |||
pid /tmp/nginx.pid; | |||
worker_processes 1; | |||
events { | |||
worker_connections 1024; | |||
} | |||
http { | |||
server_tokens off; | |||
add_header X-Frame-Options SAMEORIGIN; | |||
add_header X-Content-Type-Options nosniff; | |||
add_header X-XSS-Protection "1; mode=block"; | |||
client_body_temp_path /tmp/client_body; | |||
fastcgi_temp_path /tmp/fastcgi_temp; | |||
proxy_temp_path /tmp/proxy_temp; | |||
scgi_temp_path /tmp/scgi_temp; | |||
uwsgi_temp_path /tmp/uwsgi_temp; | |||
gzip on; | |||
gzip_comp_level 6; | |||
gzip_min_length 1024; | |||
gzip_buffers 4 32k; | |||
gzip_types text/plain application/javascript text/css; | |||
gzip_vary on; | |||
keepalive_timeout 65; | |||
proxy_buffer_size 128k; | |||
proxy_buffers 4 256k; | |||
proxy_busy_buffers_size 256k; | |||
server { | |||
listen 8080; | |||
location /basket-api { | |||
proxy_pass http://basket; | |||
proxy_redirect off; | |||
proxy_set_header Host $host; | |||
} | |||
location /catalog-api { | |||
proxy_pass http://catalog; | |||
proxy_redirect off; | |||
proxy_set_header Host $host; | |||
} | |||
location /identity { | |||
proxy_pass http://identity; | |||
proxy_redirect off; | |||
proxy_set_header Host $host; | |||
} | |||
location /ordering-api { | |||
proxy_pass http://ordering; | |||
proxy_redirect off; | |||
proxy_set_header Host $host; | |||
} | |||
location /webmvc { | |||
proxy_pass http://webmvc; | |||
proxy_redirect off; | |||
proxy_set_header Host $host; | |||
} | |||
location /webstatus { | |||
proxy_pass http://webstatus; | |||
proxy_redirect off; | |||
proxy_set_header Host $host; | |||
} | |||
location /marketing-api { | |||
proxy_pass http://marketing; | |||
proxy_redirect off; | |||
proxy_set_header Host $host; | |||
} | |||
location /payment-api { | |||
proxy_pass http://payment; | |||
proxy_redirect off; | |||
proxy_set_header Host $host; | |||
} | |||
location /locations-api { | |||
proxy_pass http://locations; | |||
proxy_redirect off; | |||
proxy_set_header Host $host; | |||
} | |||
location / { | |||
proxy_pass http://webspa; | |||
proxy_redirect off; | |||
proxy_set_header Host $host; | |||
} | |||
} | |||
} |
@ -1,7 +0,0 @@ | |||
@{ | |||
ViewData["Title"] = "About"; | |||
} | |||
<h2>@ViewData["Title"].</h2> | |||
<h3>@ViewData["Message"]</h3> | |||
<p>Use this area to provide additional information.</p> |
@ -1,17 +0,0 @@ | |||
@{ | |||
ViewData["Title"] = "Contact"; | |||
} | |||
<h2>@ViewData["Title"].</h2> | |||
<h3>@ViewData["Message"]</h3> | |||
<address> | |||
One Microsoft Way<br /> | |||
Redmond, WA 98052-6399<br /> | |||
<abbr title="Phone">P:</abbr> | |||
425.555.0100 | |||
</address> | |||
<address> | |||
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br /> | |||
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a> | |||
</address> |
@ -0,0 +1,13 @@ | |||
namespace Ordering.BackgroundTasks.Configuration | |||
{ | |||
public class BackgroundTaskSettings | |||
{ | |||
public string ConnectionString { get; set; } | |||
public string EventBusConnection { get; set; } | |||
public int GracePeriodTime { get; set; } | |||
public int CheckUpdateTime { get; set; } | |||
} | |||
} |
@ -0,0 +1,18 @@ | |||
FROM microsoft/aspnetcore:2.0.3 AS base | |||
WORKDIR /app | |||
EXPOSE 80 | |||
FROM microsoft/aspnetcore-build:2.0 AS build | |||
WORKDIR /src | |||
COPY . . | |||
RUN dotnet restore -nowarn:msb3202,nu1503 | |||
WORKDIR /src/src/Services/Ordering/Ordering.BackgroundTasks | |||
RUN dotnet build --no-restore -c Release -o /app | |||
FROM build AS publish | |||
RUN dotnet publish --no-restore -c Release -o /app | |||
FROM base AS final | |||
WORKDIR /app | |||
COPY --from=publish /app . | |||
ENTRYPOINT ["dotnet", "Ordering.BackgroundTasks.dll"] |
@ -0,0 +1,12 @@ | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | |||
namespace Ordering.BackgroundTasks.IntegrationEvents | |||
{ | |||
public class GracePeriodConfirmedIntegrationEvent : IntegrationEvent | |||
{ | |||
public int OrderId { get; } | |||
public GracePeriodConfirmedIntegrationEvent(int orderId) => | |||
OrderId = orderId; | |||
} | |||
} |
@ -0,0 +1,32 @@ | |||
<Project Sdk="Microsoft.NET.Sdk.Web"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.0</TargetFramework> | |||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> | |||
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Folder Include="wwwroot\" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.0" /> | |||
<PackageReference Include="Dapper" Version="1.50.4" /> | |||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.3" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" /> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.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.Extensions.HealthChecks.SqlServer\Microsoft.Extensions.HealthChecks.SqlServer.csproj" /> | |||
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@ -0,0 +1,25 @@ | |||
using Microsoft.AspNetCore; | |||
using Microsoft.AspNetCore.Hosting; | |||
using Microsoft.Extensions.Logging; | |||
namespace Ordering.BackgroundTasks | |||
{ | |||
public class Program | |||
{ | |||
public static void Main(string[] args) | |||
{ | |||
BuildWebHost(args).Run(); | |||
} | |||
public static IWebHost BuildWebHost(string[] args) => | |||
WebHost.CreateDefaultBuilder(args) | |||
.UseStartup<Startup>() | |||
.UseHealthChecks("/hc") | |||
.ConfigureLogging((hostingContext, builder) => | |||
{ | |||
builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); | |||
builder.AddDebug(); | |||
builder.AddConsole(); | |||
}).Build(); | |||
} | |||
} |
@ -0,0 +1,29 @@ | |||
{ | |||
"iisSettings": { | |||
"windowsAuthentication": false, | |||
"anonymousAuthentication": true, | |||
"iisExpress": { | |||
"applicationUrl": "http://localhost:5161/", | |||
"sslPort": 0 | |||
} | |||
}, | |||
"profiles": { | |||
"IIS Express": { | |||
"commandName": "IISExpress", | |||
"launchBrowser": true, | |||
"launchUrl": "api/values", | |||
"environmentVariables": { | |||
"ASPNETCORE_ENVIRONMENT": "Development" | |||
} | |||
}, | |||
"Ordering.BackgroundTasks": { | |||
"commandName": "Project", | |||
"launchBrowser": true, | |||
"launchUrl": "api/values", | |||
"environmentVariables": { | |||
"ASPNETCORE_ENVIRONMENT": "Development" | |||
}, | |||
"applicationUrl": "http://localhost:5162/" | |||
} | |||
} | |||
} |
@ -0,0 +1,161 @@ | |||
using Autofac; | |||
using Autofac.Extensions.DependencyInjection; | |||
using Microsoft.AspNetCore.Builder; | |||
using Microsoft.AspNetCore.Hosting; | |||
using Microsoft.Azure.ServiceBus; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; | |||
using Microsoft.Extensions.Configuration; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.HealthChecks; | |||
using Microsoft.Extensions.Hosting; | |||
using Microsoft.Extensions.Logging; | |||
using Ordering.BackgroundTasks.Configuration; | |||
using Ordering.BackgroundTasks.Tasks; | |||
using RabbitMQ.Client; | |||
using System; | |||
namespace Ordering.BackgroundTasks | |||
{ | |||
public class Startup | |||
{ | |||
public Startup(IConfiguration configuration) | |||
{ | |||
Configuration = configuration; | |||
} | |||
public IConfiguration Configuration { get; } | |||
// This method gets called by the runtime. Use this method to add services to the container. | |||
public IServiceProvider ConfigureServices(IServiceCollection services) | |||
{ | |||
//add health check for this service | |||
services.AddHealthChecks(checks => | |||
{ | |||
var minutes = 1; | |||
if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed)) | |||
{ | |||
minutes = minutesParsed; | |||
} | |||
checks.AddSqlCheck("OrderingDb", Configuration["ConnectionString"], TimeSpan.FromMinutes(minutes)); | |||
}); | |||
//configure settings | |||
services.Configure<BackgroundTaskSettings>(Configuration); | |||
services.AddOptions(); | |||
//configure background task | |||
services.AddSingleton<IHostedService, GracePeriodManagerService>(); | |||
//configure event bus related services | |||
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"] | |||
}; | |||
if (!string.IsNullOrEmpty(Configuration["EventBusUserName"])) | |||
{ | |||
factory.UserName = Configuration["EventBusUserName"]; | |||
} | |||
if (!string.IsNullOrEmpty(Configuration["EventBusPassword"])) | |||
{ | |||
factory.Password = Configuration["EventBusPassword"]; | |||
} | |||
var retryCount = 5; | |||
if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) | |||
{ | |||
retryCount = int.Parse(Configuration["EventBusRetryCount"]); | |||
} | |||
return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); | |||
}); | |||
} | |||
RegisterEventBus(services); | |||
//create autofac based service provider | |||
var container = new ContainerBuilder(); | |||
container.Populate(services); | |||
return new AutofacServiceProvider(container.Build()); | |||
} | |||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |||
public void Configure(IApplicationBuilder app, IHostingEnvironment env) | |||
{ | |||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously | |||
app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200)); | |||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously | |||
} | |||
private void RegisterEventBus(IServiceCollection services) | |||
{ | |||
var subscriptionClientName = Configuration["SubscriptionClientName"]; | |||
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>(); | |||
return new EventBusServiceBus(serviceBusPersisterConnection, logger, | |||
eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); | |||
}); | |||
} | |||
else | |||
{ | |||
services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp => | |||
{ | |||
var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>(); | |||
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>(); | |||
var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>(); | |||
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>(); | |||
var retryCount = 5; | |||
if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) | |||
{ | |||
retryCount = int.Parse(Configuration["EventBusRetryCount"]); | |||
} | |||
return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); | |||
}); | |||
} | |||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>(); | |||
} | |||
} | |||
} |
@ -0,0 +1,10 @@ | |||
{ | |||
"Logging": { | |||
"IncludeScopes": false, | |||
"LogLevel": { | |||
"Default": "Debug", | |||
"System": "Information", | |||
"Microsoft": "Information" | |||
} | |||
} | |||
} |
@ -0,0 +1,27 @@ | |||
{ | |||
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", | |||
"Logging": { | |||
"IncludeScopes": false, | |||
"Debug": { | |||
"LogLevel": { | |||
"Default": "Debug" | |||
} | |||
}, | |||
"Console": { | |||
"LogLevel": { | |||
"Default": "Debug" | |||
} | |||
} | |||
}, | |||
"SubscriptionClientName": "BackgroundTasks", | |||
"GracePeriodTime": "1", | |||
"CheckUpdateTime": "1000", | |||
"ApplicationInsights": { | |||
"InstrumentationKey": "" | |||
}, | |||
"AzureServiceBusEnabled": false, | |||
"EventBusRetryCount": 5, | |||
"EventBusConnection": "", | |||
"EventBusUserName": "", | |||
"EventBusPassword": "" | |||
} |