@ -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"?> | |||
<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> | |||
<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> | |||
<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> |