@ -1,47 +0,0 @@ | |||||
apiVersion: v1 | |||||
kind: Service | |||||
metadata: | |||||
labels: | |||||
app: eshop | |||||
component: frontend | |||||
name: frontend | |||||
spec: | |||||
ports: | |||||
- port: 80 | |||||
targetPort: 8080 | |||||
selector: | |||||
app: eshop | |||||
component: frontend | |||||
type: LoadBalancer | |||||
--- | |||||
apiVersion: extensions/v1beta1 | |||||
kind: Deployment | |||||
metadata: | |||||
name: frontend | |||||
spec: | |||||
template: | |||||
metadata: | |||||
labels: | |||||
app: eshop | |||||
component: frontend | |||||
spec: | |||||
containers: | |||||
- name: nginx | |||||
image: nginx:1.13.8-alpine | |||||
imagePullPolicy: IfNotPresent | |||||
ports: | |||||
- containerPort: 8080 | |||||
lifecycle: | |||||
preStop: | |||||
exec: | |||||
command: ["/usr/sbin/nginx","-s","quit"] | |||||
volumeMounts: | |||||
- name: config | |||||
mountPath: /etc/nginx | |||||
volumes: | |||||
- name: config | |||||
configMap: | |||||
name: config-files | |||||
items: | |||||
- key: nginx-conf | |||||
path: nginx.conf |
@ -0,0 +1,31 @@ | |||||
apiVersion: v1 | |||||
kind: ConfigMap | |||||
metadata: | |||||
name: internalurls | |||||
labels: | |||||
app: eshop | |||||
data: | |||||
# Internal Services & healthchecks | |||||
basket: http://basket | |||||
basket__hc: http://basket/hc | |||||
catalog: http://catalog | |||||
catalog__hc: http://catalog/hc | |||||
identity: http://identity | |||||
identity__hc: http://identity/hc | |||||
ordering: http://ordering | |||||
ordering__hc: http://ordering/hc | |||||
marketing: http://marketing | |||||
marketing__hc: http://marketing/hc | |||||
locations: http://locations | |||||
locations__hc: http://locations/hc | |||||
payment__hc: http://payment/hc | |||||
mvc__hc: http://webmvc/hc | |||||
spa__hc: http://webspa/hc | |||||
# Aggreggators | |||||
mobileshoppingagg: http://mobileshoppingagg | |||||
webshoppingagg: http://webshoppingagg | |||||
# API GWs | |||||
apigwmm: http://ocelotapigw-mm | |||||
apigwms: http://ocelotapigw-ms | |||||
apigwwm: http://ocelotapigw-wm | |||||
apigwws: http://ocelotapigw-ws |
@ -0,0 +1,34 @@ | |||||
{ | |||||
"ReRoutes": [ | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "marketing", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/m/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "locations", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/l/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
} | |||||
], | |||||
"GlobalConfiguration": { | |||||
"RequestIdKey": "OcRequestId", | |||||
"AdministrationPath": "/administration" | |||||
} | |||||
} | |||||
@ -0,0 +1,142 @@ | |||||
{ | |||||
"ReRoutes": [ | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "catalog", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/c/{everything}", | |||||
"UpstreamHttpMethod": [ "GET" ] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "basket", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/b/{everything}", | |||||
"UpstreamHttpMethod": [], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "ordering", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/o/{everything}", | |||||
"UpstreamHttpMethod": [], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "mobileshoppingagg", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/{everything}", | |||||
"UpstreamHttpMethod": [ "POST", "PUT", "GET" ], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "ordering", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/orders-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "basket", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/basket-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "catalog", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/catalog-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "marketing", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/marketing-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "payment", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/payment-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "locations.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/location-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
} | |||||
], | |||||
"GlobalConfiguration": { | |||||
"RequestIdKey": "OcRequestId", | |||||
"AdministrationPath": "/administration" | |||||
} | |||||
} | |||||
@ -0,0 +1,34 @@ | |||||
{ | |||||
"ReRoutes": [ | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "marketing", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/m/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "locations", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/l/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
} | |||||
], | |||||
"GlobalConfiguration": { | |||||
"RequestIdKey": "OcRequestId", | |||||
"AdministrationPath": "/administration" | |||||
} | |||||
} | |||||
@ -0,0 +1,142 @@ | |||||
{ | |||||
"ReRoutes": [ | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "catalog", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/c/{everything}", | |||||
"UpstreamHttpMethod": [ "GET" ] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "basket", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/b/{everything}", | |||||
"UpstreamHttpMethod": [], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "ordering", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/o/{everything}", | |||||
"UpstreamHttpMethod": [], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "webshoppingagg", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/{everything}", | |||||
"UpstreamHttpMethod": [ "POST", "PUT", "GET" ], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "ordering", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/orders-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "basket", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/basket-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "catalog", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/catalog-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "marketing", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/marketing-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "payment", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/payment-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "locations.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/location-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
} | |||||
], | |||||
"GlobalConfiguration": { | |||||
"RequestIdKey": "OcRequestId", | |||||
"AdministrationPath": "/administration" | |||||
} | |||||
} | |||||
@ -0,0 +1,155 @@ | |||||
apiVersion: extensions/v1beta1 | |||||
kind: Deployment | |||||
metadata: | |||||
name: apigwmm | |||||
spec: | |||||
paused: true | |||||
template: | |||||
metadata: | |||||
labels: | |||||
app: eshop | |||||
component: apigwmm | |||||
spec: | |||||
containers: | |||||
- name: apigwmm | |||||
image: eshop/ocelotapigw | |||||
imagePullPolicy: Always | |||||
env: | |||||
- name: PATH_BASE | |||||
value: /mobilemarketingapigw | |||||
- name: IdentityUrl | |||||
valueFrom: | |||||
configMapKeyRef: | |||||
name: internalurls | |||||
key: identity | |||||
ports: | |||||
- containerPort: 80 | |||||
volumeMounts: | |||||
- name: config | |||||
mountPath: /app/configuration | |||||
volumes: | |||||
- name: config | |||||
configMap: | |||||
name: ocelot | |||||
items: | |||||
- key: mm | |||||
path: configuration.json | |||||
imagePullSecrets: | |||||
- name: registry-key | |||||
--- | |||||
apiVersion: extensions/v1beta1 | |||||
kind: Deployment | |||||
metadata: | |||||
name: apigwms | |||||
spec: | |||||
paused: true | |||||
template: | |||||
metadata: | |||||
labels: | |||||
app: eshop | |||||
component: apigwms | |||||
spec: | |||||
containers: | |||||
- name: apigwms | |||||
image: eshop/ocelotapigw | |||||
imagePullPolicy: Always | |||||
env: | |||||
- name: PATH_BASE | |||||
value: /mobileshoppingapigw | |||||
- name: IdentityUrl | |||||
valueFrom: | |||||
configMapKeyRef: | |||||
name: internalurls | |||||
key: identity | |||||
ports: | |||||
- containerPort: 80 | |||||
volumeMounts: | |||||
- name: config | |||||
mountPath: /app/configuration | |||||
volumes: | |||||
- name: config | |||||
configMap: | |||||
name: ocelot | |||||
items: | |||||
- key: ms | |||||
path: configuration.json | |||||
imagePullSecrets: | |||||
- name: registry-key | |||||
--- | |||||
apiVersion: extensions/v1beta1 | |||||
kind: Deployment | |||||
metadata: | |||||
name: apigwwm | |||||
spec: | |||||
paused: true | |||||
template: | |||||
metadata: | |||||
labels: | |||||
app: eshop | |||||
component: apigwwm | |||||
spec: | |||||
containers: | |||||
- name: apigwwm | |||||
image: eshop/ocelotapigw | |||||
imagePullPolicy: Always | |||||
env: | |||||
- name: PATH_BASE | |||||
value: /webmarketingapigw | |||||
- name: IdentityUrl | |||||
valueFrom: | |||||
configMapKeyRef: | |||||
name: internalurls | |||||
key: identity | |||||
ports: | |||||
- containerPort: 80 | |||||
volumeMounts: | |||||
- name: config | |||||
mountPath: /app/configuration | |||||
volumes: | |||||
- name: config | |||||
configMap: | |||||
name: ocelot | |||||
items: | |||||
- key: wm | |||||
path: configuration.json | |||||
imagePullSecrets: | |||||
- name: registry-key | |||||
--- | |||||
apiVersion: extensions/v1beta1 | |||||
kind: Deployment | |||||
metadata: | |||||
name: apigwws | |||||
spec: | |||||
paused: true | |||||
template: | |||||
metadata: | |||||
labels: | |||||
app: eshop | |||||
component: apigwws | |||||
spec: | |||||
containers: | |||||
- name: apigwws | |||||
image: eshop/ocelotapigw | |||||
imagePullPolicy: Always | |||||
env: | |||||
- name: PATH_BASE | |||||
value: /webshoppingapigw | |||||
- name: IdentityUrl | |||||
valueFrom: | |||||
configMapKeyRef: | |||||
name: internalurls | |||||
key: identity | |||||
ports: | |||||
- containerPort: 80 | |||||
volumeMounts: | |||||
- name: config | |||||
mountPath: /app/configuration | |||||
volumes: | |||||
- name: config | |||||
configMap: | |||||
name: ocelot | |||||
items: | |||||
- key: ws | |||||
path: configuration.json | |||||
imagePullSecrets: | |||||
- name: registry-key |
@ -0,0 +1,55 @@ | |||||
apiVersion: v1 | |||||
kind: Service | |||||
metadata: | |||||
labels: | |||||
app: eshop | |||||
component: ocelotapigw-mm | |||||
name: ocelotapigw-mm | |||||
spec: | |||||
ports: | |||||
- port: 80 | |||||
selector: | |||||
app: eshop | |||||
component: apigwmm | |||||
--- | |||||
apiVersion: v1 | |||||
kind: Service | |||||
metadata: | |||||
labels: | |||||
app: eshop | |||||
component: ocelotapigw-ms | |||||
name: ocelotapigw-ms | |||||
spec: | |||||
ports: | |||||
- port: 80 | |||||
selector: | |||||
app: eshop | |||||
component: apigwms | |||||
--- | |||||
apiVersion: v1 | |||||
kind: Service | |||||
metadata: | |||||
labels: | |||||
app: eshop | |||||
component: ocelotapigw-wm | |||||
name: ocelotapigw-wm | |||||
spec: | |||||
ports: | |||||
- port: 80 | |||||
selector: | |||||
app: eshop | |||||
component: apigwwm | |||||
--- | |||||
apiVersion: v1 | |||||
kind: Service | |||||
metadata: | |||||
labels: | |||||
app: eshop | |||||
component: ocelotapigw-ws | |||||
name: ocelotapigw-ws | |||||
spec: | |||||
ports: | |||||
- port: 80 | |||||
selector: | |||||
app: eshop | |||||
component: apigwws |
@ -0,0 +1,19 @@ | |||||
FROM microsoft/aspnetcore:2.0 AS base | |||||
WORKDIR /app | |||||
EXPOSE 80 | |||||
FROM microsoft/aspnetcore-build:2.0 AS build | |||||
WORKDIR /src | |||||
COPY src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj src/ApiGateways/ApiGw-Base/ | |||||
RUN dotnet restore src/ApiGateways/ApiGw-Base/ | |||||
COPY . . | |||||
WORKDIR /src/src/ApiGateways/ApiGw-Base/ | |||||
RUN dotnet build -c Release -o /app | |||||
FROM build AS publish | |||||
RUN dotnet publish -c Release -o /app | |||||
FROM base AS final | |||||
WORKDIR /app | |||||
COPY --from=publish /app . | |||||
ENTRYPOINT ["dotnet", "OcelotApiGw.dll"] |
@ -0,0 +1,16 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk.Web"> | |||||
<PropertyGroup> | |||||
<TargetFramework>netcoreapp2.0</TargetFramework> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Folder Include="wwwroot\" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.3" /> | |||||
<PackageReference Include="Ocelot" Version="3.0.0" /> | |||||
</ItemGroup> | |||||
</Project> |
@ -0,0 +1,31 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNetCore; | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
namespace OcelotApiGw | |||||
{ | |||||
public class Program | |||||
{ | |||||
public static void Main(string[] args) | |||||
{ | |||||
BuildWebHost(args).Run(); | |||||
} | |||||
public static IWebHost BuildWebHost(string[] args) | |||||
{ | |||||
var builder = WebHost.CreateDefaultBuilder(args); | |||||
builder.ConfigureServices(s => s.AddSingleton(builder)) | |||||
.ConfigureAppConfiguration(ic => ic.AddJsonFile(Path.Combine("configuration", "configuration.json"))) | |||||
.UseStartup<Startup>(); | |||||
var host = builder.Build(); | |||||
return host; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,27 @@ | |||||
{ | |||||
"iisSettings": { | |||||
"windowsAuthentication": false, | |||||
"anonymousAuthentication": true, | |||||
"iisExpress": { | |||||
"applicationUrl": "http://localhost:56755/", | |||||
"sslPort": 0 | |||||
} | |||||
}, | |||||
"profiles": { | |||||
"IIS Express": { | |||||
"commandName": "IISExpress", | |||||
"launchBrowser": true, | |||||
"environmentVariables": { | |||||
"ASPNETCORE_ENVIRONMENT": "Development" | |||||
} | |||||
}, | |||||
"OcelotApiGw": { | |||||
"commandName": "Project", | |||||
"launchBrowser": true, | |||||
"environmentVariables": { | |||||
"ASPNETCORE_ENVIRONMENT": "Development" | |||||
}, | |||||
"applicationUrl": "http://localhost:64021/" | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,91 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using CacheManager.Core; | |||||
using Microsoft.AspNetCore.Builder; | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using Microsoft.AspNetCore.Http; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.Logging; | |||||
using Ocelot.DependencyInjection; | |||||
using Ocelot.Middleware; | |||||
namespace OcelotApiGw | |||||
{ | |||||
public class Startup | |||||
{ | |||||
private readonly IConfiguration _cfg; | |||||
public Startup(IConfiguration configuration) | |||||
{ | |||||
_cfg = configuration; | |||||
} | |||||
public void ConfigureServices(IServiceCollection services) | |||||
{ | |||||
var identityUrl = _cfg.GetValue<string>("IdentityUrl"); | |||||
var authenticationProviderKey = "IdentityApiKey"; | |||||
services.AddCors(options => | |||||
{ | |||||
options.AddPolicy("CorsPolicy", | |||||
builder => builder.AllowAnyOrigin() | |||||
.AllowAnyMethod() | |||||
.AllowAnyHeader() | |||||
.AllowCredentials()); | |||||
}); | |||||
services.AddAuthentication() | |||||
.AddJwtBearer(authenticationProviderKey, x => | |||||
{ | |||||
x.Authority = identityUrl; | |||||
x.RequireHttpsMetadata = false; | |||||
x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters() | |||||
{ | |||||
ValidAudiences = new[] { "orders", "basket", "locations", "marketing", "mobileshoppingagg", "webshoppingagg" } | |||||
}; | |||||
x.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents() | |||||
{ | |||||
OnAuthenticationFailed = async ctx => | |||||
{ | |||||
int i = 0; | |||||
}, | |||||
OnTokenValidated = async ctx => | |||||
{ | |||||
int i = 0; | |||||
}, | |||||
OnMessageReceived = async ctx => | |||||
{ | |||||
int i = 0; | |||||
} | |||||
}; | |||||
}); | |||||
services.AddOcelot(_cfg); | |||||
} | |||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) | |||||
{ | |||||
var pathBase = _cfg["PATH_BASE"]; | |||||
if (!string.IsNullOrEmpty(pathBase)) | |||||
{ | |||||
app.UsePathBase(pathBase); | |||||
} | |||||
if (env.IsDevelopment()) | |||||
{ | |||||
app.UseDeveloperExceptionPage(); | |||||
} | |||||
loggerFactory.AddConsole(_cfg.GetSection("Logging")); | |||||
app.UseCors("CorsPolicy"); | |||||
app.UseOcelot().Wait(); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,10 @@ | |||||
{ | |||||
"Logging": { | |||||
"IncludeScopes": true, | |||||
"LogLevel": { | |||||
"Default": "Trace", | |||||
"System": "Information", | |||||
"Microsoft": "Information" | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,34 @@ | |||||
{ | |||||
"ReRoutes": [ | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "marketing.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/m/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "locations.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/l/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
} | |||||
], | |||||
"GlobalConfiguration": { | |||||
"RequestIdKey": "OcRequestId", | |||||
"AdministrationPath": "/administration" | |||||
} | |||||
} | |||||
@ -0,0 +1,31 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config | |||||
{ | |||||
public class UrlsConfig | |||||
{ | |||||
public class CatalogOperations | |||||
{ | |||||
public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}"; | |||||
public static string GetItemsById(IEnumerable<int> ids) => $"/api/v1/catalog/items?ids={string.Join(',', ids)}"; | |||||
} | |||||
public class BasketOperations | |||||
{ | |||||
public static string GetItemById(string id) => $"/api/v1/basket/{id}"; | |||||
public static string UpdateBasket() => "/api/v1/basket"; | |||||
} | |||||
public class OrdersOperations | |||||
{ | |||||
public static string GetOrderDraft() => "/api/v1/orders/draft"; | |||||
} | |||||
public string Basket { get; set; } | |||||
public string Catalog { get; set; } | |||||
public string Orders { get; set; } | |||||
} | |||||
} |
@ -0,0 +1,133 @@ | |||||
using Microsoft.AspNetCore.Authorization; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers | |||||
{ | |||||
[Route("api/v1/[controller]")] | |||||
[Authorize] | |||||
public class BasketController : Controller | |||||
{ | |||||
private readonly ICatalogService _catalog; | |||||
private readonly IBasketService _basket; | |||||
public BasketController(ICatalogService catalogService, IBasketService basketService) | |||||
{ | |||||
_catalog = catalogService; | |||||
_basket = basketService; | |||||
} | |||||
[HttpPost] | |||||
[HttpPut] | |||||
public async Task<IActionResult> UpdateAllBasket([FromBody] UpdateBasketRequest data) | |||||
{ | |||||
if (data.Items == null || !data.Items.Any()) | |||||
{ | |||||
return BadRequest("Need to pass at least one basket line"); | |||||
} | |||||
// Retrieve the current basket | |||||
var currentBasket = await _basket.GetById(data.BuyerId); | |||||
if (currentBasket == null) | |||||
{ | |||||
currentBasket = new BasketData(data.BuyerId); | |||||
} | |||||
var catalogItems = await _catalog.GetCatalogItems(data.Items.Select(x => x.ProductId)); | |||||
var newBasket = new BasketData(data.BuyerId); | |||||
foreach (var bitem in data.Items) | |||||
{ | |||||
var catalogItem = catalogItems.SingleOrDefault(ci => ci.Id == bitem.ProductId); | |||||
if (catalogItem == null) | |||||
{ | |||||
return BadRequest($"Basket refers to a non-existing catalog item ({bitem.ProductId})"); | |||||
} | |||||
newBasket.Items.Add(new BasketDataItem() | |||||
{ | |||||
Id = bitem.Id, | |||||
ProductId = catalogItem.Id.ToString(), | |||||
ProductName = catalogItem.Name, | |||||
PictureUrl = catalogItem.PictureUri, | |||||
UnitPrice = catalogItem.Price, | |||||
Quantity = bitem.Quantity | |||||
}); | |||||
} | |||||
await _basket.Update(newBasket); | |||||
return Ok(newBasket); | |||||
} | |||||
[HttpPut] | |||||
[Route("items")] | |||||
public async Task<IActionResult> UpdateQuantities([FromBody] UpdateBasketItemsRequest data) | |||||
{ | |||||
if (!data.Updates.Any()) | |||||
{ | |||||
return BadRequest("No updates sent"); | |||||
} | |||||
// Retrieve the current basket | |||||
var currentBasket = await _basket.GetById(data.BasketId); | |||||
if (currentBasket == null) | |||||
{ | |||||
return BadRequest($"Basket with id {data.BasketId} not found."); | |||||
} | |||||
// Update with new quantities | |||||
foreach (var update in data.Updates) | |||||
{ | |||||
var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId); | |||||
if (basketItem == null) | |||||
{ | |||||
return BadRequest($"Basket item with id {update.BasketItemId} not found"); | |||||
} | |||||
basketItem.Quantity = update.NewQty; | |||||
} | |||||
// Save the updated basket | |||||
await _basket.Update(currentBasket); | |||||
return Ok(currentBasket); | |||||
} | |||||
[HttpPost] | |||||
[Route("items")] | |||||
public async Task<IActionResult> AddBasketItem([FromBody] AddBasketItemRequest data) | |||||
{ | |||||
if (data == null || data.Quantity == 0) | |||||
{ | |||||
return BadRequest("Invalid payload"); | |||||
} | |||||
// Step 1: Get the item from catalog | |||||
var item = await _catalog.GetCatalogItem(data.CatalogItemId); | |||||
//item.PictureUri = | |||||
// Step 2: Get current basket status | |||||
var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId); | |||||
// Step 3: Merge current status with new product | |||||
currentBasket.Items.Add(new BasketDataItem() | |||||
{ | |||||
UnitPrice = item.Price, | |||||
PictureUrl = item.PictureUri, | |||||
ProductId = item.Id.ToString(), | |||||
ProductName = item.Name, | |||||
Quantity = data.Quantity, | |||||
Id = Guid.NewGuid().ToString() | |||||
}); | |||||
// Step 4: Update basket | |||||
await _basket.Update(currentBasket); | |||||
return Ok(); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,18 @@ | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers | |||||
{ | |||||
[Route("")] | |||||
public class HomeController : Controller | |||||
{ | |||||
[HttpGet()] | |||||
public IActionResult Index() | |||||
{ | |||||
return new RedirectResult("~/swagger"); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,42 @@ | |||||
using Microsoft.AspNetCore.Authorization; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers | |||||
{ | |||||
[Route("api/v1/[controller]")] | |||||
[Authorize] | |||||
public class OrderController : Controller | |||||
{ | |||||
private readonly IBasketService _basketService; | |||||
private readonly IOrderApiClient _orderClient; | |||||
public OrderController(IBasketService basketService, IOrderApiClient orderClient) | |||||
{ | |||||
_basketService = basketService; | |||||
_orderClient = orderClient; | |||||
} | |||||
[Route("draft/{basketId}")] | |||||
[HttpGet] | |||||
public async Task<IActionResult> GetOrderDraft(string basketId) | |||||
{ | |||||
if (string.IsNullOrEmpty(basketId)) | |||||
{ | |||||
return BadRequest("Need a valid basketid"); | |||||
} | |||||
// Get the basket data and build a order draft based on it | |||||
var basket = await _basketService.GetById(basketId); | |||||
if (basket == null) | |||||
{ | |||||
return BadRequest($"No basket found for id {basketId}"); | |||||
} | |||||
var orderDraft = await _orderClient.GetOrderDraftFromBasket(basket); | |||||
return Ok(orderDraft); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,19 @@ | |||||
FROM microsoft/aspnetcore:2.0.5 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/ApiGateways/Mobile.Bff.Shopping/aggregator | |||||
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", "Mobile.Shopping.HttpAggregator.dll"] | |||||
@ -0,0 +1,33 @@ | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters | |||||
{ | |||||
using Microsoft.AspNetCore.Authorization; | |||||
using Swashbuckle.AspNetCore.Swagger; | |||||
using Swashbuckle.AspNetCore.SwaggerGen; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
namespace Basket.API.Infrastructure.Filters | |||||
{ | |||||
public 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 [] { "Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator" } } | |||||
}); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,27 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk.Web"> | |||||
<PropertyGroup> | |||||
<TargetFramework>netcoreapp2.0</TargetFramework> | |||||
<AssemblyName>Mobile.Shopping.HttpAggregator</AssemblyName> | |||||
<RootNamespace>Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator</RootNamespace> | |||||
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Folder Include="wwwroot\" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" /> | |||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.1.0" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\..\..\BuildingBlocks\Resilience\Resilience.Http\Resilience.Http.csproj" /> | |||||
</ItemGroup> | |||||
</Project> |
@ -0,0 +1,20 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class AddBasketItemRequest | |||||
{ | |||||
public int CatalogItemId { get; set; } | |||||
public string BasketId { get; set; } | |||||
public int Quantity { get; set; } | |||||
public AddBasketItemRequest() | |||||
{ | |||||
Quantity = 1; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,31 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class BasketData | |||||
{ | |||||
public string BuyerId { get; set; } | |||||
public List<BasketDataItem> Items { get; set; } | |||||
public BasketData(string buyerId) | |||||
{ | |||||
BuyerId = buyerId; | |||||
Items = new List<BasketDataItem>(); | |||||
} | |||||
} | |||||
public class BasketDataItem | |||||
{ | |||||
public string Id { get; set; } | |||||
public string ProductId { get; set; } | |||||
public string ProductName { get; set; } | |||||
public decimal UnitPrice { get; set; } | |||||
public decimal OldUnitPrice { get; set; } | |||||
public int Quantity { get; set; } | |||||
public string PictureUrl { get; set; } | |||||
} | |||||
} |
@ -0,0 +1,20 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class CatalogItem | |||||
{ | |||||
public int Id { get; set; } | |||||
public string Name { get; set; } | |||||
public decimal Price { get; set; } | |||||
public string PictureUri { get; set; } | |||||
} | |||||
} |
@ -0,0 +1,33 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class OrderData | |||||
{ | |||||
public string OrderNumber { get; set; } | |||||
public DateTime Date { get; set; } | |||||
public string Status { get; set; } | |||||
public decimal Total { get; set; } | |||||
public string Description { get; set; } | |||||
public string City { get; set; } | |||||
public string Street { get; set; } | |||||
public string State { get; set; } | |||||
public string Country { get; set; } | |||||
public string ZipCode { get; set; } | |||||
public string CardNumber { get; set; } | |||||
public string CardHolderName { get; set; } | |||||
public bool IsDraft { get; set; } | |||||
public DateTime CardExpiration { get; set; } | |||||
public string CardExpirationShort { get; set; } | |||||
public string CardSecurityNumber { get; set; } | |||||
public int CardTypeId { get; set; } | |||||
public string Buyer { get; set; } | |||||
public List<OrderItemData> OrderItems { get; } = new List<OrderItemData>(); | |||||
} | |||||
} |
@ -0,0 +1,17 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class OrderItemData | |||||
{ | |||||
public int ProductId { get; set; } | |||||
public string ProductName { get; set; } | |||||
public decimal UnitPrice { get; set; } | |||||
public decimal Discount { get; set; } | |||||
public int Units { get; set; } | |||||
public string PictureUrl { get; set; } | |||||
} | |||||
} |
@ -0,0 +1,31 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class UpdateBasketItemsRequest | |||||
{ | |||||
public string BasketId { get; set; } | |||||
public ICollection<UpdateBasketItemData> Updates { get; set; } | |||||
public UpdateBasketItemsRequest() | |||||
{ | |||||
Updates = new List<UpdateBasketItemData>(); | |||||
} | |||||
} | |||||
public class UpdateBasketItemData | |||||
{ | |||||
public string BasketItemId { get; set; } | |||||
public int NewQty { get; set; } | |||||
public UpdateBasketItemData() | |||||
{ | |||||
NewQty = 0; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,21 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class UpdateBasketRequest | |||||
{ | |||||
public string BuyerId { get; set; } | |||||
public IEnumerable<UpdateBasketRequestItemData> Items { get; set; } | |||||
} | |||||
public class UpdateBasketRequestItemData | |||||
{ | |||||
public string Id { get; set; } // Basket id | |||||
public int ProductId { get; set; } // Catalog item id | |||||
public int Quantity { get; set; } // Quantity | |||||
} | |||||
} |
@ -0,0 +1,36 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNetCore; | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.Logging; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator | |||||
{ | |||||
public class Program | |||||
{ | |||||
public static void Main(string[] args) | |||||
{ | |||||
BuildWebHost(args).Run(); | |||||
} | |||||
public static IWebHost BuildWebHost(string[] args) => | |||||
WebHost | |||||
.CreateDefaultBuilder(args) | |||||
.ConfigureAppConfiguration(cb => | |||||
{ | |||||
var sources = cb.Sources; | |||||
sources.Insert(3, new Microsoft.Extensions.Configuration.Json.JsonConfigurationSource() | |||||
{ | |||||
Optional = true, | |||||
Path = "appsettings.localhost.json", | |||||
ReloadOnChange = false | |||||
}); | |||||
}) | |||||
.UseStartup<Startup>() | |||||
.Build(); | |||||
} | |||||
} |
@ -0,0 +1,29 @@ | |||||
{ | |||||
"iisSettings": { | |||||
"windowsAuthentication": false, | |||||
"anonymousAuthentication": true, | |||||
"iisExpress": { | |||||
"applicationUrl": "http://localhost:57425/", | |||||
"sslPort": 0 | |||||
} | |||||
}, | |||||
"profiles": { | |||||
"IIS Express": { | |||||
"commandName": "IISExpress", | |||||
"launchBrowser": true, | |||||
"launchUrl": "api/values", | |||||
"environmentVariables": { | |||||
"ASPNETCORE_ENVIRONMENT": "Development" | |||||
} | |||||
}, | |||||
"PurchaseForMvc": { | |||||
"commandName": "Project", | |||||
"launchBrowser": true, | |||||
"launchUrl": "api/values", | |||||
"environmentVariables": { | |||||
"ASPNETCORE_ENVIRONMENT": "Development" | |||||
}, | |||||
"applicationUrl": "http://localhost:61632/" | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,53 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNetCore.Authentication; | |||||
using Microsoft.AspNetCore.Http; | |||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using Newtonsoft.Json; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services | |||||
{ | |||||
public class BasketService : IBasketService | |||||
{ | |||||
private readonly IHttpClient _apiClient; | |||||
private readonly ILogger<BasketService> _logger; | |||||
private readonly UrlsConfig _urls; | |||||
private readonly IHttpContextAccessor _httpContextAccessor; | |||||
public BasketService(IHttpClient httpClient, IHttpContextAccessor httpContextAccessor, ILogger<BasketService> logger, IOptionsSnapshot<UrlsConfig> config) | |||||
{ | |||||
_apiClient = httpClient; | |||||
_logger = logger; | |||||
_urls = config.Value; | |||||
_httpContextAccessor = httpContextAccessor; | |||||
} | |||||
public async Task<BasketData> GetById(string id) | |||||
{ | |||||
var token = await GetUserTokenAsync(); | |||||
var data = await _apiClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id), token); | |||||
var basket = !string.IsNullOrEmpty(data) ? JsonConvert.DeserializeObject<BasketData>(data) : null; | |||||
return basket; | |||||
} | |||||
public async Task Update(BasketData currentBasket) | |||||
{ | |||||
var token = await GetUserTokenAsync(); | |||||
var data = await _apiClient.PostAsync<BasketData>(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), currentBasket, token); | |||||
int i = 0; | |||||
} | |||||
async Task<string> GetUserTokenAsync() | |||||
{ | |||||
var context = _httpContextAccessor.HttpContext; | |||||
return await context.GetTokenAsync("access_token"); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,43 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using Newtonsoft.Json; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services | |||||
{ | |||||
public class CatalogService : ICatalogService | |||||
{ | |||||
private readonly IHttpClient _apiClient; | |||||
private readonly ILogger<CatalogService> _logger; | |||||
private readonly UrlsConfig _urls; | |||||
public CatalogService(IHttpClient httpClient, ILogger<CatalogService> logger, IOptionsSnapshot<UrlsConfig> config) | |||||
{ | |||||
_apiClient = httpClient; | |||||
_logger = logger; | |||||
_urls = config.Value; | |||||
} | |||||
public async Task<CatalogItem> GetCatalogItem(int id) | |||||
{ | |||||
var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id)); | |||||
var item = JsonConvert.DeserializeObject<CatalogItem>(data); | |||||
return item; | |||||
} | |||||
public async Task<IEnumerable<CatalogItem>> GetCatalogItems(IEnumerable<int> ids) | |||||
{ | |||||
var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids)); | |||||
var item = JsonConvert.DeserializeObject<CatalogItem[]>(data); | |||||
return item; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,15 @@ | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services | |||||
{ | |||||
public interface IBasketService | |||||
{ | |||||
Task<BasketData> GetById(string id); | |||||
Task Update(BasketData currentBasket); | |||||
} | |||||
} |
@ -0,0 +1,14 @@ | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services | |||||
{ | |||||
public interface ICatalogService | |||||
{ | |||||
Task<CatalogItem> GetCatalogItem(int id); | |||||
Task<IEnumerable<CatalogItem>> GetCatalogItems(IEnumerable<int> ids); | |||||
} | |||||
} |
@ -0,0 +1,13 @@ | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services | |||||
{ | |||||
public interface IOrderApiClient | |||||
{ | |||||
Task<OrderData> GetOrderDraftFromBasket(BasketData basket); | |||||
} | |||||
} |
@ -0,0 +1,37 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using Newtonsoft.Json; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services | |||||
{ | |||||
public class OrderApiClient : IOrderApiClient | |||||
{ | |||||
private readonly IHttpClient _apiClient; | |||||
private readonly ILogger<OrderApiClient> _logger; | |||||
private readonly UrlsConfig _urls; | |||||
public OrderApiClient(IHttpClient httpClient, ILogger<OrderApiClient> logger, IOptionsSnapshot<UrlsConfig> config) | |||||
{ | |||||
_apiClient = httpClient; | |||||
_logger = logger; | |||||
_urls = config.Value; | |||||
} | |||||
public async Task<OrderData> GetOrderDraftFromBasket(BasketData basket) | |||||
{ | |||||
var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft(); | |||||
var response = await _apiClient.PostAsync<BasketData>(url, basket); | |||||
response.EnsureSuccessStatusCode(); | |||||
var jsonResponse = await response.Content.ReadAsStringAsync(); | |||||
return JsonConvert.DeserializeObject<OrderData>(jsonResponse); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,138 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IdentityModel.Tokens.Jwt; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNetCore.Authentication.JwtBearer; | |||||
using Microsoft.AspNetCore.Builder; | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using Microsoft.AspNetCore.Http; | |||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters; | |||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; | |||||
using Swashbuckle.AspNetCore.Swagger; | |||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator | |||||
{ | |||||
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 void ConfigureServices(IServiceCollection services) | |||||
{ | |||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); | |||||
services.AddSingleton<IHttpClient, StandardHttpClient>(); | |||||
services.AddTransient<ICatalogService, CatalogService>(); | |||||
services.AddTransient<IBasketService, BasketService>(); | |||||
services.AddTransient<IOrderApiClient, OrderApiClient>(); | |||||
services.AddOptions(); | |||||
services.Configure<UrlsConfig>(Configuration.GetSection("urls")); | |||||
services.AddMvc(); | |||||
services.AddSwaggerGen(options => | |||||
{ | |||||
options.DescribeAllEnumsAsStrings(); | |||||
options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info | |||||
{ | |||||
Title = "Shopping Aggregator for Mobile Clients", | |||||
Version = "v1", | |||||
Description = "Shopping Aggregator for Mobile Clients", | |||||
TermsOfService = "Terms Of Service" | |||||
}); | |||||
options.AddSecurityDefinition("oauth2", new OAuth2Scheme | |||||
{ | |||||
Type = "oauth2", | |||||
Flow = "implicit", | |||||
AuthorizationUrl = $"{Configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize", | |||||
TokenUrl = $"{Configuration.GetValue<string>("IdentityUrlExternal")}/connect/token", | |||||
Scopes = new Dictionary<string, string>() | |||||
{ | |||||
{ "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" } | |||||
} | |||||
}); | |||||
options.OperationFilter<AuthorizeCheckOperationFilter>(); | |||||
}); | |||||
services.AddCors(options => | |||||
{ | |||||
options.AddPolicy("CorsPolicy", | |||||
builder => builder.AllowAnyOrigin() | |||||
.AllowAnyMethod() | |||||
.AllowAnyHeader() | |||||
.AllowCredentials()); | |||||
}); | |||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); | |||||
var identityUrl = Configuration.GetValue<string>("urls:identity"); | |||||
services.AddAuthentication(options => | |||||
{ | |||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; | |||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; | |||||
}).AddJwtBearer(options => | |||||
{ | |||||
options.Authority = identityUrl; | |||||
options.RequireHttpsMetadata = false; | |||||
options.Audience = "mobileshoppingagg"; | |||||
options.Events = new JwtBearerEvents() | |||||
{ | |||||
OnAuthenticationFailed = async ctx => | |||||
{ | |||||
int i = 0; | |||||
}, | |||||
OnTokenValidated = async ctx => | |||||
{ | |||||
int i = 0; | |||||
} | |||||
}; | |||||
}); | |||||
} | |||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) | |||||
{ | |||||
var pathBase = Configuration["PATH_BASE"]; | |||||
if (!string.IsNullOrEmpty(pathBase)) | |||||
{ | |||||
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'"); | |||||
app.UsePathBase(pathBase); | |||||
} | |||||
app.UseCors("CorsPolicy"); | |||||
if (env.IsDevelopment()) | |||||
{ | |||||
app.UseDeveloperExceptionPage(); | |||||
} | |||||
app.UseAuthentication(); | |||||
app.UseMvc(); | |||||
app.UseSwagger().UseSwaggerUI(c => | |||||
{ | |||||
c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1"); | |||||
c.ConfigureOAuth2("Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI"); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,15 @@ | |||||
{ | |||||
"Logging": { | |||||
"IncludeScopes": false, | |||||
"Debug": { | |||||
"LogLevel": { | |||||
"Default": "Warning" | |||||
} | |||||
}, | |||||
"Console": { | |||||
"LogLevel": { | |||||
"Default": "Warning" | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,8 @@ | |||||
{ | |||||
"urls": { | |||||
"basket": "http://localhost:55105", | |||||
"catalog": "http://localhost:55101", | |||||
"orders": "http://localhost:55102", | |||||
"identity": "http://localhost:55105" | |||||
} | |||||
} |
@ -0,0 +1,142 @@ | |||||
{ | |||||
"ReRoutes": [ | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "catalog.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/c/{everything}", | |||||
"UpstreamHttpMethod": [ "GET" ] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "basket.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/b/{everything}", | |||||
"UpstreamHttpMethod": [], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "ordering.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/o/{everything}", | |||||
"UpstreamHttpMethod": [], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "mobileshoppingagg", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/{everything}", | |||||
"UpstreamHttpMethod": [ "POST", "PUT", "GET" ], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "ordering.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/orders-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "basket.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/basket-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "catalog.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/catalog-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "marketing.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/marketing-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "payment.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/payment-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "locations.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/location-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
} | |||||
], | |||||
"GlobalConfiguration": { | |||||
"RequestIdKey": "OcRequestId", | |||||
"AdministrationPath": "/administration" | |||||
} | |||||
} | |||||
@ -0,0 +1,34 @@ | |||||
{ | |||||
"ReRoutes": [ | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "marketing.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/m/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "locations.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/l/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
} | |||||
], | |||||
"GlobalConfiguration": { | |||||
"RequestIdKey": "OcRequestId", | |||||
"AdministrationPath": "/administration" | |||||
} | |||||
} | |||||
@ -0,0 +1,31 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config | |||||
{ | |||||
public class UrlsConfig | |||||
{ | |||||
public class CatalogOperations | |||||
{ | |||||
public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}"; | |||||
public static string GetItemsById(IEnumerable<int> ids) => $"/api/v1/catalog/items?ids={string.Join(',', ids)}"; | |||||
} | |||||
public class BasketOperations | |||||
{ | |||||
public static string GetItemById(string id) => $"/api/v1/basket/{id}"; | |||||
public static string UpdateBasket() => "/api/v1/basket"; | |||||
} | |||||
public class OrdersOperations | |||||
{ | |||||
public static string GetOrderDraft() => "/api/v1/orders/draft"; | |||||
} | |||||
public string Basket { get; set; } | |||||
public string Catalog { get; set; } | |||||
public string Orders { get; set; } | |||||
} | |||||
} |
@ -0,0 +1,133 @@ | |||||
using Microsoft.AspNetCore.Authorization; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers | |||||
{ | |||||
[Route("api/v1/[controller]")] | |||||
[Authorize] | |||||
public class BasketController : Controller | |||||
{ | |||||
private readonly ICatalogService _catalog; | |||||
private readonly IBasketService _basket; | |||||
public BasketController(ICatalogService catalogService, IBasketService basketService) | |||||
{ | |||||
_catalog = catalogService; | |||||
_basket = basketService; | |||||
} | |||||
[HttpPost] | |||||
[HttpPut] | |||||
public async Task<IActionResult> UpdateAllBasket([FromBody] UpdateBasketRequest data) | |||||
{ | |||||
if (data.Items == null || !data.Items.Any()) | |||||
{ | |||||
return BadRequest("Need to pass at least one basket line"); | |||||
} | |||||
// Retrieve the current basket | |||||
var currentBasket = await _basket.GetById(data.BuyerId); | |||||
if (currentBasket == null) | |||||
{ | |||||
currentBasket = new BasketData(data.BuyerId); | |||||
} | |||||
var catalogItems = await _catalog.GetCatalogItems(data.Items.Select(x => x.ProductId)); | |||||
var newBasket = new BasketData(data.BuyerId); | |||||
foreach (var bitem in data.Items) | |||||
{ | |||||
var catalogItem = catalogItems.SingleOrDefault(ci => ci.Id == bitem.ProductId); | |||||
if (catalogItem == null) | |||||
{ | |||||
return BadRequest($"Basket refers to a non-existing catalog item ({bitem.ProductId})"); | |||||
} | |||||
newBasket.Items.Add(new BasketDataItem() | |||||
{ | |||||
Id = bitem.Id, | |||||
ProductId = catalogItem.Id.ToString(), | |||||
ProductName = catalogItem.Name, | |||||
PictureUrl = catalogItem.PictureUri, | |||||
UnitPrice = catalogItem.Price, | |||||
Quantity = bitem.Quantity | |||||
}); | |||||
} | |||||
await _basket.Update(newBasket); | |||||
return Ok(newBasket); | |||||
} | |||||
[HttpPut] | |||||
[Route("items")] | |||||
public async Task<IActionResult> UpdateQuantities([FromBody] UpdateBasketItemsRequest data) | |||||
{ | |||||
if (!data.Updates.Any()) | |||||
{ | |||||
return BadRequest("No updates sent"); | |||||
} | |||||
// Retrieve the current basket | |||||
var currentBasket = await _basket.GetById(data.BasketId); | |||||
if (currentBasket == null) | |||||
{ | |||||
return BadRequest($"Basket with id {data.BasketId} not found."); | |||||
} | |||||
// Update with new quantities | |||||
foreach (var update in data.Updates) | |||||
{ | |||||
var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId); | |||||
if (basketItem == null) | |||||
{ | |||||
return BadRequest($"Basket item with id {update.BasketItemId} not found"); | |||||
} | |||||
basketItem.Quantity = update.NewQty; | |||||
} | |||||
// Save the updated basket | |||||
await _basket.Update(currentBasket); | |||||
return Ok(currentBasket); | |||||
} | |||||
[HttpPost] | |||||
[Route("items")] | |||||
public async Task<IActionResult> AddBasketItem([FromBody] AddBasketItemRequest data) | |||||
{ | |||||
if (data == null || data.Quantity == 0) | |||||
{ | |||||
return BadRequest("Invalid payload"); | |||||
} | |||||
// Step 1: Get the item from catalog | |||||
var item = await _catalog.GetCatalogItem(data.CatalogItemId); | |||||
//item.PictureUri = | |||||
// Step 2: Get current basket status | |||||
var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId); | |||||
// Step 3: Merge current status with new product | |||||
currentBasket.Items.Add(new BasketDataItem() | |||||
{ | |||||
UnitPrice = item.Price, | |||||
PictureUrl = item.PictureUri, | |||||
ProductId = item.Id.ToString(), | |||||
ProductName = item.Name, | |||||
Quantity = data.Quantity, | |||||
Id = Guid.NewGuid().ToString() | |||||
}); | |||||
// Step 4: Update basket | |||||
await _basket.Update(currentBasket); | |||||
return Ok(); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,18 @@ | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers | |||||
{ | |||||
[Route("")] | |||||
public class HomeController : Controller | |||||
{ | |||||
[HttpGet()] | |||||
public IActionResult Index() | |||||
{ | |||||
return new RedirectResult("~/swagger"); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,42 @@ | |||||
using Microsoft.AspNetCore.Authorization; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers | |||||
{ | |||||
[Route("api/v1/[controller]")] | |||||
[Authorize] | |||||
public class OrderController : Controller | |||||
{ | |||||
private readonly IBasketService _basketService; | |||||
private readonly IOrderApiClient _orderClient; | |||||
public OrderController(IBasketService basketService, IOrderApiClient orderClient) | |||||
{ | |||||
_basketService = basketService; | |||||
_orderClient = orderClient; | |||||
} | |||||
[Route("draft/{basketId}")] | |||||
[HttpGet] | |||||
public async Task<IActionResult> GetOrderDraft(string basketId) | |||||
{ | |||||
if (string.IsNullOrEmpty(basketId)) | |||||
{ | |||||
return BadRequest("Need a valid basketid"); | |||||
} | |||||
// Get the basket data and build a order draft based on it | |||||
var basket = await _basketService.GetById(basketId); | |||||
if (basket == null) | |||||
{ | |||||
return BadRequest($"No basket found for id {basketId}"); | |||||
} | |||||
var orderDraft = await _orderClient.GetOrderDraftFromBasket(basket); | |||||
return Ok(orderDraft); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,18 @@ | |||||
FROM microsoft/aspnetcore:2.0.5 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/ApiGateways/Web.Bff.Shopping/aggregator | |||||
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", "Web.Shopping.HttpAggregator.dll"] |
@ -0,0 +1,33 @@ | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters | |||||
{ | |||||
using Microsoft.AspNetCore.Authorization; | |||||
using Swashbuckle.AspNetCore.Swagger; | |||||
using Swashbuckle.AspNetCore.SwaggerGen; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
namespace Basket.API.Infrastructure.Filters | |||||
{ | |||||
public 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 [] { "Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator" } } | |||||
}); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,20 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class AddBasketItemRequest | |||||
{ | |||||
public int CatalogItemId { get; set; } | |||||
public string BasketId { get; set; } | |||||
public int Quantity { get; set; } | |||||
public AddBasketItemRequest() | |||||
{ | |||||
Quantity = 1; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,31 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class BasketData | |||||
{ | |||||
public string BuyerId { get; set; } | |||||
public List<BasketDataItem> Items { get; set; } | |||||
public BasketData(string buyerId) | |||||
{ | |||||
BuyerId = buyerId; | |||||
Items = new List<BasketDataItem>(); | |||||
} | |||||
} | |||||
public class BasketDataItem | |||||
{ | |||||
public string Id { get; set; } | |||||
public string ProductId { get; set; } | |||||
public string ProductName { get; set; } | |||||
public decimal UnitPrice { get; set; } | |||||
public decimal OldUnitPrice { get; set; } | |||||
public int Quantity { get; set; } | |||||
public string PictureUrl { get; set; } | |||||
} | |||||
} |
@ -0,0 +1,20 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class CatalogItem | |||||
{ | |||||
public int Id { get; set; } | |||||
public string Name { get; set; } | |||||
public decimal Price { get; set; } | |||||
public string PictureUri { get; set; } | |||||
} | |||||
} |
@ -0,0 +1,33 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class OrderData | |||||
{ | |||||
public string OrderNumber { get; set; } | |||||
public DateTime Date { get; set; } | |||||
public string Status { get; set; } | |||||
public decimal Total { get; set; } | |||||
public string Description { get; set; } | |||||
public string City { get; set; } | |||||
public string Street { get; set; } | |||||
public string State { get; set; } | |||||
public string Country { get; set; } | |||||
public string ZipCode { get; set; } | |||||
public string CardNumber { get; set; } | |||||
public string CardHolderName { get; set; } | |||||
public bool IsDraft { get; set; } | |||||
public DateTime CardExpiration { get; set; } | |||||
public string CardExpirationShort { get; set; } | |||||
public string CardSecurityNumber { get; set; } | |||||
public int CardTypeId { get; set; } | |||||
public string Buyer { get; set; } | |||||
public List<OrderItemData> OrderItems { get; } = new List<OrderItemData>(); | |||||
} | |||||
} |
@ -0,0 +1,17 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class OrderItemData | |||||
{ | |||||
public int ProductId { get; set; } | |||||
public string ProductName { get; set; } | |||||
public decimal UnitPrice { get; set; } | |||||
public decimal Discount { get; set; } | |||||
public int Units { get; set; } | |||||
public string PictureUrl { get; set; } | |||||
} | |||||
} |
@ -0,0 +1,31 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class UpdateBasketItemsRequest | |||||
{ | |||||
public string BasketId { get; set; } | |||||
public ICollection<UpdateBasketItemData> Updates { get; set; } | |||||
public UpdateBasketItemsRequest() | |||||
{ | |||||
Updates = new List<UpdateBasketItemData>(); | |||||
} | |||||
} | |||||
public class UpdateBasketItemData | |||||
{ | |||||
public string BasketItemId { get; set; } | |||||
public int NewQty { get; set; } | |||||
public UpdateBasketItemData() | |||||
{ | |||||
NewQty = 0; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,21 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models | |||||
{ | |||||
public class UpdateBasketRequest | |||||
{ | |||||
public string BuyerId { get; set; } | |||||
public IEnumerable<UpdateBasketRequestItemData> Items { get; set; } | |||||
} | |||||
public class UpdateBasketRequestItemData | |||||
{ | |||||
public string Id { get; set; } // Basket id | |||||
public int ProductId { get; set; } // Catalog item id | |||||
public int Quantity { get; set; } // Quantity | |||||
} | |||||
} |
@ -0,0 +1,36 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNetCore; | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.Logging; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator | |||||
{ | |||||
public class Program | |||||
{ | |||||
public static void Main(string[] args) | |||||
{ | |||||
BuildWebHost(args).Run(); | |||||
} | |||||
public static IWebHost BuildWebHost(string[] args) => | |||||
WebHost | |||||
.CreateDefaultBuilder(args) | |||||
.ConfigureAppConfiguration(cb => | |||||
{ | |||||
var sources = cb.Sources; | |||||
sources.Insert(3, new Microsoft.Extensions.Configuration.Json.JsonConfigurationSource() | |||||
{ | |||||
Optional = true, | |||||
Path = "appsettings.localhost.json", | |||||
ReloadOnChange = false | |||||
}); | |||||
}) | |||||
.UseStartup<Startup>() | |||||
.Build(); | |||||
} | |||||
} |
@ -0,0 +1,29 @@ | |||||
{ | |||||
"iisSettings": { | |||||
"windowsAuthentication": false, | |||||
"anonymousAuthentication": true, | |||||
"iisExpress": { | |||||
"applicationUrl": "http://localhost:57425/", | |||||
"sslPort": 0 | |||||
} | |||||
}, | |||||
"profiles": { | |||||
"IIS Express": { | |||||
"commandName": "IISExpress", | |||||
"launchBrowser": true, | |||||
"launchUrl": "api/values", | |||||
"environmentVariables": { | |||||
"ASPNETCORE_ENVIRONMENT": "Development" | |||||
} | |||||
}, | |||||
"PurchaseForMvc": { | |||||
"commandName": "Project", | |||||
"launchBrowser": true, | |||||
"launchUrl": "api/values", | |||||
"environmentVariables": { | |||||
"ASPNETCORE_ENVIRONMENT": "Development" | |||||
}, | |||||
"applicationUrl": "http://localhost:61632/" | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,53 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNetCore.Authentication; | |||||
using Microsoft.AspNetCore.Http; | |||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using Newtonsoft.Json; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services | |||||
{ | |||||
public class BasketService : IBasketService | |||||
{ | |||||
private readonly IHttpClient _apiClient; | |||||
private readonly ILogger<BasketService> _logger; | |||||
private readonly UrlsConfig _urls; | |||||
private readonly IHttpContextAccessor _httpContextAccessor; | |||||
public BasketService(IHttpClient httpClient, IHttpContextAccessor httpContextAccessor, ILogger<BasketService> logger, IOptionsSnapshot<UrlsConfig> config) | |||||
{ | |||||
_apiClient = httpClient; | |||||
_logger = logger; | |||||
_urls = config.Value; | |||||
_httpContextAccessor = httpContextAccessor; | |||||
} | |||||
public async Task<BasketData> GetById(string id) | |||||
{ | |||||
var token = await GetUserTokenAsync(); | |||||
var data = await _apiClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id), token); | |||||
var basket = !string.IsNullOrEmpty(data) ? JsonConvert.DeserializeObject<BasketData>(data) : null; | |||||
return basket; | |||||
} | |||||
public async Task Update(BasketData currentBasket) | |||||
{ | |||||
var token = await GetUserTokenAsync(); | |||||
var data = await _apiClient.PostAsync<BasketData>(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), currentBasket, token); | |||||
int i = 0; | |||||
} | |||||
async Task<string> GetUserTokenAsync() | |||||
{ | |||||
var context = _httpContextAccessor.HttpContext; | |||||
return await context.GetTokenAsync("access_token"); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,43 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using Newtonsoft.Json; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services | |||||
{ | |||||
public class CatalogService : ICatalogService | |||||
{ | |||||
private readonly IHttpClient _apiClient; | |||||
private readonly ILogger<CatalogService> _logger; | |||||
private readonly UrlsConfig _urls; | |||||
public CatalogService(IHttpClient httpClient, ILogger<CatalogService> logger, IOptionsSnapshot<UrlsConfig> config) | |||||
{ | |||||
_apiClient = httpClient; | |||||
_logger = logger; | |||||
_urls = config.Value; | |||||
} | |||||
public async Task<CatalogItem> GetCatalogItem(int id) | |||||
{ | |||||
var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id)); | |||||
var item = JsonConvert.DeserializeObject<CatalogItem>(data); | |||||
return item; | |||||
} | |||||
public async Task<IEnumerable<CatalogItem>> GetCatalogItems(IEnumerable<int> ids) | |||||
{ | |||||
var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids)); | |||||
var item = JsonConvert.DeserializeObject<CatalogItem[]>(data); | |||||
return item; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,15 @@ | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services | |||||
{ | |||||
public interface IBasketService | |||||
{ | |||||
Task<BasketData> GetById(string id); | |||||
Task Update(BasketData currentBasket); | |||||
} | |||||
} |
@ -0,0 +1,14 @@ | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services | |||||
{ | |||||
public interface ICatalogService | |||||
{ | |||||
Task<CatalogItem> GetCatalogItem(int id); | |||||
Task<IEnumerable<CatalogItem>> GetCatalogItems(IEnumerable<int> ids); | |||||
} | |||||
} |
@ -0,0 +1,13 @@ | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services | |||||
{ | |||||
public interface IOrderApiClient | |||||
{ | |||||
Task<OrderData> GetOrderDraftFromBasket(BasketData basket); | |||||
} | |||||
} |
@ -0,0 +1,37 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using Newtonsoft.Json; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services | |||||
{ | |||||
public class OrderApiClient : IOrderApiClient | |||||
{ | |||||
private readonly IHttpClient _apiClient; | |||||
private readonly ILogger<OrderApiClient> _logger; | |||||
private readonly UrlsConfig _urls; | |||||
public OrderApiClient(IHttpClient httpClient, ILogger<OrderApiClient> logger, IOptionsSnapshot<UrlsConfig> config) | |||||
{ | |||||
_apiClient = httpClient; | |||||
_logger = logger; | |||||
_urls = config.Value; | |||||
} | |||||
public async Task<OrderData> GetOrderDraftFromBasket(BasketData basket) | |||||
{ | |||||
var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft(); | |||||
var response = await _apiClient.PostAsync<BasketData>(url, basket); | |||||
response.EnsureSuccessStatusCode(); | |||||
var jsonResponse = await response.Content.ReadAsStringAsync(); | |||||
return JsonConvert.DeserializeObject<OrderData>(jsonResponse); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,138 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IdentityModel.Tokens.Jwt; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNetCore.Authentication.JwtBearer; | |||||
using Microsoft.AspNetCore.Builder; | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using Microsoft.AspNetCore.Http; | |||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.Extensions.Options; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters; | |||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services; | |||||
using Swashbuckle.AspNetCore.Swagger; | |||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator | |||||
{ | |||||
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 void ConfigureServices(IServiceCollection services) | |||||
{ | |||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); | |||||
services.AddSingleton<IHttpClient, StandardHttpClient>(); | |||||
services.AddTransient<ICatalogService, CatalogService>(); | |||||
services.AddTransient<IBasketService, BasketService>(); | |||||
services.AddTransient<IOrderApiClient, OrderApiClient>(); | |||||
services.AddOptions(); | |||||
services.Configure<UrlsConfig>(Configuration.GetSection("urls")); | |||||
services.AddMvc(); | |||||
services.AddSwaggerGen(options => | |||||
{ | |||||
options.DescribeAllEnumsAsStrings(); | |||||
options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info | |||||
{ | |||||
Title = "Shopping Aggregator for Web Clients", | |||||
Version = "v1", | |||||
Description = "Shopping Aggregator for Web Clients", | |||||
TermsOfService = "Terms Of Service" | |||||
}); | |||||
options.AddSecurityDefinition("oauth2", new OAuth2Scheme | |||||
{ | |||||
Type = "oauth2", | |||||
Flow = "implicit", | |||||
AuthorizationUrl = $"{Configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize", | |||||
TokenUrl = $"{Configuration.GetValue<string>("IdentityUrlExternal")}/connect/token", | |||||
Scopes = new Dictionary<string, string>() | |||||
{ | |||||
{ "webshoppingagg", "Shopping Aggregator for Web Clients" } | |||||
} | |||||
}); | |||||
options.OperationFilter<AuthorizeCheckOperationFilter>(); | |||||
}); | |||||
services.AddCors(options => | |||||
{ | |||||
options.AddPolicy("CorsPolicy", | |||||
builder => builder.AllowAnyOrigin() | |||||
.AllowAnyMethod() | |||||
.AllowAnyHeader() | |||||
.AllowCredentials()); | |||||
}); | |||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); | |||||
var identityUrl = Configuration.GetValue<string>("urls:identity"); | |||||
services.AddAuthentication(options => | |||||
{ | |||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; | |||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; | |||||
}).AddJwtBearer(options => | |||||
{ | |||||
options.Authority = identityUrl; | |||||
options.RequireHttpsMetadata = false; | |||||
options.Audience = "webshoppingagg"; | |||||
options.Events = new JwtBearerEvents() | |||||
{ | |||||
OnAuthenticationFailed = async ctx => | |||||
{ | |||||
int i = 0; | |||||
}, | |||||
OnTokenValidated = async ctx => | |||||
{ | |||||
int i = 0; | |||||
} | |||||
}; | |||||
}); | |||||
} | |||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) | |||||
{ | |||||
var pathBase = Configuration["PATH_BASE"]; | |||||
if (!string.IsNullOrEmpty(pathBase)) | |||||
{ | |||||
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'"); | |||||
app.UsePathBase(pathBase); | |||||
} | |||||
app.UseCors("CorsPolicy"); | |||||
if (env.IsDevelopment()) | |||||
{ | |||||
app.UseDeveloperExceptionPage(); | |||||
} | |||||
app.UseAuthentication(); | |||||
app.UseMvc(); | |||||
app.UseSwagger().UseSwaggerUI(c => | |||||
{ | |||||
c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1"); | |||||
c.ConfigureOAuth2("Microsoft.eShopOnContainers.Web.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI"); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,27 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk.Web"> | |||||
<PropertyGroup> | |||||
<TargetFramework>netcoreapp2.0</TargetFramework> | |||||
<AssemblyName>Web.Shopping.HttpAggregator</AssemblyName> | |||||
<RootNamespace>Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator</RootNamespace> | |||||
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Folder Include="wwwroot\" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" /> | |||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.1.0" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\..\..\BuildingBlocks\Resilience\Resilience.Http\Resilience.Http.csproj" /> | |||||
</ItemGroup> | |||||
</Project> |
@ -0,0 +1,15 @@ | |||||
{ | |||||
"Logging": { | |||||
"IncludeScopes": false, | |||||
"Debug": { | |||||
"LogLevel": { | |||||
"Default": "Warning" | |||||
} | |||||
}, | |||||
"Console": { | |||||
"LogLevel": { | |||||
"Default": "Warning" | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,8 @@ | |||||
{ | |||||
"urls": { | |||||
"basket": "http://localhost:55105", | |||||
"catalog": "http://localhost:55101", | |||||
"orders": "http://localhost:55102", | |||||
"identity": "http://localhost:55105" | |||||
} | |||||
} |
@ -0,0 +1,142 @@ | |||||
{ | |||||
"ReRoutes": [ | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "catalog.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/c/{everything}", | |||||
"UpstreamHttpMethod": [ "GET" ] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "basket.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/b/{everything}", | |||||
"UpstreamHttpMethod": [], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/api/{version}/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "ordering.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/api/{version}/o/{everything}", | |||||
"UpstreamHttpMethod": [], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "webshoppingagg", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/{everything}", | |||||
"UpstreamHttpMethod": [ "POST", "PUT", "GET" ], | |||||
"AuthenticationOptions": { | |||||
"AuthenticationProviderKey": "IdentityApiKey", | |||||
"AllowedScopes": [] | |||||
} | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "ordering.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/orders-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "basket.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/basket-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "catalog.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/catalog-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "marketing.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/marketing-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "payment.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/payment-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
}, | |||||
{ | |||||
"DownstreamPathTemplate": "/{everything}", | |||||
"DownstreamScheme": "http", | |||||
"DownstreamHostAndPorts": [ | |||||
{ | |||||
"Host": "locations.api", | |||||
"Port": 80 | |||||
} | |||||
], | |||||
"UpstreamPathTemplate": "/location-api/{everything}", | |||||
"UpstreamHttpMethod": [] | |||||
} | |||||
], | |||||
"GlobalConfiguration": { | |||||
"RequestIdKey": "OcRequestId", | |||||
"AdministrationPath": "/administration" | |||||
} | |||||
} | |||||
@ -1,13 +0,0 @@ | |||||
namespace eShopOnContainers.Core.Services.Settings | |||||
{ | |||||
public interface ISettingsServiceImplementation | |||||
{ | |||||
bool GetValueOrDefault(string key, bool defaultValue); | |||||
string GetValueOrDefault(string key, string defaultValue); | |||||
bool AddOrUpdateValue(string key, bool value); | |||||
bool AddOrUpdateValue(string key, string value); | |||||
void Remove(string key); | |||||
} | |||||
} |
@ -1,149 +0,0 @@ | |||||
using Android.App; | |||||
using Android.Content; | |||||
using Android.Preferences; | |||||
using eShopOnContainers.Core.Services.Settings; | |||||
using eShopOnContainers.Droid.Services; | |||||
using System; | |||||
[assembly: Xamarin.Forms.Dependency(typeof(SettingsServiceImplementation))] | |||||
namespace eShopOnContainers.Droid.Services | |||||
{ | |||||
public class SettingsServiceImplementation : ISettingsServiceImplementation | |||||
{ | |||||
#region Internal Implementation | |||||
readonly object _locker = new object(); | |||||
ISharedPreferences GetSharedPreference() | |||||
{ | |||||
return PreferenceManager.GetDefaultSharedPreferences(Application.Context); | |||||
} | |||||
bool AddOrUpdateValueInternal<T>(string key, T value) | |||||
{ | |||||
if (Application.Context == null) | |||||
return false; | |||||
if (value == null) | |||||
{ | |||||
Remove(key); | |||||
return true; | |||||
} | |||||
var type = typeof(T); | |||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) | |||||
{ | |||||
type = Nullable.GetUnderlyingType(type); | |||||
} | |||||
var typeCode = Type.GetTypeCode(type); | |||||
lock (_locker) | |||||
{ | |||||
using (var sharedPrefs = GetSharedPreference()) | |||||
{ | |||||
using (var editor = sharedPrefs.Edit()) | |||||
{ | |||||
switch (typeCode) | |||||
{ | |||||
case TypeCode.Boolean: | |||||
editor.PutBoolean(key, Convert.ToBoolean(value)); | |||||
break; | |||||
case TypeCode.String: | |||||
editor.PutString(key, Convert.ToString(value)); | |||||
break; | |||||
default: | |||||
throw new ArgumentException($"Value of type {typeCode} is not supported."); | |||||
} | |||||
editor.Commit(); | |||||
} | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
T GetValueOrDefaultInternal<T>(string key, T defaultValue = default(T)) | |||||
{ | |||||
if (Application.Context == null) | |||||
return defaultValue; | |||||
if (!Contains(key)) | |||||
return defaultValue; | |||||
lock (_locker) | |||||
{ | |||||
using (var sharedPrefs = GetSharedPreference()) | |||||
{ | |||||
var type = typeof(T); | |||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) | |||||
{ | |||||
type = Nullable.GetUnderlyingType(type); | |||||
} | |||||
object value = null; | |||||
var typeCode = Type.GetTypeCode(type); | |||||
switch (typeCode) | |||||
{ | |||||
case TypeCode.Boolean: | |||||
value = sharedPrefs.GetBoolean(key, Convert.ToBoolean(defaultValue)); | |||||
break; | |||||
case TypeCode.String: | |||||
value = sharedPrefs.GetString(key, Convert.ToString(defaultValue)); | |||||
break; | |||||
default: | |||||
throw new ArgumentException($"Value of type {typeCode} is not supported."); | |||||
} | |||||
return null != value ? (T)value : defaultValue; | |||||
} | |||||
} | |||||
} | |||||
bool Contains(string key) | |||||
{ | |||||
if (Application.Context == null) | |||||
return false; | |||||
lock (_locker) | |||||
{ | |||||
using (var sharedPrefs = GetSharedPreference()) | |||||
{ | |||||
if (sharedPrefs == null) | |||||
return false; | |||||
return sharedPrefs.Contains(key); | |||||
} | |||||
} | |||||
} | |||||
#endregion | |||||
#region ISettingsServiceImplementation | |||||
public bool AddOrUpdateValue(string key, bool value) => AddOrUpdateValueInternal(key, value); | |||||
public bool AddOrUpdateValue(string key, string value) => AddOrUpdateValueInternal(key, value); | |||||
public bool GetValueOrDefault(string key, bool defaultValue) => GetValueOrDefaultInternal(key, defaultValue); | |||||
public string GetValueOrDefault(string key, string defaultValue) => GetValueOrDefaultInternal(key, defaultValue); | |||||
public void Remove(string key) | |||||
{ | |||||
if (Application.Context == null) | |||||
return; | |||||
lock (_locker) | |||||
{ | |||||
using (var sharedPrefs = GetSharedPreference()) | |||||
{ | |||||
using (var editor = sharedPrefs.Edit()) | |||||
{ | |||||
editor.Remove(key); | |||||
editor.Commit(); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
#endregion | |||||
} | |||||
} |
@ -1,429 +0,0 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\build\netstandard1.0\Xamarin.Forms.props" Condition="Exists('..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\build\netstandard1.0\Xamarin.Forms.props')" /> | |||||
<PropertyGroup> | |||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||||
<ProductVersion>8.0.30703</ProductVersion> | |||||
<SchemaVersion>2.0</SchemaVersion> | |||||
<ProjectGuid>{62DBB163-9CA9-4818-B48B-13233DF37C24}</ProjectGuid> | |||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | |||||
<OutputType>Library</OutputType> | |||||
<AppDesignerFolder>Properties</AppDesignerFolder> | |||||
<RootNamespace>eShopOnContainers.Droid</RootNamespace> | |||||
<AssemblyName>eShopOnContainers.Droid</AssemblyName> | |||||
<FileAlignment>512</FileAlignment> | |||||
<AndroidApplication>true</AndroidApplication> | |||||
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile> | |||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> | |||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest> | |||||
<AndroidUseLatestPlatformSdk>true</AndroidUseLatestPlatformSdk> | |||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion> | |||||
<AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis> | |||||
<AndroidStoreUncompressedFileExtensions /> | |||||
<MandroidI18n /> | |||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize> | |||||
<JavaOptions /> | |||||
<NuGetPackageImportStamp> | |||||
</NuGetPackageImportStamp> | |||||
<AndroidTlsProvider> | |||||
</AndroidTlsProvider> | |||||
<SkipValidatePackageReferences>true</SkipValidatePackageReferences> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||||
<DebugSymbols>True</DebugSymbols> | |||||
<DebugType>full</DebugType> | |||||
<Optimize>false</Optimize> | |||||
<OutputPath>bin\Debug\</OutputPath> | |||||
<DefineConstants>DEBUG;TRACE</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime> | |||||
<AndroidLinkMode>None</AndroidLinkMode> | |||||
<EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk> | |||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize> | |||||
<Debugger>Xamarin</Debugger> | |||||
<AndroidSupportedAbis>armeabi;armeabi-v7a;x86</AndroidSupportedAbis> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||||
<DebugType>pdbonly</DebugType> | |||||
<Optimize>true</Optimize> | |||||
<OutputPath>bin\Release\</OutputPath> | |||||
<DefineConstants>TRACE</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime> | |||||
<AndroidLinkMode>SdkOnly</AndroidLinkMode> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Reference Include="Acr.Support.Android, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Acr.Support.2.1.0\lib\MonoAndroid10\Acr.Support.Android.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="AndHUD, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\AndHUD.1.2.0\lib\MonoAndroid\AndHUD.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.2.2.9\lib\MonoAndroid10\FFImageLoading.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.2.2.9\lib\MonoAndroid10\FFImageLoading.Platform.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="IdentityModel.Portable, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\IdentityModel.1.3.1\lib\portable-net45+wp80+win8+wpa81\IdentityModel.Portable.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Microsoft.CSharp" /> | |||||
<Reference Include="ModernHttpClient, Version=2.4.2.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\modernhttpclient.2.4.2\lib\MonoAndroid\ModernHttpClient.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Mono.Android" /> | |||||
<Reference Include="mscorlib" /> | |||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="OkHttp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\modernhttpclient.2.4.2\lib\MonoAndroid\OkHttp.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="PCLCrypto, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d4421c8a4786956c, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\PCLCrypto.2.0.147\lib\MonoAndroid23\PCLCrypto.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.BCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.Kernel32, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.NCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.Windows.Core, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Plugin.CurrentActivity, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Plugin.CurrentActivity.1.0.1\lib\MonoAndroid10\Plugin.CurrentActivity.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Plugin.Geolocator, Version=3.0.4.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xam.Plugin.Geolocator.3.0.4\lib\MonoAndroid10\Plugin.Geolocator.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Plugin.Geolocator.Abstractions, Version=3.0.4.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xam.Plugin.Geolocator.3.0.4\lib\MonoAndroid10\Plugin.Geolocator.Abstractions.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Plugin.Permissions, Version=1.1.6.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Plugin.Permissions.1.1.7\lib\MonoAndroid10\Plugin.Permissions.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Plugin.Permissions.Abstractions, Version=1.1.6.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Plugin.Permissions.1.1.7\lib\MonoAndroid10\Plugin.Permissions.Abstractions.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Plugin.Settings, Version=2.6.0.12, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xam.Plugins.Settings.2.6.0.12-beta\lib\MonoAndroid10\Plugin.Settings.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Plugin.Settings.Abstractions, Version=2.6.0.12, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xam.Plugins.Settings.2.6.0.12-beta\lib\MonoAndroid10\Plugin.Settings.Abstractions.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="SlideOverKit, Version=1.0.6135.18790, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\SlideOverKit.2.1.4\lib\MonoAndroid10\SlideOverKit.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="SlideOverKit.Droid, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\SlideOverKit.2.1.4\lib\MonoAndroid10\SlideOverKit.Droid.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Splat.1.6.2\lib\monoandroid\Splat.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="System" /> | |||||
<Reference Include="System.Core" /> | |||||
<Reference Include="System.Net.Http" /> | |||||
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Microsoft.Net.Http.2.2.29\lib\monoandroid\System.Net.Http.Extensions.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Microsoft.Net.Http.2.2.29\lib\monoandroid\System.Net.Http.Primitives.dll</HintPath> | |||||
<Private>True</Private> | |||||
</Reference> | |||||
<Reference Include="System.Xml.Linq" /> | |||||
<Reference Include="System.Xml" /> | |||||
<Reference Include="Validation, Version=2.2.0.0, Culture=neutral, PublicKeyToken=2fc06f0d701809a7, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="System.IO.Compression" /> | |||||
<Reference Include="Autofac"> | |||||
<HintPath>..\..\..\..\packages\Autofac.4.5.0\lib\netstandard1.1\Autofac.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Acr.UserDialogs"> | |||||
<HintPath>..\..\..\..\packages\Acr.UserDialogs.6.3.8\lib\MonoAndroid10\Acr.UserDialogs.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Acr.UserDialogs.Interface"> | |||||
<HintPath>..\..\..\..\packages\Acr.UserDialogs.6.3.8\lib\MonoAndroid10\Acr.UserDialogs.Interface.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FormsViewGroup"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\lib\MonoAndroid10\FormsViewGroup.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Core"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\lib\MonoAndroid10\Xamarin.Forms.Core.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Platform.Android"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Platform"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\lib\MonoAndroid10\Xamarin.Forms.Platform.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Xaml"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading.Forms"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.2.9\lib\MonoAndroid10\FFImageLoading.Forms.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading.Forms.Droid"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.2.9\lib\MonoAndroid10\FFImageLoading.Forms.Droid.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Animated.Vector.Drawable"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Vector.Drawable"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.Vector.Drawable.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Vector.Drawable.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.v7.RecyclerView"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.v7.RecyclerView.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v7.RecyclerView.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Annotations"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.Annotations.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Annotations.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Compat"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.Compat.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Compat.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.v7.CardView"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.v7.CardView.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v7.CardView.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Media.Compat"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.Media.Compat.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Media.Compat.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Core.UI"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.Core.UI.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Core.UI.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Core.Utils"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.Core.Utils.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Core.Utils.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Fragment"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.Fragment.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Fragment.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Design"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.Design.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Design.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.Transition"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.Transition.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Transition.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.v4"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.v4.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v4.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.v7.Palette"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.v7.Palette.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v7.Palette.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.v7.AppCompat"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.v7.AppCompat.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v7.AppCompat.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Android.Support.v7.MediaRouter"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Android.Support.v7.MediaRouter.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v7.MediaRouter.dll</HintPath> | |||||
</Reference> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Compile Include="Activities\MainActivity.cs" /> | |||||
<Compile Include="Effects\EntryLineColorEffect.cs" /> | |||||
<Compile Include="Extensions\ViewExtensions.cs" /> | |||||
<Compile Include="Helpers\Settings.cs" /> | |||||
<Compile Include="MainApplication.cs" /> | |||||
<Compile Include="Renderers\BadgeView.cs" /> | |||||
<Compile Include="Renderers\CustomNavigationPageRenderer.cs" /> | |||||
<Compile Include="Renderers\CustomTabbedPageRenderer.cs" /> | |||||
<Compile Include="Renderers\SlideDownMenuPageRenderer.cs" /> | |||||
<Compile Include="Resources\Resource.Designer.cs" /> | |||||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||||
<Compile Include="Effects\CircleEffect.cs" /> | |||||
<Compile Include="Effects\BaseContainerEffect.cs" /> | |||||
<Compile Include="Activities\SplashActivity.cs" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidAsset Include="..\CommonResources\Fonts\Montserrat-Bold.ttf"> | |||||
<Link>Assets\Montserrat-Bold.ttf</Link> | |||||
</AndroidAsset> | |||||
<AndroidAsset Include="..\CommonResources\Fonts\Montserrat-Regular.ttf"> | |||||
<Link>Assets\Montserrat-Regular.ttf</Link> | |||||
</AndroidAsset> | |||||
<AndroidAsset Include="..\CommonResources\Fonts\SourceSansPro-Regular.ttf"> | |||||
<Link>Assets\SourceSansPro-Regular.ttf</Link> | |||||
</AndroidAsset> | |||||
<None Include="app.config" /> | |||||
<None Include="packages.config" /> | |||||
<None Include="Resources\AboutResources.txt" /> | |||||
<None Include="Assets\AboutAssets.txt" /> | |||||
<AndroidResource Include="Resources\drawable-xxhdpi\switch_off.png" /> | |||||
<AndroidResource Include="Resources\drawable-xxhdpi\switch_on.png" /> | |||||
<AndroidResource Include="Resources\layout\Tabs.axml"> | |||||
<SubType>Designer</SubType> | |||||
</AndroidResource> | |||||
<AndroidResource Include="Resources\layout\Toolbar.axml"> | |||||
<SubType>Designer</SubType> | |||||
</AndroidResource> | |||||
<AndroidResource Include="Resources\layout\TabLayout.axml"> | |||||
<SubType>Designer</SubType> | |||||
</AndroidResource> | |||||
<AndroidResource Include="Resources\drawable-hdpi\menu_campaigns.png" /> | |||||
<AndroidResource Include="Resources\drawable-xhdpi\menu_campaigns.png" /> | |||||
<AndroidResource Include="Resources\drawable-xxhdpi\menu_campaigns.png" /> | |||||
<AndroidResource Include="Resources\drawable-hdpi\menu_filter.png" /> | |||||
<AndroidResource Include="Resources\drawable-xhdpi\menu_filter.png" /> | |||||
<AndroidResource Include="Resources\drawable-xxhdpi\menu_filter.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\icon.png" /> | |||||
<AndroidResource Include="Resources\drawable-hdpi\icon.png" /> | |||||
<AndroidResource Include="Resources\drawable-xhdpi\icon.png" /> | |||||
<AndroidResource Include="Resources\drawable-xxhdpi\icon.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Include="Properties\AndroidManifest.xml" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\values\styles.xml" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\fake_product_01.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\fake_product_03.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\fake_product_02.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-hdpi\menu_profile.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xhdpi\menu_profile.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xxhdpi\menu_profile.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-hdpi\menu_cart.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xhdpi\menu_cart.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xxhdpi\menu_cart.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xxhdpi\product_add.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xhdpi\product_add.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-hdpi\product_add.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\values\colors.xml" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-hdpi\background.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xhdpi\background.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xxhdpi\background.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\fake_product_04.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\fake_product_05.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-hdpi\app_settings.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xhdpi\app_settings.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xxhdpi\app_settings.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-hdpi\switch_on.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xhdpi\switch_on.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-hdpi\switch_off.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xhdpi\switch_off.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\noimage.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\default_product.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\banner.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-hdpi\header_logo.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xhdpi\header_logo.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable-xxhdpi\header_logo.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\fake_campaign_02.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\fake_campaign_01.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<AndroidResource Include="Resources\drawable\default_campaign.png" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\eShopOnContainers.Core\eShopOnContainers.Core.csproj"> | |||||
<Project>{ba96a12c-4ee3-46c4-bb3f-f811b554cd01}</Project> | |||||
<Name>eShopOnContainers.Core</Name> | |||||
</ProjectReference> | |||||
</ItemGroup> | |||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> | |||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||||
<PropertyGroup> | |||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | |||||
</PropertyGroup> | |||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" /> | |||||
</Target> | |||||
<Import Project="..\..\..\..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\build\netstandard1.0\Xamarin.Forms.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\build\netstandard1.0\Xamarin.Forms.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.Vector.Drawable.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Vector.Drawable.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.Vector.Drawable.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Vector.Drawable.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.v7.RecyclerView.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.RecyclerView.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.v7.RecyclerView.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.RecyclerView.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.Compat.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Compat.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.Compat.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Compat.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.v7.CardView.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.CardView.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.v7.CardView.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.CardView.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.Media.Compat.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Media.Compat.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.Media.Compat.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Media.Compat.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.Core.UI.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Core.UI.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.Core.UI.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Core.UI.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.Core.Utils.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Core.Utils.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.Core.Utils.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Core.Utils.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.Fragment.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Fragment.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.Fragment.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Fragment.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.Design.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Design.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.Design.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Design.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.Transition.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Transition.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.Transition.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Transition.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.v4.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v4.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.v4.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v4.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.v7.Palette.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.Palette.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.v7.Palette.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.Palette.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.v7.AppCompat.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.AppCompat.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.v7.AppCompat.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.AppCompat.targets')" /> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Android.Support.v7.MediaRouter.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.MediaRouter.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Android.Support.v7.MediaRouter.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.MediaRouter.targets')" /> | |||||
</Project> |
@ -1,232 +1,232 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
<Import Project="..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.props" Condition="Exists('..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.props')" /> | |||||
<Import Project="..\..\..\..\packages\xunit.core.2.3.1\build\xunit.core.props" Condition="Exists('..\..\..\..\packages\xunit.core.2.3.1\build\xunit.core.props')" /> | |||||
<PropertyGroup> | |||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||||
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform> | |||||
<ProjectGuid>{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}</ProjectGuid> | |||||
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | |||||
<OutputType>Exe</OutputType> | |||||
<RootNamespace>eShopOnContainers.TestRunner.iOS</RootNamespace> | |||||
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix> | |||||
<AssemblyName>eShopOnContainersTestRunneriOS</AssemblyName> | |||||
<NuGetPackageImportStamp> | |||||
</NuGetPackageImportStamp> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' "> | |||||
<DebugSymbols>true</DebugSymbols> | |||||
<DebugType>full</DebugType> | |||||
<Optimize>false</Optimize> | |||||
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath> | |||||
<DefineConstants>DEBUG</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>false</ConsolePause> | |||||
<MtouchArch>x86_64</MtouchArch> | |||||
<MtouchLink>None</MtouchLink> | |||||
<MtouchDebug>True</MtouchDebug> | |||||
<MtouchProfiling>False</MtouchProfiling> | |||||
<MtouchFastDev>False</MtouchFastDev> | |||||
<MtouchUseLlvm>False</MtouchUseLlvm> | |||||
<MtouchUseThumb>False</MtouchUseThumb> | |||||
<MtouchEnableBitcode>False</MtouchEnableBitcode> | |||||
<OptimizePNGs>True</OptimizePNGs> | |||||
<MtouchTlsProvider>Default</MtouchTlsProvider> | |||||
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler> | |||||
<MtouchFloat32>False</MtouchFloat32> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' "> | |||||
<DebugSymbols>false</DebugSymbols> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>true</Optimize> | |||||
<OutputPath>bin\iPhoneSimulator\Release</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<MtouchLink>None</MtouchLink> | |||||
<MtouchArch>x86_64</MtouchArch> | |||||
<ConsolePause>false</ConsolePause> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' "> | |||||
<DebugSymbols>true</DebugSymbols> | |||||
<DebugType>full</DebugType> | |||||
<Optimize>false</Optimize> | |||||
<OutputPath>bin\iPhone\Debug</OutputPath> | |||||
<DefineConstants>DEBUG</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>false</ConsolePause> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<CodesignKey>iPhone Developer</CodesignKey> | |||||
<MtouchDebug>true</MtouchDebug> | |||||
<MtouchLink>None</MtouchLink> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' "> | |||||
<DebugSymbols>false</DebugSymbols> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>true</Optimize> | |||||
<OutputPath>bin\iPhone\Release</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<ConsolePause>false</ConsolePause> | |||||
<CodesignKey>iPhone Developer</CodesignKey> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' "> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>True</Optimize> | |||||
<OutputPath>bin\iPhone\Ad-Hoc</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>False</ConsolePause> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<BuildIpa>True</BuildIpa> | |||||
<CodesignProvision>Automatic:AdHoc</CodesignProvision> | |||||
<CodesignKey>iPhone Distribution</CodesignKey> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' "> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>True</Optimize> | |||||
<OutputPath>bin\iPhone\AppStore</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>False</ConsolePause> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<CodesignProvision>Automatic:AppStore</CodesignProvision> | |||||
<CodesignKey>iPhone Distribution</CodesignKey> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Compile Include="Main.cs" /> | |||||
<Compile Include="AppDelegate.cs" /> | |||||
<None Include="app.config" /> | |||||
<None Include="Info.plist" /> | |||||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||||
<InterfaceDefinition Include="Resources\LaunchScreen.xib" /> | |||||
<None Include="packages.config" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Reference Include="System" /> | |||||
<Reference Include="System.Xml" /> | |||||
<Reference Include="System.Core" /> | |||||
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Platform.iOS, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Xaml, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.iOS" /> | |||||
<Reference Include="System.IO.Compression" /> | |||||
<Reference Include="System.Net.Http" /> | |||||
<Reference Include="xunit.runner.devices"> | |||||
<HintPath>..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.devices.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="xunit.runner.utility.netstandard15"> | |||||
<HintPath>..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.utility.netstandard15.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="xunit.abstractions"> | |||||
<HintPath>..\..\..\..\packages\xunit.abstractions.2.0.1\lib\netstandard1.0\xunit.abstractions.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="xunit.assert"> | |||||
<HintPath>..\..\..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="xunit.core"> | |||||
<HintPath>..\..\..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="xunit.execution.dotnet"> | |||||
<HintPath>..\..\..\..\packages\xunit.extensibility.execution.2.3.1\lib\netstandard1.1\xunit.execution.dotnet.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Microsoft.CSharp" /> | |||||
<Reference Include="Newtonsoft.Json"> | |||||
<HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="SlideOverKit"> | |||||
<HintPath>..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="SlideOverKit.iOS"> | |||||
<HintPath>..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.iOS.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="IdentityModel"> | |||||
<HintPath>..\..\..\..\packages\IdentityModel.3.0.0\lib\netstandard2.0\IdentityModel.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Acr.Support.iOS"> | |||||
<HintPath>..\..\..\..\packages\Acr.Support.2.1.0\lib\Xamarin.iOS10\Acr.Support.iOS.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="BTProgressHUD"> | |||||
<HintPath>..\..\..\..\packages\BTProgressHUD.1.2.0.5\lib\Xamarin.iOS10\BTProgressHUD.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Splat"> | |||||
<HintPath>..\..\..\..\packages\Splat.2.0.0\lib\Xamarin.iOS10\Splat.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Acr.UserDialogs"> | |||||
<HintPath>..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Acr.UserDialogs.Interface"> | |||||
<HintPath>..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.Interface.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="WebP.Touch"> | |||||
<HintPath>..\..\..\..\packages\WebP.Touch.1.0.7\lib\Xamarin.iOS10\WebP.Touch.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading.Platform"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Platform.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading.Forms"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading.Forms.Touch"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.Touch.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.Windows.Core"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.Kernel32"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.BCrypt"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.NCrypt"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Validation"> | |||||
<HintPath>..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PCLCrypto"> | |||||
<HintPath>..\..\..\..\packages\PCLCrypto.2.0.147\lib\xamarinios10\PCLCrypto.dll</HintPath> | |||||
</Reference> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Content Include="Entitlements.plist" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj"> | |||||
<Project>{FDD910BC-DF0F-483D-B7D5-C7D831855172}</Project> | |||||
<Name>eShopOnContainers.UnitTests</Name> | |||||
</ProjectReference> | |||||
</ItemGroup> | |||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" /> | |||||
<Import Project="..\..\..\..\packages\xunit.runner.devices.2.3.3\build\xamarinios10\xunit.runner.devices.targets" Condition="Exists('..\..\..\..\packages\xunit.runner.devices.2.3.3\build\xamarinios10\xunit.runner.devices.targets')" /> | |||||
<Import Project="..\..\..\..\packages\xunit.core.2.3.1\build\xunit.core.targets" Condition="Exists('..\..\..\..\packages\xunit.core.2.3.1\build\xunit.core.targets')" /> | |||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.props" Condition="Exists('..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.props')" /> | |||||
<Import Project="..\..\..\..\packages\xunit.core.2.3.1\build\xunit.core.props" Condition="Exists('..\..\..\..\packages\xunit.core.2.3.1\build\xunit.core.props')" /> | |||||
<PropertyGroup> | <PropertyGroup> | ||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | |||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||||
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform> | |||||
<ProjectGuid>{B68C2B56-7581-46AE-B55D-D25DDFD3BFE3}</ProjectGuid> | |||||
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | |||||
<OutputType>Exe</OutputType> | |||||
<RootNamespace>eShopOnContainers.TestRunner.iOS</RootNamespace> | |||||
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix> | |||||
<AssemblyName>eShopOnContainersTestRunneriOS</AssemblyName> | |||||
<NuGetPackageImportStamp> | |||||
</NuGetPackageImportStamp> | |||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<Error Condition="!Exists('..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.props'))" /> | |||||
<Error Condition="!Exists('..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.targets'))" /> | |||||
<Error Condition="!Exists('..\..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets'))" /> | |||||
</Target> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.targets')" /> | |||||
<Import Project="..\..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('..\..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets')" /> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' "> | |||||
<DebugSymbols>true</DebugSymbols> | |||||
<DebugType>full</DebugType> | |||||
<Optimize>false</Optimize> | |||||
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath> | |||||
<DefineConstants>DEBUG</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>false</ConsolePause> | |||||
<MtouchArch>x86_64</MtouchArch> | |||||
<MtouchLink>None</MtouchLink> | |||||
<MtouchDebug>True</MtouchDebug> | |||||
<MtouchProfiling>False</MtouchProfiling> | |||||
<MtouchFastDev>False</MtouchFastDev> | |||||
<MtouchUseLlvm>False</MtouchUseLlvm> | |||||
<MtouchUseThumb>False</MtouchUseThumb> | |||||
<MtouchEnableBitcode>False</MtouchEnableBitcode> | |||||
<OptimizePNGs>True</OptimizePNGs> | |||||
<MtouchTlsProvider>Default</MtouchTlsProvider> | |||||
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler> | |||||
<MtouchFloat32>False</MtouchFloat32> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' "> | |||||
<DebugSymbols>false</DebugSymbols> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>true</Optimize> | |||||
<OutputPath>bin\iPhoneSimulator\Release</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<MtouchLink>None</MtouchLink> | |||||
<MtouchArch>x86_64</MtouchArch> | |||||
<ConsolePause>false</ConsolePause> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' "> | |||||
<DebugSymbols>true</DebugSymbols> | |||||
<DebugType>full</DebugType> | |||||
<Optimize>false</Optimize> | |||||
<OutputPath>bin\iPhone\Debug</OutputPath> | |||||
<DefineConstants>DEBUG</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>false</ConsolePause> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<CodesignKey>iPhone Developer</CodesignKey> | |||||
<MtouchDebug>true</MtouchDebug> | |||||
<MtouchLink>None</MtouchLink> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' "> | |||||
<DebugSymbols>false</DebugSymbols> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>true</Optimize> | |||||
<OutputPath>bin\iPhone\Release</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<ConsolePause>false</ConsolePause> | |||||
<CodesignKey>iPhone Developer</CodesignKey> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' "> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>True</Optimize> | |||||
<OutputPath>bin\iPhone\Ad-Hoc</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>False</ConsolePause> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<BuildIpa>True</BuildIpa> | |||||
<CodesignProvision>Automatic:AdHoc</CodesignProvision> | |||||
<CodesignKey>iPhone Distribution</CodesignKey> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' "> | |||||
<DebugType>none</DebugType> | |||||
<Optimize>True</Optimize> | |||||
<OutputPath>bin\iPhone\AppStore</OutputPath> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
<ConsolePause>False</ConsolePause> | |||||
<MtouchArch>ARMv7, ARM64</MtouchArch> | |||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> | |||||
<CodesignProvision>Automatic:AppStore</CodesignProvision> | |||||
<CodesignKey>iPhone Distribution</CodesignKey> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Compile Include="Main.cs" /> | |||||
<Compile Include="AppDelegate.cs" /> | |||||
<None Include="app.config" /> | |||||
<None Include="Info.plist" /> | |||||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||||
<InterfaceDefinition Include="Resources\LaunchScreen.xib" /> | |||||
<None Include="packages.config" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Reference Include="System" /> | |||||
<Reference Include="System.Xml" /> | |||||
<Reference Include="System.Core" /> | |||||
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Platform.iOS, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.Forms.Xaml, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Xamarin.iOS" /> | |||||
<Reference Include="System.IO.Compression" /> | |||||
<Reference Include="System.Net.Http" /> | |||||
<Reference Include="xunit.runner.devices"> | |||||
<HintPath>..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.devices.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="xunit.runner.utility.netstandard15"> | |||||
<HintPath>..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.utility.netstandard15.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="xunit.abstractions"> | |||||
<HintPath>..\..\..\..\packages\xunit.abstractions.2.0.1\lib\netstandard1.0\xunit.abstractions.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="xunit.assert"> | |||||
<HintPath>..\..\..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="xunit.core"> | |||||
<HintPath>..\..\..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="xunit.execution.dotnet"> | |||||
<HintPath>..\..\..\..\packages\xunit.extensibility.execution.2.3.1\lib\netstandard1.1\xunit.execution.dotnet.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Newtonsoft.Json"> | |||||
<HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="SlideOverKit"> | |||||
<HintPath>..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="SlideOverKit.iOS"> | |||||
<HintPath>..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.iOS.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="IdentityModel"> | |||||
<HintPath>..\..\..\..\packages\IdentityModel.3.0.0\lib\netstandard2.0\IdentityModel.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Acr.Support.iOS"> | |||||
<HintPath>..\..\..\..\packages\Acr.Support.2.1.0\lib\Xamarin.iOS10\Acr.Support.iOS.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="BTProgressHUD"> | |||||
<HintPath>..\..\..\..\packages\BTProgressHUD.1.2.0.5\lib\Xamarin.iOS10\BTProgressHUD.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Splat"> | |||||
<HintPath>..\..\..\..\packages\Splat.2.0.0\lib\Xamarin.iOS10\Splat.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Acr.UserDialogs"> | |||||
<HintPath>..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Acr.UserDialogs.Interface"> | |||||
<HintPath>..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.Interface.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="WebP.Touch"> | |||||
<HintPath>..\..\..\..\packages\WebP.Touch.1.0.7\lib\Xamarin.iOS10\WebP.Touch.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading.Platform"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Platform.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading.Forms"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="FFImageLoading.Forms.Touch"> | |||||
<HintPath>..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.Touch.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.Windows.Core"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.Kernel32"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.BCrypt"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PInvoke.NCrypt"> | |||||
<HintPath>..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Validation"> | |||||
<HintPath>..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="PCLCrypto"> | |||||
<HintPath>..\..\..\..\packages\PCLCrypto.2.0.147\lib\xamarinios10\PCLCrypto.dll</HintPath> | |||||
</Reference> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Content Include="Entitlements.plist" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\eShopOnContainers.UnitTests\eShopOnContainers.UnitTests.csproj"> | |||||
<Project>{FDD910BC-DF0F-483D-B7D5-C7D831855172}</Project> | |||||
<Name>eShopOnContainers.UnitTests</Name> | |||||
</ProjectReference> | |||||
</ItemGroup> | |||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" /> | |||||
<Import Project="..\..\..\..\packages\xunit.runner.devices.2.3.3\build\xamarinios10\xunit.runner.devices.targets" Condition="Exists('..\..\..\..\packages\xunit.runner.devices.2.3.3\build\xamarinios10\xunit.runner.devices.targets')" /> | |||||
<Import Project="..\..\..\..\packages\xunit.core.2.3.1\build\xunit.core.targets" Condition="Exists('..\..\..\..\packages\xunit.core.2.3.1\build\xunit.core.targets')" /> | |||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||||
<PropertyGroup> | |||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | |||||
</PropertyGroup> | |||||
<Error Condition="!Exists('..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.props'))" /> | |||||
<Error Condition="!Exists('..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.targets'))" /> | |||||
<Error Condition="!Exists('..\..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets'))" /> | |||||
</Target> | |||||
<Import Project="..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.targets" Condition="Exists('..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\build\netstandard1.0\Xamarin.Forms.targets')" /> | |||||
<Import Project="..\..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('..\..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets')" /> | |||||
</Project> | </Project> |