diff --git a/.dockerignore b/.dockerignore index e58ae957a..f4850f3c7 100644 --- a/.dockerignore +++ b/.dockerignore @@ -13,7 +13,6 @@ hosts LICENSE *.testsettings vsts-docs -test ServiceFabric readme k8s @@ -32,5 +31,4 @@ cli-linux !**/wwwroot/lib/signalr/* !**/wwwroot/lib/toastr/* global.json -**/appsettings.localhost.json src/Web/WebSPA/wwwroot/ \ No newline at end of file diff --git a/.env b/.env index 28a94504c..24e293653 100644 --- a/.env +++ b/.env @@ -24,4 +24,4 @@ ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.162 #ESHOP_SERVICE_BUS_USERNAME= #ESHOP_SERVICE_BUS_PASSWORD= #INSTRUMENTATION_KEY= -#USE_LOADTEST= \ No newline at end of file +#USE_LOADTEST= diff --git a/.gitignore b/.gitignore index 3c690a758..1a11f9674 100644 --- a/.gitignore +++ b/.gitignore @@ -262,4 +262,3 @@ pub/ /src/Web/WebMVC/wwwroot/lib /src/Web/WebMVC/wwwroot/css/site.min.css **/.kube/** -.mfractor diff --git a/docker-compose.dcproj b/docker-compose.dcproj index 296c4b5e0..b9522f28f 100644 --- a/docker-compose.dcproj +++ b/docker-compose.dcproj @@ -7,7 +7,6 @@ webmvc Linux 2.1 - LaunchBrowser diff --git a/k8s/conf_cloud.yaml b/k8s/conf_cloud.yaml index a914105ae..624d3a59b 100644 --- a/k8s/conf_cloud.yaml +++ b/k8s/conf_cloud.yaml @@ -3,12 +3,14 @@ kind: ConfigMap metadata: name: externalcfg labels: - app: eshop + app: eshop data: # Basket.API entries - basket__ConnectionString: REDIS CONNECTION STRING FOR BASKET + BasketBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX for topic in case of using Azure) + BasketRedisConStr: REDIS CONNECTION STRING FOR BASKET # Catalog.API entries - catalog__ConnectionString: Catalog SQL SERVER CONNECTION STRING (Server=xxxx;Intial Catalog=yyy;....) + CatalogBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX for topic in case of using Azure) + CatalogSqlDb: Catalog SQL SERVER CONNECTION STRING (Server=xxxx;Intial Catalog=yyy;....) # Identity.API entries IdentitySqlDb: Identity SQL SERVER CONNECTION STRING (Server=xxxx;Intial Catalog=yyy;....) # Locations.API entries @@ -28,7 +30,5 @@ data: # Payment.API entries PaymentBus: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX for topic in case of using Azure) # Global entries - all_UseAzureServiceBus: "TRUE" IF USE AZURE SB ("FALSE" FOR USING RABBITMQ) - keystore: REDIS CONNECTION STRING FOR KEYSTORE - all_EventBusConnection: CONNECTION_STRING (NAME OF RABBITMQ CONTAINER OR Endpoint=sb://XXXX in case of using Azure) - all_InstrumentationKey: APPINSIGHTS KEY + UseAzureServiceBus: "TRUE" IF USE AZURE SB ("FALSE" FOR USING RABBITMQ) + keystore: REDIS CONNECTION STRING FOR KEYSTORE \ No newline at end of file diff --git a/k8s/conf_local.yaml b/k8s/conf_local.yaml index 615754bcf..9a2059e63 100644 --- a/k8s/conf_local.yaml +++ b/k8s/conf_local.yaml @@ -5,23 +5,28 @@ metadata: labels: app: eshop data: - basket__ConnectionString: basket-data - catalog__ConnectionString: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word; - catalog__AzureStorageEnabled: "False" - identity__ConnectionString: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word; - locations__ConnectionString: mongodb://nosql-data - locations__Database: LocationsDb - marketing__MongoConnectionString: mongodb://nosql-data - marketing__MongoDatabase: MarketingDb - marketing__ConnectionString: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word; - ordering__ConnectionString: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word; + BasketBus: rabbitmq + BasketRedisConStr: basket-data + CatalogBus: rabbitmq + CatalogSqlDb: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word; + CatalogAzureStorageEnabled: "False" + IdentitySqlDb: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word; + LocationsBus: rabbitmq + LocationsNoSqlDb: mongodb://nosql-data + LocationsNoSqlDbName: LocationsDb + MarketingBus: rabbitmq + MarketingNoSqlDb: mongodb://nosql-data + MarketingNoSqlDbName: MarketingDb + MarketingSqlDb: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word; + OrderingBus: rabbitmq + OrderingSqlDb: Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word; + PaymentBus: rabbitmq + UseAzureServiceBus: "False" + EnableLoadTest: "False" keystore: keystore-data - GracePeriodManager__GracePeriodTime: "1" - GracePeriodManager__CheckUpdateTime: "15000" - all__EventBusConnection: rabbitmq - all__InstrumentationKey: "" - all__EnableLoadTest: "False" - all__UseAzureServiceBus: "False" + GracePeriodManager_GracePeriodTime: "1" + GracePeriodManager_CheckUpdateTime: "15000" + Instrumentation_Key: "" diff --git a/k8s/frontend.yaml b/k8s/frontend.yaml new file mode 100644 index 000000000..bd244beb2 --- /dev/null +++ b/k8s/frontend.yaml @@ -0,0 +1,47 @@ +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 diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml index b5773bb25..3c2fe8bad 100644 --- a/k8s/ingress.yaml +++ b/k8s/ingress.yaml @@ -11,10 +11,22 @@ spec: rules: - http: paths: + - path: /basket-api + backend: + serviceName: basket + servicePort: 80 + - path: /catalog-api + backend: + serviceName: catalog + servicePort: 80 - path: /identity backend: serviceName: identity servicePort: 80 + - path: /ordering-api + backend: + serviceName: ordering + servicePort: 80 - path: /webmvc backend: serviceName: webmvc @@ -23,37 +35,21 @@ spec: backend: serviceName: webstatus servicePort: 80 - - path: /webshoppingapigw - backend: - serviceName: ocelotapigw-ws - servicePort: 80 - - path: /webmarketingapigw + - path: /marketing-api backend: - serviceName: ocelotapigw-wm + serviceName: marketing servicePort: 80 - - path: /mobilemarketingapigw - backend: - serviceName: ocelotapigw-mm - servicePort: 80 - - path: /mobileshoppingapigw - backend: - serviceName: ocelotapigw-ms - servicePort: 80 - - path: /webshoppingagg + - path: /payment-api backend: - serviceName: webshoppingagg + serviceName: payment servicePort: 80 - - path: /mobileshoppingagg + - path: /locations-api backend: - serviceName: mobileshoppingagg + serviceName: locations servicePort: 80 - - path: /payment-api - backend: - serviceName: payment - servicePort: 80 - path: / backend: serviceName: webspa servicePort: 80 - + diff --git a/k8s/ocelot/configuration-mobile-marketing.json b/k8s/ocelot/configuration-mobile-marketing.json deleted file mode 100644 index 666df1633..000000000 --- a/k8s/ocelot/configuration-mobile-marketing.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "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" - } -} - \ No newline at end of file diff --git a/k8s/ocelot/configuration-mobile-shopping.json b/k8s/ocelot/configuration-mobile-shopping.json deleted file mode 100644 index cf3a48aff..000000000 --- a/k8s/ocelot/configuration-mobile-shopping.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "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" - } - } - \ No newline at end of file diff --git a/k8s/ocelot/configuration-web-marketing.json b/k8s/ocelot/configuration-web-marketing.json deleted file mode 100644 index 666df1633..000000000 --- a/k8s/ocelot/configuration-web-marketing.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "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" - } -} - \ No newline at end of file diff --git a/k8s/ocelot/service.yaml b/k8s/ocelot/service.yaml deleted file mode 100644 index 858b54b21..000000000 --- a/k8s/ocelot/service.yaml +++ /dev/null @@ -1,55 +0,0 @@ -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 diff --git a/k8s/readme.md b/k8s/readme.md index 43534d32e..9c8e1a512 100644 --- a/k8s/readme.md +++ b/k8s/readme.md @@ -3,6 +3,7 @@ This folder contains files needed to **create** a ACS with Kubernetes in Azure and to **deploy** eShopServices in a existing Kubernetes: - `gen-k8s-env.ps1` Script to create a ACS with Kubernetes in Azure + - `deploy.ps1` Script to deploy eShopOnContainers in a existing k8s Refer to file [README.k8s.md](./README.k8s.md) for detailed information diff --git a/k8s/services.yaml b/k8s/services.yaml index ad537eaf0..2235c64f7 100644 --- a/k8s/services.yaml +++ b/k8s/services.yaml @@ -126,34 +126,6 @@ spec: --- apiVersion: v1 kind: Service -metadata: - labels: - app: eshop - component: webshoppingagg - name: webshoppingagg -spec: - ports: - - port: 80 - selector: - app: eshop - component: webshoppingagg ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: eshop - component: mobileshoppingagg - name: mobileshoppingagg -spec: - ports: - - port: 80 - selector: - app: eshop - component: mobileshoppingagg ---- -apiVersion: v1 -kind: Service metadata: labels: app: eshop diff --git a/readme/README.ENV.md b/readme/README.ENV.md index bdb436a1a..bfa6c677b 100644 --- a/readme/README.ENV.md +++ b/readme/README.ENV.md @@ -8,9 +8,8 @@ To enable the Redis Cache of Azure in eShop it is necessary to have previously c For example: >ESHOP_AZURE_REDIS_BASKET_DB=yourredisservice.redis.cache.windows.net:6379,password=yourredisservicepassword,ssl=False,abortConnect=False -With the steps explained in the next section, you will be able to run the application with Azure Service Bus instead of the container of RabbitMQ service. - # Azure Service Bus service +With the steps explained in this section, you will be able to run the application with Azure Service Bus instead of the container of RabbitMQ service. To enable the service bus of Azure in eShop solution it is necessary having created previously the service bus service through ARM file or manually through Azure portal. You can use the [ARM files](deploy/az/servicebus/readme.md) already created in eShop. Finally, it is necessary to get the Shared access policy named "Root" (if you generated the service through ARM file) from eshop_event_bus topic. This policy must be declared on .env file located in the solution root folder with `ESHOP_AZURE_SERVICE_BUS` name. For example: @@ -18,9 +17,8 @@ For example: Once the service bus service is created, it is necessary to set to true the "AzureServiceBusEnabled" environment variable from `settings.json` file on Catalog.API, Ordering.API, Basket.API, Payment.API, GracePeriodManager, Marketing.API and Locations.API. -With the steps explained in the next section, you will be able to run the application with Azure Storage Account instead of the local container storage. - # Azure Storage Account service +With the steps explained in this section, you will be able to run the application with Azure Storage Account instead of the local file folder storage. To enable Azure storage of Azure in eShopOnAzure solution it is necessary having created previously the storage service through ARM file or manually through Azure portal. You can use the ARM files find under **deploy/az/storage** folder already created in eShop. Once the storage account is created, it is very important to create a new container(blob kind) and upload the solution catalog pics files before to continue.Later, it is necessary to set to true the "AzureStorageEnabled" environment variable from `settings.json` in Catalog.API and Marketing.API.Finally, it is necessary to get the container endpoint url from information service in the Azure portal, This url must be declared on .env file located in the solution root folder with `ESHOP_AZURE_STORAGE_CATALOG` for the Catalog.API content and `ESHOP_AZURE_STORAGE_MARKETING` for the Marketing.API content. Do not forget to put a slash character '/' in the end of the url. @@ -39,9 +37,8 @@ For example: >ESHOP_AZURE_STORAGE_MARKETING_NAME=storageaccountname >ESHOP_AZURE_STORAGE_MARKETING_KEY=storageaccountkey -With the steps explained in the next section, you will be able to run the application with Azure SQL Database instead of local storage. - # Azure SQL Database +With the steps explained in this section, you will be able to run the application with Azure SQL Database instead of a local SQL Server container. To enable Azure SQL Database in eShop is required to have a Azure SQL with the databases for Ordering.API, Identity.API, Catalaog.API and Marketing.API. You can use the [ARM files](deploy/az/sql/readme.md) already created in this project or do it manually. Once the databases are created, it is necessary to get the connection string for each service and set the corresponding variable in the .env file. For example: @@ -50,9 +47,8 @@ For example: >ESHOP_AZURE_ORDERING_DB=orderingazureconnectionstring >ESHOP_AZURE_MARKETING_DB=marketingazureconnectionstring -With the steps explained in the next section, you will be able to run the application with Azure Cosmos DB Database instead of local storage. - # Azure Cosmos DB +With the steps explained in this section, you will be able to run the application with Azure Cosmos DB Database instead of a local MongoDB container. To enable Azure Cosmos DB in eShop is required to have the connection string. If you do not have an Azure Cosmos DB created you can use the ARM files under **deploy/az/cosmos** folder available in eShop or do it manually. Once the connection string is availabe it is necessary to add it in the .env file in the `ESHOP_AZURE_COSMOSDB`variable. For example: @@ -64,4 +60,4 @@ To enable the Azure Functions in eShop you can add the URI where the functions h For example: >ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI=https://marketing-functions.azurewebsites.net/api/MarketingDetailsHttpTrigger?code=AzureFunctioncode -See Azure Functions deployment Files and Readme for more details [ARM files](deploy/az/azurefunctions/readme.md) \ No newline at end of file +See Azure Functions deployment Files and Readme for more details [ARM files](deploy/az/azurefunctions/readme.md) diff --git a/src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj b/src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj deleted file mode 100644 index d72d014b4..000000000 --- a/src/ApiGateways/ApiGw-Base/OcelotApiGw.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - netcoreapp2.0 - - - - - - - - - - - - diff --git a/src/ApiGateways/ApiGw-Base/Properties/launchSettings.json b/src/ApiGateways/ApiGw-Base/Properties/launchSettings.json deleted file mode 100644 index 2308ca466..000000000 --- a/src/ApiGateways/ApiGw-Base/Properties/launchSettings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "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/" - } - } -} \ No newline at end of file diff --git a/src/ApiGateways/ApiGw-Base/Startup.cs b/src/ApiGateways/ApiGw-Base/Startup.cs deleted file mode 100644 index f6a36b59e..000000000 --- a/src/ApiGateways/ApiGw-Base/Startup.cs +++ /dev/null @@ -1,91 +0,0 @@ -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("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(); - } - } -} diff --git a/src/ApiGateways/ApiGw-Base/appsettings.json b/src/ApiGateways/ApiGw-Base/appsettings.json deleted file mode 100644 index 426750e6a..000000000 --- a/src/ApiGateways/ApiGw-Base/appsettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "IncludeScopes": true, - "LogLevel": { - "Default": "Trace", - "System": "Information", - "Microsoft": "Information" - } - } -} \ No newline at end of file diff --git a/src/ApiGateways/Mobile.Bff.Marketing/apigw/configuration.json b/src/ApiGateways/Mobile.Bff.Marketing/apigw/configuration.json deleted file mode 100644 index 85d6777e6..000000000 --- a/src/ApiGateways/Mobile.Bff.Marketing/apigw/configuration.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "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" - } - } - \ No newline at end of file diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Config/UrlsConfig.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Config/UrlsConfig.cs deleted file mode 100644 index e920fbbb2..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Config/UrlsConfig.cs +++ /dev/null @@ -1,31 +0,0 @@ -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 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; } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs deleted file mode 100644 index 702c805fb..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs +++ /dev/null @@ -1,133 +0,0 @@ -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 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 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 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(); - } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/HomeController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/HomeController.cs deleted file mode 100644 index 48a71480a..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/HomeController.cs +++ /dev/null @@ -1,18 +0,0 @@ -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"); - } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs deleted file mode 100644 index 4c18d25ae..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs +++ /dev/null @@ -1,42 +0,0 @@ -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 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); - } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile deleted file mode 100644 index 273743cee..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -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"] - diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs deleted file mode 100644 index b3a7246aa..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs +++ /dev/null @@ -1,33 +0,0 @@ -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().Any() || - context.ApiDescription.ActionAttributes().OfType().Any(); - - if (hasAuthorize) - { - operation.Responses.Add("401", new Response { Description = "Unauthorized" }); - operation.Responses.Add("403", new Response { Description = "Forbidden" }); - - operation.Security = new List>>(); - operation.Security.Add(new Dictionary> - { - { "oauth2", new [] { "Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator" } } - }); - } - } - } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj deleted file mode 100644 index bd6d73950..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - netcoreapp2.0 - Mobile.Shopping.HttpAggregator - Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator - ..\..\..\docker-compose.dcproj - - - - - - - - - - - - - - - - - - - - diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs deleted file mode 100644 index f81842c09..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs +++ /dev/null @@ -1,20 +0,0 @@ -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; - } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketData.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketData.cs deleted file mode 100644 index 1b9348c44..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketData.cs +++ /dev/null @@ -1,31 +0,0 @@ -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 Items { get; set; } - - public BasketData(string buyerId) - { - BuyerId = buyerId; - Items = new List(); - } - } - - 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; } - - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/CatalogItem.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/CatalogItem.cs deleted file mode 100644 index 25f766719..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/CatalogItem.cs +++ /dev/null @@ -1,20 +0,0 @@ -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; } - - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderData.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderData.cs deleted file mode 100644 index e87cc18f0..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderData.cs +++ /dev/null @@ -1,33 +0,0 @@ -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 OrderItems { get; } = new List(); - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderItemData.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderItemData.cs deleted file mode 100644 index b0179e470..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderItemData.cs +++ /dev/null @@ -1,17 +0,0 @@ -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; } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs deleted file mode 100644 index 43cc81b89..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs +++ /dev/null @@ -1,31 +0,0 @@ -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 Updates { get; set; } - - public UpdateBasketItemsRequest() - { - Updates = new List(); - } - } - - public class UpdateBasketItemData - { - public string BasketItemId { get; set; } - public int NewQty { get; set; } - - public UpdateBasketItemData() - { - NewQty = 0; - } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs deleted file mode 100644 index cb22bf55f..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs +++ /dev/null @@ -1,21 +0,0 @@ -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 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 - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs deleted file mode 100644 index 0c88fcd7d..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs +++ /dev/null @@ -1,36 +0,0 @@ -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() - .Build(); - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Properties/launchSettings.json b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Properties/launchSettings.json deleted file mode 100644 index 925e70b0d..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Properties/launchSettings.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "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/" - } - } -} \ No newline at end of file diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs deleted file mode 100644 index b00fbb52c..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs +++ /dev/null @@ -1,53 +0,0 @@ -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 _logger; - private readonly UrlsConfig _urls; - private readonly IHttpContextAccessor _httpContextAccessor; - - public BasketService(IHttpClient httpClient, IHttpContextAccessor httpContextAccessor, ILogger logger, IOptionsSnapshot config) - { - _apiClient = httpClient; - _logger = logger; - _urls = config.Value; - _httpContextAccessor = httpContextAccessor; - } - - public async Task 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(data) : null; - return basket; - } - - public async Task Update(BasketData currentBasket) - { - var token = await GetUserTokenAsync(); - var data = await _apiClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), currentBasket, token); - int i = 0; - } - - async Task GetUserTokenAsync() - { - var context = _httpContextAccessor.HttpContext; - return await context.GetTokenAsync("access_token"); - } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs deleted file mode 100644 index d37b67679..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs +++ /dev/null @@ -1,43 +0,0 @@ -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 _logger; - private readonly UrlsConfig _urls; - - public CatalogService(IHttpClient httpClient, ILogger logger, IOptionsSnapshot config) - { - _apiClient = httpClient; - _logger = logger; - _urls = config.Value; - } - - public async Task GetCatalogItem(int id) - { - var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id)); - var item = JsonConvert.DeserializeObject(data); - return item; - } - - public async Task> GetCatalogItems(IEnumerable ids) - { - var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids)); - var item = JsonConvert.DeserializeObject(data); - return item; - - } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs deleted file mode 100644 index 6fd6871c1..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs +++ /dev/null @@ -1,15 +0,0 @@ -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 GetById(string id); - Task Update(BasketData currentBasket); - - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs deleted file mode 100644 index d7e605bfa..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs +++ /dev/null @@ -1,14 +0,0 @@ -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 GetCatalogItem(int id); - Task> GetCatalogItems(IEnumerable ids); - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs deleted file mode 100644 index 30ac013b9..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs +++ /dev/null @@ -1,13 +0,0 @@ -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 GetOrderDraftFromBasket(BasketData basket); - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs deleted file mode 100644 index 2659e11cc..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs +++ /dev/null @@ -1,37 +0,0 @@ -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 _logger; - private readonly UrlsConfig _urls; - - public OrderApiClient(IHttpClient httpClient, ILogger logger, IOptionsSnapshot config) - { - _apiClient = httpClient; - _logger = logger; - _urls = config.Value; - } - - public async Task GetOrderDraftFromBasket(BasketData basket) - { - var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft(); - var response = await _apiClient.PostAsync(url, basket); - response.EnsureSuccessStatusCode(); - var jsonResponse = await response.Content.ReadAsStringAsync(); - return JsonConvert.DeserializeObject(jsonResponse); - } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs deleted file mode 100644 index 73b736519..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs +++ /dev/null @@ -1,138 +0,0 @@ -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(); - services.AddSingleton(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddOptions(); - services.Configure(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("IdentityUrlExternal")}/connect/authorize", - TokenUrl = $"{Configuration.GetValue("IdentityUrlExternal")}/connect/token", - Scopes = new Dictionary() - { - { "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" } - } - }); - - options.OperationFilter(); - }); - - services.AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder.AllowAnyOrigin() - .AllowAnyMethod() - .AllowAnyHeader() - .AllowCredentials()); - }); - - - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); - var identityUrl = Configuration.GetValue("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"); - }); - - - } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json deleted file mode 100644 index 26bb0ac7a..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Warning" - } - }, - "Console": { - "LogLevel": { - "Default": "Warning" - } - } - } -} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json deleted file mode 100644 index 57b5e894d..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "urls": { - "basket": "http://localhost:55105", - "catalog": "http://localhost:55101", - "orders": "http://localhost:55102", - "identity": "http://localhost:55105" - } -} diff --git a/src/ApiGateways/Web.Bff.Marketing/apigw/configuration.json b/src/ApiGateways/Web.Bff.Marketing/apigw/configuration.json deleted file mode 100644 index 8afe4a4d6..000000000 --- a/src/ApiGateways/Web.Bff.Marketing/apigw/configuration.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "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" - } -} - \ No newline at end of file diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Config/UrlsConfig.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Config/UrlsConfig.cs deleted file mode 100644 index 19be27dce..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Config/UrlsConfig.cs +++ /dev/null @@ -1,31 +0,0 @@ -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 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; } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs deleted file mode 100644 index bfef55726..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs +++ /dev/null @@ -1,133 +0,0 @@ -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 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 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 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(); - } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/HomeController.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/HomeController.cs deleted file mode 100644 index 58ed48d1a..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/HomeController.cs +++ /dev/null @@ -1,18 +0,0 @@ -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"); - } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs deleted file mode 100644 index fd108ffb8..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs +++ /dev/null @@ -1,42 +0,0 @@ -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 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); - } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile b/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile deleted file mode 100644 index ce6f1b155..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -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"] diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs deleted file mode 100644 index 3f382e5df..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs +++ /dev/null @@ -1,33 +0,0 @@ -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().Any() || - context.ApiDescription.ActionAttributes().OfType().Any(); - - if (hasAuthorize) - { - operation.Responses.Add("401", new Response { Description = "Unauthorized" }); - operation.Responses.Add("403", new Response { Description = "Forbidden" }); - - operation.Security = new List>>(); - operation.Security.Add(new Dictionary> - { - { "oauth2", new [] { "Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator" } } - }); - } - } - } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs deleted file mode 100644 index 88aff245f..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs +++ /dev/null @@ -1,20 +0,0 @@ -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; - } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/BasketData.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/BasketData.cs deleted file mode 100644 index 01831a5c9..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/BasketData.cs +++ /dev/null @@ -1,31 +0,0 @@ -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 Items { get; set; } - - public BasketData(string buyerId) - { - BuyerId = buyerId; - Items = new List(); - } - } - - 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; } - - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/CatalogItem.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/CatalogItem.cs deleted file mode 100644 index c6085f934..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/CatalogItem.cs +++ /dev/null @@ -1,20 +0,0 @@ -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; } - - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderData.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderData.cs deleted file mode 100644 index e9d5982b9..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderData.cs +++ /dev/null @@ -1,33 +0,0 @@ -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 OrderItems { get; } = new List(); - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderItemData.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderItemData.cs deleted file mode 100644 index 1a40cb8cb..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/OrderItemData.cs +++ /dev/null @@ -1,17 +0,0 @@ -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; } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs deleted file mode 100644 index b41c069bc..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs +++ /dev/null @@ -1,31 +0,0 @@ -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 Updates { get; set; } - - public UpdateBasketItemsRequest() - { - Updates = new List(); - } - } - - public class UpdateBasketItemData - { - public string BasketItemId { get; set; } - public int NewQty { get; set; } - - public UpdateBasketItemData() - { - NewQty = 0; - } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs deleted file mode 100644 index 9beeeade4..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs +++ /dev/null @@ -1,21 +0,0 @@ -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 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 - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs deleted file mode 100644 index c865a8b3b..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs +++ /dev/null @@ -1,36 +0,0 @@ -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() - .Build(); - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json deleted file mode 100644 index 925e70b0d..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "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/" - } - } -} \ No newline at end of file diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs deleted file mode 100644 index 5ca89a408..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs +++ /dev/null @@ -1,53 +0,0 @@ -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 _logger; - private readonly UrlsConfig _urls; - private readonly IHttpContextAccessor _httpContextAccessor; - - public BasketService(IHttpClient httpClient, IHttpContextAccessor httpContextAccessor, ILogger logger, IOptionsSnapshot config) - { - _apiClient = httpClient; - _logger = logger; - _urls = config.Value; - _httpContextAccessor = httpContextAccessor; - } - - public async Task 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(data) : null; - return basket; - } - - public async Task Update(BasketData currentBasket) - { - var token = await GetUserTokenAsync(); - var data = await _apiClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), currentBasket, token); - int i = 0; - } - - async Task GetUserTokenAsync() - { - var context = _httpContextAccessor.HttpContext; - return await context.GetTokenAsync("access_token"); - } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs deleted file mode 100644 index 46d895f68..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs +++ /dev/null @@ -1,43 +0,0 @@ -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 _logger; - private readonly UrlsConfig _urls; - - public CatalogService(IHttpClient httpClient, ILogger logger, IOptionsSnapshot config) - { - _apiClient = httpClient; - _logger = logger; - _urls = config.Value; - } - - public async Task GetCatalogItem(int id) - { - var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id)); - var item = JsonConvert.DeserializeObject(data); - return item; - } - - public async Task> GetCatalogItems(IEnumerable ids) - { - var data = await _apiClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids)); - var item = JsonConvert.DeserializeObject(data); - return item; - - } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IBasketService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IBasketService.cs deleted file mode 100644 index f59c31965..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IBasketService.cs +++ /dev/null @@ -1,15 +0,0 @@ -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 GetById(string id); - Task Update(BasketData currentBasket); - - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/ICatalogService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/ICatalogService.cs deleted file mode 100644 index 7d192f3cc..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/ICatalogService.cs +++ /dev/null @@ -1,14 +0,0 @@ -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 GetCatalogItem(int id); - Task> GetCatalogItems(IEnumerable ids); - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IOrderApiClient.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IOrderApiClient.cs deleted file mode 100644 index c97eccbbd..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IOrderApiClient.cs +++ /dev/null @@ -1,13 +0,0 @@ -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 GetOrderDraftFromBasket(BasketData basket); - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs deleted file mode 100644 index 220e9afa9..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs +++ /dev/null @@ -1,37 +0,0 @@ -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 _logger; - private readonly UrlsConfig _urls; - - public OrderApiClient(IHttpClient httpClient, ILogger logger, IOptionsSnapshot config) - { - _apiClient = httpClient; - _logger = logger; - _urls = config.Value; - } - - public async Task GetOrderDraftFromBasket(BasketData basket) - { - var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft(); - var response = await _apiClient.PostAsync(url, basket); - response.EnsureSuccessStatusCode(); - var jsonResponse = await response.Content.ReadAsStringAsync(); - return JsonConvert.DeserializeObject(jsonResponse); - } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs deleted file mode 100644 index 17f9f90e6..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs +++ /dev/null @@ -1,138 +0,0 @@ -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(); - services.AddSingleton(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddOptions(); - services.Configure(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("IdentityUrlExternal")}/connect/authorize", - TokenUrl = $"{Configuration.GetValue("IdentityUrlExternal")}/connect/token", - Scopes = new Dictionary() - { - { "webshoppingagg", "Shopping Aggregator for Web Clients" } - } - }); - - options.OperationFilter(); - }); - - services.AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder.AllowAnyOrigin() - .AllowAnyMethod() - .AllowAnyHeader() - .AllowCredentials()); - }); - - - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); - var identityUrl = Configuration.GetValue("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"); - }); - - - } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj deleted file mode 100644 index 0b6dbf44b..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - netcoreapp2.0 - Web.Shopping.HttpAggregator - Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator - ..\..\..\docker-compose.dcproj - - - - - - - - - - - - - - - - - - - - diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json deleted file mode 100644 index 26bb0ac7a..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Warning" - } - }, - "Console": { - "LogLevel": { - "Default": "Warning" - } - } - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json deleted file mode 100644 index 57b5e894d..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "urls": { - "basket": "http://localhost:55105", - "catalog": "http://localhost:55101", - "orders": "http://localhost:55102", - "identity": "http://localhost:55105" - } -} diff --git a/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs b/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs index 9fa38ee8d..18051a501 100644 --- a/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs +++ b/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs @@ -97,11 +97,6 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http throw new HttpRequestException(); } - if (!response.IsSuccessStatusCode) - { - return null; - } - return await response.Content.ReadAsStringAsync(); }); } diff --git a/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs b/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs index 578168bff..a5f6a63c4 100644 --- a/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs +++ b/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs @@ -36,11 +36,6 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http var response = await _client.SendAsync(requestMessage); - if (!response.IsSuccessStatusCode) - { - return null; - } - return await response.Content.ReadAsStringAsync(); } diff --git a/src/Mobile/README.md b/src/Mobile/README.md index 4a12698b1..f73ebd564 100644 --- a/src/Mobile/README.md +++ b/src/Mobile/README.md @@ -1,12 +1,12 @@ # eShopOnContainers -eShopOnContainers is a reference app whose imagined purpose is to serve the mobile workforce of a fictitious company that sells products. The app allow to manage the catalog, view products, manage the basket and the orders. +eShopOnContainers is a reference app whose imagined purpose is to serve the mobile workforce of a fictitious company that sells products. The app would allow a user to manage their catalog, view products, manage the basket/cart and the orders. eShopOnContainers ### Supported platforms: iOS, Android and Windows -### The app architecture consists of two parts: +### The app's architecture consists of two parts: 1. A Xamarin.Forms mobile app for iOS, Android and Windows. 2. Several .NET Web API microservices deployed as Docker containers. @@ -22,7 +22,7 @@ This project exercises the following platforms, frameworks or features: * Central Styles * Custom Renderers * Animations - * IoC + * IoC (Inversion of Control) * Messaging Center * Custom Controls * Cross Plugins @@ -40,10 +40,10 @@ The app targets **three** platforms: * iOS * Android * Universal Windows Platform (UWP) - * UWP supported only in Visual Studio, not Xamarin Studio or Visual Studio for MacOS + * UWP is supported only in Visual Studio, not Xamarin Studio or Visual Studio for MacOS -As of 07/03/2017, eShopOnContainers features **89.2% code share** (7.2% iOS / 16.7% Android / 8.7% Windows). +As of 07/03/2017, eShopOnContainers features **89.2% code sharing** (7.2% iOS / 16.7% Android / 8.7% Windows). ## Licenses @@ -58,7 +58,7 @@ This project uses some third-party assets with a license that requires attributi ## Requirements ### Requirements for March 2017 version of eShopOnContainers -* [Visual Studio __2015__](https://www.visualstudio.com/en-us/products/vs-2015-product-editions.aspx) (14.0 or higher) to compile C# 6 langage features (or Visual Studio MacOS) +* [Visual Studio __2015__](https://www.visualstudio.com/en-us/products/vs-2015-product-editions.aspx) (14.0 or higher) to compile C# 6 language features (or Visual Studio for MacOS) * Xamarin add-ons for Visual Studio (available via the Visual Studio installer) * __Visual Studio Community Edition is fully supported!__ * [Android SDK Tools](https://developer.xamarin.com/guides/android/getting_started/installation/windows/) 25.2.3 or higher @@ -68,23 +68,23 @@ This project uses some third-party assets with a license that requires attributi #### [1. Ensure the Xamarin platform is installed](http://developer.xamarin.com/guides/cross-platform/getting_started/installation/) -#### 2. Ensure Xamarin are updated +#### 2. Ensure Xamarin is updated Xamarin will periodically automatically check for updates. You can also manually check for updates. -Ensure Xamarin are updated +Ensure Xamarin is updated ### 3. Project Setup Restore NuGet packages for the project. ### 4. Ensure Android Emulator is installed -You can use any Android emulator although it is highly recommended to use an x86 based version. +You can use any Android emulator, although it is highly recommended to use an x86 based version. Visual Studio Android Emulator -**Note**: The Visual Studio Android Emulator cannot run well inside a virtual machine or over Remote Desktop or VNC since it relies on virtualization and OpenGL. +**Note**: The Visual Studio Android Emulator cannot run well inside a Virtual Machine or over Remote Desktop or VNC since it relies on virtualization and OpenGL. -To deploy and debug the application on a physical device, refer to these [link](https://developer.xamarin.com/guides/android/deployment,_testing,_and_metrics/debug-on-device/). +To deploy and debug the application on a physical device, refer to this [link](https://developer.xamarin.com/guides/android/deployment,_testing,_and_metrics/debug-on-device/). ### 5. Ensure Mac connection To set up the Mac host, you must enable communication between the Xamarin extension for Visual Studio and your Mac. @@ -97,7 +97,7 @@ The app has the following screens: * a auth screen * a catalog list -* a profile section with a order list +* a profile section with an orders list * a readonly order detail screen * a customizable basket * a checkout screen @@ -117,22 +117,22 @@ If you see build issues when pulling updates from the repo, try cleaning and reb **Unsupported major.minor version 52.0** -So, you just downloaded the source code and ready to build the application and... +So, you just downloaded the source code and you are ready to build the application and ... Unsupported major.minor version 52.0 We have two possible fixes. -The first one is based on updating Java JDK and ensure its use. The version 52.0 referenced in the error refers to the JDK, specifically to version 8. Xamarin Android 7.0 requires the JDK 1.8 to use the Android Nougat APIs (API Level 24). It is also necessary a 64-bit version to be able to use personal controls in the Android editor among other actions. +The first one is based on updating Java JDK and ensure it's being used. The version 52.0 referenced in the error refers to the JDK, specifically to version 8. Xamarin Android 7.0 requires the JDK 1.8 to use the Android Nougat APIs (API Level 24). It is also necessary for a 64-bit version to be able to use personal controls in the Android editor among other actions. -Download the corresponding version of the JDK in this [link](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html). +Download the corresponding version of the JDK from this [link](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html). After downloading and installing, we must ensure that the installed version is used. For that: Visual Studio: Tools> Options> Xamarin> Android Settings> Java Development Kit Location. Xamarin Studio (on Mac): Xamarin Studio> Preferences> Projects> SDK Locations> Android> Java SDK (JDK). -The second way is based on using Android 6.0 or what is the same API Level 23. +The second way is based on using Android 6.0 which is the same as API Level 23. **Could not connect to the debugger using Android Hyper-V emulators** @@ -142,7 +142,7 @@ The application performs the deployment and even boots into the emulator, but st The error is related with incompatibilities between the host processor and the Hyper-V virtual machine. -In Windows 10, we press the start button and write MMC. Next, click the Hyper-V Manager option: +In Windows 10, we press the start button and write MMC, short for Microsoft Management Console. Next, click the Hyper-V Manager option: Could not connect to the debugger diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Extensions/ObservableExtension.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Extensions/ObservableExtension.cs index 800f9a031..ad10bd941 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Extensions/ObservableExtension.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Extensions/ObservableExtension.cs @@ -15,6 +15,7 @@ namespace eShopOnContainers.Core.Extensions } return collection; + } } } \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs index e1637d7be..d501a5d46 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs @@ -4,7 +4,7 @@ { public const string AzureTag = "Azure"; public const string MockTag = "Mock"; - public const string DefaultEndpoint = "http://YOUR_IP_OR_DNS_NAME"; // i.e.: "http://YOUR_IP" or "http://YOUR_DNS_NAME" + public const string DefaultEndpoint = "http://13.88.8.119"; private string _baseEndpoint; private static readonly GlobalSetting _instance = new GlobalSetting(); @@ -38,8 +38,18 @@ public string RegisterWebsite { get; set; } + public string CatalogEndpoint { get; set; } + + public string OrdersEndpoint { get; set; } + + public string BasketEndpoint { get; set; } + public string IdentityEndpoint { get; set; } + public string LocationEndpoint { get; set; } + + public string MarketingEndpoint { get; set; } + public string UserInfoEndpoint { get; set; } public string TokenEndpoint { get; set; } @@ -52,17 +62,18 @@ private void UpdateEndpoint(string baseEndpoint) { - var identityBaseEndpoint = $"{baseEndpoint}/identity"; - RegisterWebsite = $"{identityBaseEndpoint}/Account/Register"; - LogoutCallback = $"{identityBaseEndpoint}/Account/Redirecting"; - - var connectBaseEndpoint = $"{identityBaseEndpoint}/connect"; - IdentityEndpoint = $"{connectBaseEndpoint}/authorize"; - UserInfoEndpoint = $"{connectBaseEndpoint}/userinfo"; - TokenEndpoint = $"{connectBaseEndpoint}/token"; - LogoutEndpoint = $"{connectBaseEndpoint}/endsession"; - - IdentityCallback = $"{baseEndpoint}/xamarincallback"; + RegisterWebsite = $"{baseEndpoint}:5105/Account/Register"; + CatalogEndpoint = $"{baseEndpoint}:5101"; + OrdersEndpoint = $"{baseEndpoint}:5102"; + BasketEndpoint = $"{baseEndpoint}:5103"; + IdentityEndpoint = $"{baseEndpoint}:5105/connect/authorize"; + UserInfoEndpoint = $"{baseEndpoint}:5105/connect/userinfo"; + TokenEndpoint = $"{baseEndpoint}:5105/connect/token"; + LogoutEndpoint = $"{baseEndpoint}:5105/connect/endsession"; + IdentityCallback = $"{baseEndpoint}:5105/xamarincallback"; + LogoutCallback = $"{baseEndpoint}:5105/Account/Redirecting"; + LocationEndpoint = $"{baseEndpoint}:5109"; + MarketingEndpoint = $"{baseEndpoint}:5110"; } } } \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs index b36488f24..54f3a03bc 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs @@ -11,7 +11,7 @@ namespace eShopOnContainers.Core.Services.Basket private readonly IRequestProvider _requestProvider; private readonly IFixUriService _fixUriService; - private const string ApiUrlBase = "mobileshoppingapigw/api/v1/b/basket"; + private const string ApiUrlBase = "api/v1/basket"; public BasketService(IRequestProvider requestProvider, IFixUriService fixUriService) { @@ -21,23 +21,15 @@ namespace eShopOnContainers.Core.Services.Basket public async Task GetBasketAsync(string guidUser, string token) { - var builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint) + var builder = new UriBuilder(GlobalSetting.Instance.BasketEndpoint) { Path = $"{ApiUrlBase}/{guidUser}" }; var uri = builder.ToString(); - CustomerBasket basket; - - try - { - basket = await _requestProvider.GetAsync(uri, token); - } - catch (HttpRequestExceptionEx exception) when (exception.HttpCode == System.Net.HttpStatusCode.NotFound) - { - basket = null; - } + CustomerBasket basket = + await _requestProvider.GetAsync(uri, token); _fixUriService.FixBasketItemPictureUri(basket?.Items); return basket; @@ -45,7 +37,7 @@ namespace eShopOnContainers.Core.Services.Basket public async Task UpdateBasketAsync(CustomerBasket customerBasket, string token) { - var builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint) + var builder = new UriBuilder(GlobalSetting.Instance.BasketEndpoint) { Path = ApiUrlBase }; @@ -57,7 +49,7 @@ namespace eShopOnContainers.Core.Services.Basket public async Task CheckoutAsync(BasketCheckout basketCheckout, string token) { - var builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint) + var builder = new UriBuilder(GlobalSetting.Instance.BasketEndpoint) { Path = $"{ApiUrlBase}/checkout" }; @@ -68,7 +60,7 @@ namespace eShopOnContainers.Core.Services.Basket public async Task ClearBasketAsync(string guidUser, string token) { - var builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint) + var builder = new UriBuilder(GlobalSetting.Instance.BasketEndpoint) { Path = $"{ApiUrlBase}/{guidUser}" }; diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Catalog/CatalogService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Catalog/CatalogService.cs index 2811416ad..2e63e9516 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Catalog/CatalogService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Catalog/CatalogService.cs @@ -13,8 +13,6 @@ namespace eShopOnContainers.Core.Services.Catalog { private readonly IRequestProvider _requestProvider; private readonly IFixUriService _fixUriService; - - private const string ApiUrlBase = "mobileshoppingapigw/api/v1/c/catalog"; public CatalogService(IRequestProvider requestProvider, IFixUriService fixUriService) { @@ -24,8 +22,8 @@ namespace eShopOnContainers.Core.Services.Catalog public async Task> FilterAsync(int catalogBrandId, int catalogTypeId) { - UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint); - builder.Path = $"{ApiUrlBase}/items/type/{catalogTypeId}/brand/{catalogBrandId}"; + UriBuilder builder = new UriBuilder(GlobalSetting.Instance.CatalogEndpoint); + builder.Path = string.Format("api/v1/catalog/items/type/{0}/brand/{1}", catalogTypeId, catalogBrandId); string uri = builder.ToString(); CatalogRoot catalog = await _requestProvider.GetAsync(uri); @@ -38,8 +36,8 @@ namespace eShopOnContainers.Core.Services.Catalog public async Task> GetCatalogAsync() { - UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint); - builder.Path = $"{ApiUrlBase}/items"; + UriBuilder builder = new UriBuilder(GlobalSetting.Instance.CatalogEndpoint); + builder.Path = "api/v1/catalog/items"; string uri = builder.ToString(); CatalogRoot catalog = await _requestProvider.GetAsync(uri); @@ -55,8 +53,8 @@ namespace eShopOnContainers.Core.Services.Catalog public async Task> GetCatalogBrandAsync() { - UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint); - builder.Path = $"{ApiUrlBase}/catalogbrands"; + UriBuilder builder = new UriBuilder(GlobalSetting.Instance.CatalogEndpoint); + builder.Path = "api/v1/catalog/catalogbrands"; string uri = builder.ToString(); IEnumerable brands = await _requestProvider.GetAsync>(uri); @@ -69,8 +67,8 @@ namespace eShopOnContainers.Core.Services.Catalog public async Task> GetCatalogTypeAsync() { - UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint); - builder.Path = $"{ApiUrlBase}/catalogtypes"; + UriBuilder builder = new UriBuilder(GlobalSetting.Instance.CatalogEndpoint); + builder.Path = "api/v1/catalog/catalogtypes"; string uri = builder.ToString(); IEnumerable types = await _requestProvider.GetAsync>(uri); diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/LocationService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/LocationService.cs index e18d335c0..f20ae6339 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/LocationService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Location/LocationService.cs @@ -15,8 +15,8 @@ namespace eShopOnContainers.Core.Services.Location public async Task UpdateUserLocation(eShopOnContainers.Core.Models.Location.Location newLocReq, string token) { - UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint); - builder.Path = "/mobilemarketingapigw/api/v1/l/locations"; + UriBuilder builder = new UriBuilder(GlobalSetting.Instance.LocationEndpoint); + builder.Path = "api/v1/locations"; string uri = builder.ToString(); await _requestProvider.PostAsync(uri, newLocReq, token); } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs index 2fa5eaa9e..cb74f11b0 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Marketing/CampaignService.cs @@ -13,8 +13,6 @@ namespace eShopOnContainers.Core.Services.Marketing private readonly IRequestProvider _requestProvider; private readonly IFixUriService _fixUriService; - private const string ApiUrlBase = "mobilemarketingapigw/api/v1/m/campaigns"; - public CampaignService(IRequestProvider requestProvider, IFixUriService fixUriService) { _requestProvider = requestProvider; @@ -23,8 +21,8 @@ namespace eShopOnContainers.Core.Services.Marketing public async Task> GetAllCampaignsAsync(string token) { - UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint); - builder.Path = $"{ApiUrlBase}/user"; + UriBuilder builder = new UriBuilder(GlobalSetting.Instance.MarketingEndpoint); + builder.Path = "api/v1/campaigns/user"; string uri = builder.ToString(); CampaignRoot campaign = await _requestProvider.GetAsync(uri, token); @@ -40,8 +38,8 @@ namespace eShopOnContainers.Core.Services.Marketing public async Task GetCampaignByIdAsync(int campaignId, string token) { - UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint); - builder.Path = $"{ApiUrlBase}/{campaignId}"; + UriBuilder builder = new UriBuilder(GlobalSetting.Instance.MarketingEndpoint); + builder.Path = $"api/v1/campaigns/{campaignId}"; string uri = builder.ToString(); return await _requestProvider.GetAsync(uri, token); } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Order/OrderService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Order/OrderService.cs index fb9a0c627..f242971fb 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Order/OrderService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Order/OrderService.cs @@ -11,8 +11,6 @@ namespace eShopOnContainers.Core.Services.Order { private readonly IRequestProvider _requestProvider; - private const string ApiUrlBase = "mobileshoppingapigw/api/v1/o/orders"; - public OrderService(IRequestProvider requestProvider) { _requestProvider = requestProvider; @@ -25,9 +23,9 @@ namespace eShopOnContainers.Core.Services.Order public async Task> GetOrdersAsync(string token) { - UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint); + UriBuilder builder = new UriBuilder(GlobalSetting.Instance.OrdersEndpoint); - builder.Path = ApiUrlBase; + builder.Path = "api/v1/orders"; string uri = builder.ToString(); @@ -42,9 +40,9 @@ namespace eShopOnContainers.Core.Services.Order { try { - UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint); + UriBuilder builder = new UriBuilder(GlobalSetting.Instance.OrdersEndpoint); - builder.Path = $"{ApiUrlBase}/{orderId}"; + builder.Path = string.Format("api/v1/orders/{0}", orderId); string uri = builder.ToString(); @@ -78,9 +76,9 @@ namespace eShopOnContainers.Core.Services.Order public async Task CancelOrderAsync(int orderId, string token) { - UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BaseEndpoint); + UriBuilder builder = new UriBuilder(GlobalSetting.Instance.OrdersEndpoint); - builder.Path = $"{ApiUrlBase}/cancel"; + builder.Path = "api/v1/orders/cancel"; var cancelOrderCommand = new CancelOrderCommand(orderId); diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsService.cs index 69ede7b72..5e2732bf9 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsService.cs @@ -1,6 +1,4 @@ -using System.Threading.Tasks; - -namespace eShopOnContainers.Core.Services.Settings +namespace eShopOnContainers.Core.Services.Settings { public interface ISettingsService { @@ -12,10 +10,5 @@ namespace eShopOnContainers.Core.Services.Settings string Latitude { get; set; } string Longitude { get; set; } bool AllowGpsLocation { get; set; } - - bool GetValueOrDefault(string key, bool defaultValue); - string GetValueOrDefault(string key, string defaultValue); - Task AddOrUpdateValue(string key, bool value); - Task AddOrUpdateValue(string key, string value); } } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsServiceImplementation.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsServiceImplementation.cs new file mode 100644 index 000000000..ef9d14ed6 --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/ISettingsServiceImplementation.cs @@ -0,0 +1,13 @@ +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); + } +} diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/SettingsService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/SettingsService.cs index ca3e03c04..a13f53187 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/SettingsService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Settings/SettingsService.cs @@ -1,11 +1,21 @@ -using System; -using System.Threading.Tasks; -using Xamarin.Forms; +using eShopOnContainers.Core.Services.Dependency; namespace eShopOnContainers.Core.Services.Settings { public class SettingsService : ISettingsService { + private readonly ISettingsServiceImplementation _settingsService; + + ISettingsServiceImplementation AppSettings + { + get { return _settingsService; } + } + + public SettingsService(IDependencyService dependencyService) + { + _settingsService = dependencyService.Get(); + } + #region Setting Constants private const string AccessToken = "access_token"; @@ -27,113 +37,52 @@ namespace eShopOnContainers.Core.Services.Settings #endregion - #region Settings Properties - public string AuthAccessToken { - get => GetValueOrDefault(AccessToken, AccessTokenDefault); - set => AddOrUpdateValue(AccessToken, value); + get => AppSettings.GetValueOrDefault(AccessToken, AccessTokenDefault); + set => AppSettings.AddOrUpdateValue(AccessToken, value); } public string AuthIdToken { - get => GetValueOrDefault(IdToken, IdTokenDefault); - set => AddOrUpdateValue(IdToken, value); + get => AppSettings.GetValueOrDefault(IdToken, IdTokenDefault); + set => AppSettings.AddOrUpdateValue(IdToken, value); } public bool UseMocks { - get => GetValueOrDefault(IdUseMocks, UseMocksDefault); - set => AddOrUpdateValue(IdUseMocks, value); + get => AppSettings.GetValueOrDefault(IdUseMocks, UseMocksDefault); + set => AppSettings.AddOrUpdateValue(IdUseMocks, value); } public string UrlBase { - get => GetValueOrDefault(IdUrlBase, UrlBaseDefault); - set => AddOrUpdateValue(IdUrlBase, value); + get => AppSettings.GetValueOrDefault(IdUrlBase, UrlBaseDefault); + set => AppSettings.AddOrUpdateValue(IdUrlBase, value); } public bool UseFakeLocation { - get => GetValueOrDefault(IdUseFakeLocation, UseFakeLocationDefault); - set => AddOrUpdateValue(IdUseFakeLocation, value); + get => AppSettings.GetValueOrDefault(IdUseFakeLocation, UseFakeLocationDefault); + set => AppSettings.AddOrUpdateValue(IdUseFakeLocation, value); } public string Latitude { - get => GetValueOrDefault(IdLatitude, FakeLatitudeDefault.ToString()); - set => AddOrUpdateValue(IdLatitude, value); + get => AppSettings.GetValueOrDefault(IdLatitude, FakeLatitudeDefault.ToString()); + set => AppSettings.AddOrUpdateValue(IdLatitude, value); } public string Longitude { - get => GetValueOrDefault(IdLongitude, FakeLongitudeDefault.ToString()); - set => AddOrUpdateValue(IdLongitude, value); + get => AppSettings.GetValueOrDefault(IdLongitude, FakeLongitudeDefault.ToString()); + set => AppSettings.AddOrUpdateValue(IdLongitude, value); } public bool AllowGpsLocation { - get => GetValueOrDefault(IdAllowGpsLocation, AllowGpsLocationDefault); - set => AddOrUpdateValue(IdAllowGpsLocation, value); + get => AppSettings.GetValueOrDefault(IdAllowGpsLocation, AllowGpsLocationDefault); + set => AppSettings.AddOrUpdateValue(IdAllowGpsLocation, value); } - - #endregion - - #region Public Methods - - public Task AddOrUpdateValue(string key, bool value) => AddOrUpdateValueInternal(key, value); - public Task 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); - - #endregion - - #region Internal Implementation - - async Task AddOrUpdateValueInternal(string key, T value) - { - if (value == null) - { - await Remove(key); - } - - Application.Current.Properties[key] = value; - try - { - await Application.Current.SavePropertiesAsync(); - } - catch (Exception ex) - { - Console.WriteLine("Unable to save: " + key, " Message: " + ex.Message); - } - } - - T GetValueOrDefaultInternal(string key, T defaultValue = default(T)) - { - object value = null; - if (Application.Current.Properties.ContainsKey(key)) - { - value = Application.Current.Properties[key]; - } - return null != value ? (T)value : defaultValue; - } - - async Task Remove(string key) - { - try - { - if (Application.Current.Properties[key] != null) - { - Application.Current.Properties.Remove(key); - await Application.Current.SavePropertiesAsync(); - } - } - catch (Exception ex) - { - Console.WriteLine("Unable to remove: " + key, " Message: " + ex.Message); - } - } - - #endregion } } \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/LoginView.xaml b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/LoginView.xaml index 2bccd06d6..f6b9bd72c 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/LoginView.xaml +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/LoginView.xaml @@ -337,14 +337,28 @@ Grid.RowSpan="2" IsVisible="{Binding IsLogin}"> + Source="{Binding LoginUrl}" + AbsoluteLayout.LayoutBounds="0, 0, 1, 1" + AbsoluteLayout.LayoutFlags="All"> - + + + + + + + + + + + + diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Extensions/LocationExtensions.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Extensions/LocationExtensions.cs index 031c186aa..41ea2ad3e 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Extensions/LocationExtensions.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Extensions/LocationExtensions.cs @@ -32,7 +32,7 @@ namespace eShopOnContainers.Droid.Extensions { return new DateTimeOffset(Epoch.AddMilliseconds(location.Time)); } - catch (Exception) + catch (Exception e) { return new DateTimeOffset(Epoch); } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Services/SettingsServiceImplementation.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Services/SettingsServiceImplementation.cs new file mode 100644 index 000000000..7cdce4555 --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Services/SettingsServiceImplementation.cs @@ -0,0 +1,149 @@ +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(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(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 + } +} diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj index 92e2df581..7d699f9d2 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj @@ -19,7 +19,7 @@ Off Properties\AndroidManifest.xml true - v8.1 + v8.0 armeabi,armeabi-v7a,x86 @@ -211,6 +211,7 @@ + diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj.bak b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj.bak new file mode 100644 index 000000000..8a2babd2e --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj.bak @@ -0,0 +1,429 @@ + + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {62DBB163-9CA9-4818-B48B-13233DF37C24} + {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + Properties + eShopOnContainers.Droid + eShopOnContainers.Droid + 512 + true + Resources\Resource.Designer.cs + Off + Properties\AndroidManifest.xml + true + v8.0 + armeabi,armeabi-v7a,x86 + + + 1G + + + + + + true + + + True + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + True + None + False + 1G + Xamarin + armeabi;armeabi-v7a;x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + False + SdkOnly + + + + ..\..\..\..\packages\Acr.Support.2.1.0\lib\MonoAndroid10\Acr.Support.Android.dll + True + + + ..\..\..\..\packages\AndHUD.1.2.0\lib\MonoAndroid\AndHUD.dll + True + + + ..\..\..\..\packages\Xamarin.FFImageLoading.2.2.9\lib\MonoAndroid10\FFImageLoading.dll + + + ..\..\..\..\packages\Xamarin.FFImageLoading.2.2.9\lib\MonoAndroid10\FFImageLoading.Platform.dll + + + ..\..\..\..\packages\IdentityModel.1.3.1\lib\portable-net45+wp80+win8+wpa81\IdentityModel.Portable.dll + True + + + + ..\..\..\..\packages\modernhttpclient.2.4.2\lib\MonoAndroid\ModernHttpClient.dll + True + + + + + ..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll + + + ..\..\..\..\packages\modernhttpclient.2.4.2\lib\MonoAndroid\OkHttp.dll + True + + + ..\..\..\..\packages\PCLCrypto.2.0.147\lib\MonoAndroid23\PCLCrypto.dll + + + ..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll + + + ..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll + + + ..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll + + + ..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll + + + ..\..\..\..\packages\Plugin.CurrentActivity.1.0.1\lib\MonoAndroid10\Plugin.CurrentActivity.dll + + + ..\..\..\..\packages\Xam.Plugin.Geolocator.3.0.4\lib\MonoAndroid10\Plugin.Geolocator.dll + + + ..\..\..\..\packages\Xam.Plugin.Geolocator.3.0.4\lib\MonoAndroid10\Plugin.Geolocator.Abstractions.dll + + + ..\..\..\..\packages\Plugin.Permissions.1.1.7\lib\MonoAndroid10\Plugin.Permissions.dll + + + ..\..\..\..\packages\Plugin.Permissions.1.1.7\lib\MonoAndroid10\Plugin.Permissions.Abstractions.dll + + + ..\..\..\..\packages\Xam.Plugins.Settings.2.6.0.12-beta\lib\MonoAndroid10\Plugin.Settings.dll + True + + + ..\..\..\..\packages\Xam.Plugins.Settings.2.6.0.12-beta\lib\MonoAndroid10\Plugin.Settings.Abstractions.dll + True + + + ..\..\..\..\packages\SlideOverKit.2.1.4\lib\MonoAndroid10\SlideOverKit.dll + True + + + ..\..\..\..\packages\SlideOverKit.2.1.4\lib\MonoAndroid10\SlideOverKit.Droid.dll + True + + + ..\..\..\..\packages\Splat.1.6.2\lib\monoandroid\Splat.dll + True + + + + + + ..\..\..\..\packages\Microsoft.Net.Http.2.2.29\lib\monoandroid\System.Net.Http.Extensions.dll + True + + + ..\..\..\..\packages\Microsoft.Net.Http.2.2.29\lib\monoandroid\System.Net.Http.Primitives.dll + True + + + + + ..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll + + + + ..\..\..\..\packages\Autofac.4.5.0\lib\netstandard1.1\Autofac.dll + + + ..\..\..\..\packages\Acr.UserDialogs.6.3.8\lib\MonoAndroid10\Acr.UserDialogs.dll + + + ..\..\..\..\packages\Acr.UserDialogs.6.3.8\lib\MonoAndroid10\Acr.UserDialogs.Interface.dll + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\lib\MonoAndroid10\FormsViewGroup.dll + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\lib\MonoAndroid10\Xamarin.Forms.Core.dll + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\lib\MonoAndroid10\Xamarin.Forms.Platform.dll + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.91635\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll + + + ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.2.9\lib\MonoAndroid10\FFImageLoading.Forms.dll + + + ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.2.9\lib\MonoAndroid10\FFImageLoading.Forms.Droid.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.Vector.Drawable.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Vector.Drawable.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.v7.RecyclerView.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v7.RecyclerView.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.Annotations.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Annotations.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.Compat.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Compat.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.v7.CardView.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v7.CardView.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.Media.Compat.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Media.Compat.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.Core.UI.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Core.UI.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.Core.Utils.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Core.Utils.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.Fragment.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Fragment.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.Design.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Design.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.Transition.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Transition.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.v4.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v4.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.v7.Palette.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v7.Palette.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.v7.AppCompat.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v7.AppCompat.dll + + + ..\..\..\..\packages\Xamarin.Android.Support.v7.MediaRouter.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.v7.MediaRouter.dll + + + + + + + + + + + + + + + + + + + + + Assets\Montserrat-Bold.ttf + + + Assets\Montserrat-Regular.ttf + + + Assets\SourceSansPro-Regular.ttf + + + + + + + + + Designer + + + Designer + + + Designer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {ba96a12c-4ee3-46c4-bb3f-f811b554cd01} + eShopOnContainers.Core + + + + + + 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}. + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj index 250d836a7..4a83a29a8 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.iOS/eShopOnContainers.TestRunner.iOS.csproj @@ -1,232 +1,232 @@  - - + + + + Debug + iPhoneSimulator + {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3} + {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Exe + eShopOnContainers.TestRunner.iOS + Resources + eShopOnContainersTestRunneriOS + + + + + true + full + false + bin\iPhoneSimulator\Debug + DEBUG + prompt + 4 + false + x86_64 + None + True + False + False + False + False + False + True + Default + HttpClientHandler + False + + + false + none + true + bin\iPhoneSimulator\Release + prompt + 4 + None + x86_64 + false + + + true + full + false + bin\iPhone\Debug + DEBUG + prompt + 4 + false + ARMv7, ARM64 + Entitlements.plist + iPhone Developer + true + None + + + false + none + true + bin\iPhone\Release + prompt + 4 + Entitlements.plist + ARMv7, ARM64 + false + iPhone Developer + + + none + True + bin\iPhone\Ad-Hoc + prompt + 4 + False + ARMv7, ARM64 + Entitlements.plist + True + Automatic:AdHoc + iPhone Distribution + + + none + True + bin\iPhone\AppStore + prompt + 4 + False + ARMv7, ARM64 + Entitlements.plist + Automatic:AppStore + iPhone Distribution + + + + + + + + + + + + + + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll + + + + + + ..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.devices.dll + + + ..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.utility.netstandard15.dll + + + ..\..\..\..\packages\xunit.abstractions.2.0.1\lib\netstandard1.0\xunit.abstractions.dll + + + ..\..\..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll + + + ..\..\..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll + + + ..\..\..\..\packages\xunit.extensibility.execution.2.3.1\lib\netstandard1.1\xunit.execution.dotnet.dll + + + + ..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll + + + ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.dll + + + ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.iOS.dll + + + ..\..\..\..\packages\IdentityModel.3.0.0\lib\netstandard2.0\IdentityModel.dll + + + ..\..\..\..\packages\Acr.Support.2.1.0\lib\Xamarin.iOS10\Acr.Support.iOS.dll + + + ..\..\..\..\packages\BTProgressHUD.1.2.0.5\lib\Xamarin.iOS10\BTProgressHUD.dll + + + ..\..\..\..\packages\Splat.2.0.0\lib\Xamarin.iOS10\Splat.dll + + + ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.dll + + + ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.Interface.dll + + + ..\..\..\..\packages\WebP.Touch.1.0.7\lib\Xamarin.iOS10\WebP.Touch.dll + + + ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.dll + + + ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Platform.dll + + + ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.dll + + + ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.Touch.dll + + + ..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll + + + ..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll + + + ..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll + + + ..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll + + + ..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll + + + ..\..\..\..\packages\PCLCrypto.2.0.147\lib\xamarinios10\PCLCrypto.dll + + + + + + + + {FDD910BC-DF0F-483D-B7D5-C7D831855172} + eShopOnContainers.UnitTests + + + + + + - Debug - iPhoneSimulator - {B68C2B56-7581-46AE-B55D-D25DDFD3BFE3} - {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Exe - eShopOnContainers.TestRunner.iOS - Resources - eShopOnContainersTestRunneriOS - - - true + 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}. - - true - full - false - bin\iPhoneSimulator\Debug - DEBUG - prompt - 4 - false - x86_64 - None - True - False - False - False - False - False - True - Default - HttpClientHandler - False - - - false - none - true - bin\iPhoneSimulator\Release - prompt - 4 - None - x86_64 - false - - - true - full - false - bin\iPhone\Debug - DEBUG - prompt - 4 - false - ARMv7, ARM64 - Entitlements.plist - iPhone Developer - true - None - - - false - none - true - bin\iPhone\Release - prompt - 4 - Entitlements.plist - ARMv7, ARM64 - false - iPhone Developer - - - none - True - bin\iPhone\Ad-Hoc - prompt - 4 - False - ARMv7, ARM64 - Entitlements.plist - True - Automatic:AdHoc - iPhone Distribution - - - none - True - bin\iPhone\AppStore - prompt - 4 - False - ARMv7, ARM64 - Entitlements.plist - Automatic:AppStore - iPhone Distribution - - - - - - - - - - - - - - - - ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll - - - ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll - - - ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll - - - ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll - - - - - - ..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.devices.dll - - - ..\..\..\..\packages\xunit.runner.devices.2.3.3\lib\xamarinios10\xunit.runner.utility.netstandard15.dll - - - ..\..\..\..\packages\xunit.abstractions.2.0.1\lib\netstandard1.0\xunit.abstractions.dll - - - ..\..\..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll - - - ..\..\..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll - - - ..\..\..\..\packages\xunit.extensibility.execution.2.3.1\lib\netstandard1.1\xunit.execution.dotnet.dll - - - ..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll - - - ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.dll - - - ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.iOS.dll - - - ..\..\..\..\packages\IdentityModel.3.0.0\lib\netstandard2.0\IdentityModel.dll - - - ..\..\..\..\packages\Acr.Support.2.1.0\lib\Xamarin.iOS10\Acr.Support.iOS.dll - - - ..\..\..\..\packages\BTProgressHUD.1.2.0.5\lib\Xamarin.iOS10\BTProgressHUD.dll - - - ..\..\..\..\packages\Splat.2.0.0\lib\Xamarin.iOS10\Splat.dll - - - ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.dll - - - ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.Interface.dll - - - ..\..\..\..\packages\WebP.Touch.1.0.7\lib\Xamarin.iOS10\WebP.Touch.dll - - - ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.dll - - - ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Platform.dll - - - ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.dll - - - ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.Touch.dll - - - ..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll - - - ..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll - - - ..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll - - - ..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll - - - ..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll - - - ..\..\..\..\packages\PCLCrypto.2.0.147\lib\xamarinios10\PCLCrypto.dll - - - - - - - - {FDD910BC-DF0F-483D-B7D5-C7D831855172} - eShopOnContainers.UnitTests - - - - - - - - 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}. - - - - - - - + + + + + + \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/Mocks/MockSettingsService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/Mocks/MockSettingsService.cs index 37bfc125f..23e1cedc5 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/Mocks/MockSettingsService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.UnitTests/Mocks/MockSettingsService.cs @@ -1,110 +1,65 @@ using eShopOnContainers.Core.Services.Settings; -using System.Collections.Generic; -using System.Threading.Tasks; +using System; namespace eShopOnContainers.UnitTests.Mocks { public class MockSettingsService : ISettingsService { - IDictionary _settings = new Dictionary(); - - const string AccessToken = "access_token"; - const string IdToken = "id_token"; - const string IdUseMocks = "use_mocks"; - const string IdUrlBase = "url_base"; - const string IdUseFakeLocation = "use_fake_location"; - const string IdLatitude = "latitude"; - const string IdLongitude = "longitude"; - const string IdAllowGpsLocation = "allow_gps_location"; - readonly string AccessTokenDefault = string.Empty; - readonly string IdTokenDefault = string.Empty; - readonly bool UseMocksDefault = true; - readonly bool UseFakeLocationDefault = false; - readonly bool AllowGpsLocationDefault = false; - readonly double FakeLatitudeDefault = 47.604610d; - readonly double FakeLongitudeDefault = -122.315752d; - readonly string UrlBaseDefault = "https://13.88.8.119"; + string _accessTokenDefault = string.Empty; + string _idTokenDefault = string.Empty; + bool _useMocksDefault = true; + string _urlBaseDefault = "https://13.88.8.119"; + bool _useFakeLocationDefault = false; + bool _allowGpsLocationDefault = false; + double _fakeLatitudeDefault = 47.604610d; + double _fakeLongitudeDefault = -122.315752d; public string AuthAccessToken { - get => GetValueOrDefault(AccessToken, AccessTokenDefault); - set => AddOrUpdateValue(AccessToken, value); + get { return _accessTokenDefault; } + set { _accessTokenDefault = value; } } public string AuthIdToken { - get => GetValueOrDefault(IdToken, IdTokenDefault); - set => AddOrUpdateValue(IdToken, value); + get { return _idTokenDefault; } + set { _idTokenDefault = value; } } public bool UseMocks { - get => GetValueOrDefault(IdUseMocks, UseMocksDefault); - set => AddOrUpdateValue(IdUseMocks, value); + get { return _useMocksDefault; } + set { _useMocksDefault = value; } } public string UrlBase { - get => GetValueOrDefault(IdUrlBase, UrlBaseDefault); - set => AddOrUpdateValue(IdUrlBase, value); + get { return _urlBaseDefault; } + set { _urlBaseDefault = value; } } public bool UseFakeLocation { - get => GetValueOrDefault(IdUseFakeLocation, UseFakeLocationDefault); - set => AddOrUpdateValue(IdUseFakeLocation, value); + get { return _useFakeLocationDefault; } + set { _useFakeLocationDefault = value; } } public string Latitude { - get => GetValueOrDefault(IdLatitude, FakeLatitudeDefault.ToString()); - set => AddOrUpdateValue(IdLatitude, value); + get { return _fakeLatitudeDefault.ToString(); } + set { _fakeLatitudeDefault = Convert.ToDouble(value); } } public string Longitude { - get => GetValueOrDefault(IdLongitude, FakeLongitudeDefault.ToString()); - set => AddOrUpdateValue(IdLongitude, value); + get { return _fakeLongitudeDefault.ToString(); } + set { _fakeLongitudeDefault = Convert.ToDouble(value); } } public bool AllowGpsLocation { - get => GetValueOrDefault(IdAllowGpsLocation, AllowGpsLocationDefault); - set => AddOrUpdateValue(IdAllowGpsLocation, value); - } - - public Task AddOrUpdateValue(string key, bool value) => AddOrUpdateValueInternal(key, value); - public Task 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); - - Task AddOrUpdateValueInternal(string key, T value) - { - if (value == null) - { - Remove(key); - } - - _settings[key] = value; - return Task.Delay(10); - } - - T GetValueOrDefaultInternal(string key, T defaultValue = default(T)) - { - object value = null; - if (_settings.ContainsKey(key)) - { - value = _settings[key]; - } - return null != value ? (T)value : defaultValue; - } - - void Remove(string key) - { - if (_settings[key] != null) - { - _settings.Remove(key); - } + get { return _allowGpsLocationDefault; } + set { _allowGpsLocationDefault = value; } } } } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Windows/Services/SettingsServiceImplementation.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Windows/Services/SettingsServiceImplementation.cs new file mode 100644 index 000000000..e13fafd9f --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Windows/Services/SettingsServiceImplementation.cs @@ -0,0 +1,99 @@ +using eShopOnContainers.Core.Services.Settings; +using eShopOnContainers.Windows.Services; +using Windows.Storage; + +[assembly: Xamarin.Forms.Dependency(typeof(SettingsServiceImplementation))] +namespace eShopOnContainers.Windows.Services +{ + public class SettingsServiceImplementation : ISettingsServiceImplementation + { + #region Internal Implementation + + readonly object _locker = new object(); + + ApplicationDataContainer GetAppSettings() + { + return ApplicationData.Current.LocalSettings; + } + + bool AddOrUpdateValueInternal(string key, T value) + { + bool valueChanged = false; + + if (value == null) + { + Remove(key); + return true; + } + + lock (_locker) + { + var settings = GetAppSettings(); + if (settings.Values.ContainsKey(key)) + { + if (settings.Values[key] != (object)value) + { + settings.Values[key] = value; + valueChanged = true; + } + } + else + { + settings.Values[key] = value; + valueChanged = true; + } + } + + return valueChanged; + } + + T GetValueOrDefaultInternal(string key, T defaultValue = default(T)) + { + object value; + + lock (_locker) + { + var settings = GetAppSettings(); + if (settings.Values.ContainsKey(key)) + { + var tempValue = settings.Values[key]; + if (tempValue != null) + value = (T)tempValue; + else + value = defaultValue; + } + else + { + value = defaultValue; + } + } + return null != value ? (T)value : defaultValue; + } + + #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) + { + lock (_locker) + { + var settings = GetAppSettings(); + if (settings.Values.ContainsKey(key)) + { + settings.Values.Remove(key); + } + } + } + + #endregion + } +} diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Windows/eShopOnContainers.Windows.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.Windows/eShopOnContainers.Windows.csproj index 9a1a2d108..b879d31c6 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Windows/eShopOnContainers.Windows.csproj +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Windows/eShopOnContainers.Windows.csproj @@ -123,6 +123,7 @@ + diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/Services/SettingsServiceImplementation.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/Services/SettingsServiceImplementation.cs new file mode 100644 index 000000000..ee17b8ff7 --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/Services/SettingsServiceImplementation.cs @@ -0,0 +1,128 @@ +using eShopOnContainers.Core.Services.Settings; +using eShopOnContainers.iOS.Services; +using Foundation; +using System; + +[assembly: Xamarin.Forms.Dependency(typeof(SettingsServiceImplementation))] +namespace eShopOnContainers.iOS.Services +{ + public class SettingsServiceImplementation : ISettingsServiceImplementation + { + #region Internal Implementation + + readonly object _locker = new object(); + + NSUserDefaults GetUserDefaults() => NSUserDefaults.StandardUserDefaults; + + bool AddOrUpdateValueInternal(string key, T value) + { + 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) + { + var defaults = GetUserDefaults(); + switch (typeCode) + { + case TypeCode.Boolean: + defaults.SetBool(Convert.ToBoolean(value), key); + break; + case TypeCode.String: + defaults.SetString(Convert.ToString(value), key); + break; + default: + throw new ArgumentException($"Value of type {typeCode} is unsupported."); + } + + try + { + defaults.Synchronize(); + } + catch (Exception ex) + { + Console.WriteLine("Unable to save: " + key, " Message: " + ex.Message); + } + } + return true; + } + + T GetValueOrDefaultInternal(string key, T defaultValue = default(T)) + { + lock (_locker) + { + var defaults = GetUserDefaults(); + + if (defaults[key] == null) + { + return defaultValue; + } + + 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 = defaults.BoolForKey(key); + break; + case TypeCode.String: + value = defaults.StringForKey(key); + break; + default: + throw new ArgumentException($"Value of type {typeCode} is unsupported."); + } + + return null != value ? (T)value : defaultValue; + } + } + + #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) + { + lock (_locker) + { + var defaults = GetUserDefaults(); + try + { + if (defaults[key] != null) + { + defaults.RemoveObject(key); + defaults.Synchronize(); + } + } + catch (Exception ex) + { + Console.WriteLine("Unable to remove: " + key, " Message: " + ex.Message); + } + } + } + + #endregion + } +} diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj index 3d18f3a5c..6ea0a4465 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.iOS/eShopOnContainers.iOS.csproj @@ -1,428 +1,429 @@  - + + + Debug + iPhoneSimulator + 8.0.30703 + 2.0 + {6EEB23DC-7063-4444-9AF8-90DF24F549C0} + {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Exe + eShopOnContainers.iOS + Resources + eShopOnContainersiOS + + + true + + + true + full + false + bin\iPhoneSimulator\Debug + DEBUG + prompt + 4 + false + i386, x86_64 + None + True + False + False + False + False + False + True + Default + HttpClientHandler + False + + + none + true + bin\iPhoneSimulator\Release + prompt + 4 + None + i386, x86_64 + false + + + true + full + false + bin\iPhone\Debug + DEBUG + prompt + 4 + false + ARMv7, ARM64 + iPhone Developer + true + Entitlements.plist + None + + + none + true + bin\iPhone\Release + prompt + 4 + ARMv7, ARM64 + false + iPhone Developer + Entitlements.plist + + + none + True + bin\iPhone\Ad-Hoc + prompt + 4 + False + ARMv7, ARM64 + True + Automatic:AdHoc + iPhone Distribution + Entitlements.plist + + + none + True + bin\iPhone\AppStore + prompt + 4 + False + ARMv7, ARM64 + Automatic:AppStore + iPhone Distribution + Entitlements.plist + + + + + + + Resources\fonts\Montserrat-Bold.ttf + + + Resources\fonts\Montserrat-Regular.ttf + + + Resources\fonts\SourceSansPro-Regular.ttf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll + + + ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll + + + ..\..\..\..\packages\WebP.Touch.1.0.7\lib\Xamarin.iOS10\WebP.Touch.dll + + + ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.dll + + + ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Platform.dll + + + ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.dll + + + ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.Touch.dll + + + ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.dll + + + ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.iOS.dll + + + ..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.Abstractions.dll + + + ..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.dll + + + + ..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll + + + ..\..\..\..\packages\Acr.Support.2.1.0\lib\Xamarin.iOS10\Acr.Support.iOS.dll + + + ..\..\..\..\packages\BTProgressHUD.1.2.0.5\lib\Xamarin.iOS10\BTProgressHUD.dll + + + ..\..\..\..\packages\Splat.2.0.0\lib\Xamarin.iOS10\Splat.dll + + + ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.dll + + + ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.Interface.dll + + + ..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll + + + ..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll + + + ..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll + + + ..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll + + + ..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll + + + ..\..\..\..\packages\PCLCrypto.2.0.147\lib\xamarinios10\PCLCrypto.dll + + + ..\..\..\..\packages\IdentityModel.3.0.0\lib\netstandard2.0\IdentityModel.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7} + eShopOnContainers.Core + + + + + + + + + - Debug - iPhoneSimulator - 8.0.30703 - 2.0 - {6EEB23DC-7063-4444-9AF8-90DF24F549C0} - {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Exe - eShopOnContainers.iOS - Resources - eShopOnContainersiOS - - - true - true + 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}. - - true - full - false - bin\iPhoneSimulator\Debug - DEBUG - prompt - 4 - false - i386, x86_64 - None - True - False - False - False - False - False - True - Default - HttpClientHandler - False - - - none - true - bin\iPhoneSimulator\Release - prompt - 4 - None - i386, x86_64 - false - - - true - full - false - bin\iPhone\Debug - DEBUG - prompt - 4 - false - ARMv7, ARM64 - iPhone Developer - true - Entitlements.plist - None - - - none - true - bin\iPhone\Release - prompt - 4 - ARMv7, ARM64 - false - iPhone Developer - Entitlements.plist - - - none - True - bin\iPhone\Ad-Hoc - prompt - 4 - False - ARMv7, ARM64 - True - Automatic:AdHoc - iPhone Distribution - Entitlements.plist - - - none - True - bin\iPhone\AppStore - prompt - 4 - False - ARMv7, ARM64 - Automatic:AppStore - iPhone Distribution - Entitlements.plist - - - - - - - Resources\fonts\Montserrat-Bold.ttf - - - Resources\fonts\Montserrat-Regular.ttf - - - Resources\fonts\SourceSansPro-Regular.ttf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll - - - ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll - - - ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll - - - ..\..\..\..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll - - - ..\..\..\..\packages\WebP.Touch.1.0.7\lib\Xamarin.iOS10\WebP.Touch.dll - - - ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.dll - - - ..\..\..\..\packages\Xamarin.FFImageLoading.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Platform.dll - - - ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.dll - - - ..\..\..\..\packages\Xamarin.FFImageLoading.Forms.2.3.4\lib\Xamarin.iOS10\FFImageLoading.Forms.Touch.dll - - - ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.dll - - - ..\..\..\..\packages\SlideOverKit.2.1.5\lib\Xamarin.iOS10\SlideOverKit.iOS.dll - - - ..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.Abstractions.dll - - - ..\..\..\..\packages\Xam.Plugins.Settings.3.1.1\lib\Xamarin.iOS10\Plugin.Settings.dll - - - ..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll - - - ..\..\..\..\packages\Acr.Support.2.1.0\lib\Xamarin.iOS10\Acr.Support.iOS.dll - - - ..\..\..\..\packages\BTProgressHUD.1.2.0.5\lib\Xamarin.iOS10\BTProgressHUD.dll - - - ..\..\..\..\packages\Splat.2.0.0\lib\Xamarin.iOS10\Splat.dll - - - ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.dll - - - ..\..\..\..\packages\Acr.UserDialogs.6.5.1\lib\Xamarin.iOS10\Acr.UserDialogs.Interface.dll - - - ..\..\..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll - - - ..\..\..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll - - - ..\..\..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll - - - ..\..\..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll - - - ..\..\..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll - - - ..\..\..\..\packages\PCLCrypto.2.0.147\lib\xamarinios10\PCLCrypto.dll - - - ..\..\..\..\packages\IdentityModel.3.0.0\lib\netstandard2.0\IdentityModel.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {76C5F2A7-6CD5-49EA-9F33-EC44DE6539C7} - eShopOnContainers.Core - - - - - - - - - - - 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}. - - - - \ No newline at end of file + + + diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs index b6dd5a4b0..b604959b8 100644 --- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs +++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs @@ -34,10 +34,6 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers public async Task Get(string id) { var basket = await _repository.GetBasketAsync(id); - if (basket == null) - { - return NotFound(); - } return Ok(basket); } diff --git a/src/Services/Basket/Basket.API/Properties/launchSettings.json b/src/Services/Basket/Basket.API/Properties/launchSettings.json index 60a56b153..36effc287 100644 --- a/src/Services/Basket/Basket.API/Properties/launchSettings.json +++ b/src/Services/Basket/Basket.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:58017/", + "applicationUrl": "http://localhost:5103/", "sslPort": 0 } }, @@ -19,7 +19,7 @@ "Microsoft.eShopOnContainers.Services.Basket.API": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "http://localhost:55103/", + "launchUrl": "http://localhost:5000/swagger", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs index 71f700762..1b53171d0 100644 --- a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs +++ b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs @@ -32,16 +32,11 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers // GET api/v1/[controller]/items[?pageSize=3&pageIndex=10] [HttpGet] - [Route("items")] + [Route("[action]")] [ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)] - [ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)] - public async Task Items([FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0, [FromQuery] string ids = null) - { - if (!string.IsNullOrEmpty(ids)) - { - return GetItemsByIds(ids); - } + public async Task Items([FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) + { var totalItems = await _catalogContext.CatalogItems .LongCountAsync(); @@ -59,23 +54,6 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers return Ok(model); } - private IActionResult GetItemsByIds(string ids) - { - var numIds = ids.Split(',') - .Select(id => (Ok: int.TryParse(id, out int x), Value: x)); - if (!numIds.All(nid => nid.Ok)) - { - return BadRequest("ids value invalid. Must be comma-separated list of numbers"); - } - - var idsToSelect = numIds.Select(id => id.Value); - var items = _catalogContext.CatalogItems.Where(ci => idsToSelect.Contains(ci.Id)).ToList(); - - items = ChangeUriPlaceholder(items); - return Ok(items); - - } - [HttpGet] [Route("items/{id:int}")] [ProducesResponseType((int)HttpStatusCode.NotFound)] @@ -88,11 +66,6 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers } var item = await _catalogContext.CatalogItems.SingleOrDefaultAsync(ci => ci.Id == id); - - var baseUri = _settings.PicBaseUrl; - var azureStorageEnabled = _settings.AzureStorageEnabled; - item.FillProductUrl(baseUri, azureStorageEnabled: azureStorageEnabled); - if (item != null) { return Ok(item); @@ -271,12 +244,13 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers private List ChangeUriPlaceholder(List items) { var baseUri = _settings.PicBaseUrl; - var azureStorageEnabled = _settings.AzureStorageEnabled; - foreach (var item in items) + items.ForEach(catalogItem => { - item.FillProductUrl(baseUri, azureStorageEnabled: azureStorageEnabled); - } + catalogItem.PictureUri = _settings.AzureStorageEnabled + ? baseUri + catalogItem.PictureFileName + : baseUri.Replace("[0]", catalogItem.Id.ToString()); + }); return items; } diff --git a/src/Services/Catalog/Catalog.API/Extensions/CatalogItemExtensions.cs b/src/Services/Catalog/Catalog.API/Extensions/CatalogItemExtensions.cs deleted file mode 100644 index 71b9d88a3..000000000 --- a/src/Services/Catalog/Catalog.API/Extensions/CatalogItemExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.Services.Catalog.API.Model -{ - public static class CatalogItemExtensions - { - public static void FillProductUrl(this CatalogItem item, string picBaseUrl, bool azureStorageEnabled) - { - item.PictureUri = azureStorageEnabled - ? picBaseUrl + item.PictureFileName - : picBaseUrl.Replace("[0]", item.Id.ToString()); - } - } -} diff --git a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json index 2b21ca280..1bf8eb1f3 100644 --- a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json +++ b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:57424/", + "applicationUrl": "http://localhost:5101", "sslPort": 0 } }, @@ -19,7 +19,6 @@ "Microsoft.eShopOnContainers.Services.Catalog.API": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "http://localhost:55101/", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Services/Identity/Identity.API/Properties/launchSettings.json b/src/Services/Identity/Identity.API/Properties/launchSettings.json index e52e9f99c..91f06fd57 100644 --- a/src/Services/Identity/Identity.API/Properties/launchSettings.json +++ b/src/Services/Identity/Identity.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:54010/", + "applicationUrl": "http://localhost:5105", "sslPort": 0 } }, @@ -11,7 +11,7 @@ "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, - "launchUrl": "http://localhost:55105", + "launchUrl": "http://localhost:5105", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -19,7 +19,7 @@ "eShopOnContainers.Identity": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "http://localhost:55105", + "launchUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Services/Location/Locations.API/Properties/launchSettings.json b/src/Services/Location/Locations.API/Properties/launchSettings.json index 1c86a33b1..45b637914 100644 --- a/src/Services/Location/Locations.API/Properties/launchSettings.json +++ b/src/Services/Location/Locations.API/Properties/launchSettings.json @@ -1,9 +1,9 @@ -{ +{ "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:54020/", + "applicationUrl": "http://localhost:3278/", "sslPort": 0 } }, @@ -26,4 +26,4 @@ "applicationUrl": "http://localhost:3279" } } -} \ No newline at end of file +} diff --git a/src/Services/Marketing/Marketing.API/Properties/launchSettings.json b/src/Services/Marketing/Marketing.API/Properties/launchSettings.json index dea046099..e222e065d 100644 --- a/src/Services/Marketing/Marketing.API/Properties/launchSettings.json +++ b/src/Services/Marketing/Marketing.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:63455/", + "applicationUrl": "http://localhost:5110", "sslPort": 0 } }, diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs index 1f6e41005..43f2c6072 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.Serialization; using System.Collections; using Ordering.API.Application.Models; -using System.Linq; namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands { @@ -72,7 +71,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands string cardNumber, string cardHolderName, DateTime cardExpiration, string cardSecurityNumber, int cardTypeId) : this() { - _orderItems = basketItems.ToOrderItemsDTO().ToList(); + _orderItems = MapToOrderItems(basketItems); UserId = userId; UserName = userName; City = city; @@ -88,6 +87,20 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands CardExpiration = cardExpiration; } + private List MapToOrderItems(List basketItems) + { + var result = new List(); + basketItems.ForEach((item) => { + result.Add(new OrderItemDTO() { + ProductId = int.TryParse(item.ProductId, out int id) ? id : -1, + ProductName = item.ProductName, + PictureUrl = item.PictureUrl, + UnitPrice = item.UnitPrice, + Units = item.Quantity + }); + }); + return result; + } public class OrderItemDTO { diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommand.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommand.cs deleted file mode 100644 index 1d3d52c63..000000000 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommand.cs +++ /dev/null @@ -1,27 +0,0 @@ -using MediatR; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; -using Ordering.API.Application.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Threading.Tasks; -using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand; - -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands -{ - public class CreateOrderDraftCommand : IRequest - { - - public string BuyerId { get; private set; } - - public IEnumerable Items { get; private set; } - - public CreateOrderDraftCommand(string buyerId, IEnumerable items) - { - BuyerId = buyerId; - Items = items; - } - } - -} diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommandHandler.cs deleted file mode 100644 index 2c315248b..000000000 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommandHandler.cs +++ /dev/null @@ -1,72 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands -{ - using Domain.AggregatesModel.OrderAggregate; - using global::Ordering.API.Application.Models; - using MediatR; - using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services; - using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Threading; - using System.Threading.Tasks; - using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand; - - // Regular CommandHandler - public class CreateOrderDraftCommandHandler - : IRequestHandler - { - private readonly IOrderRepository _orderRepository; - private readonly IIdentityService _identityService; - private readonly IMediator _mediator; - - // Using DI to inject infrastructure persistence Repositories - public CreateOrderDraftCommandHandler(IMediator mediator, IIdentityService identityService) - { - _identityService = identityService ?? throw new ArgumentNullException(nameof(identityService)); - _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator)); - } - - public Task Handle(CreateOrderDraftCommand message, CancellationToken cancellationToken) - { - - var order = Order.NewDraft(); - var orderItems = message.Items.Select(i => i.ToOrderItemDTO()); - foreach (var item in orderItems) - { - order.AddOrderItem(item.ProductId, item.ProductName, item.UnitPrice, item.Discount, item.PictureUrl, item.Units); - } - - return Task.FromResult(OrderDraftDTO.FromOrder(order)); - } - } - - - public class OrderDraftDTO - { - public IEnumerable OrderItems { get; set; } - public decimal Total { get; set; } - - public static OrderDraftDTO FromOrder(Order order) - { - return new OrderDraftDTO() - { - OrderItems = order.OrderItems.Select(oi => new OrderItemDTO - { - Discount = oi.GetCurrentDiscount(), - ProductId = oi.ProductId, - UnitPrice = oi.GetUnitPrice(), - PictureUrl = oi.GetPictureUri(), - Units = oi.GetUnits(), - ProductName = oi.GetOrderItemProductName() - }), - Total = order.GetTotal() - }; - } - - } - - - - -} diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs index ac179c97f..993986543 100644 --- a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs +++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs @@ -5,7 +5,6 @@ using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries; using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services; using Ordering.API.Application.Commands; -using Ordering.API.Application.Models; using System; using System.Collections.Generic; using System.Net; @@ -102,14 +101,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers return Ok(cardTypes); } - - [Route("draft")] - [HttpPost] - public async Task GetOrderDraftFromBasketData([FromBody] CreateOrderDraftCommand createOrderDraftCommand) - { - var draft = await _mediator.Send(createOrderDraftCommand); - return Ok(draft); - } } } diff --git a/src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs b/src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs deleted file mode 100644 index 56f280978..000000000 --- a/src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand; - -namespace Ordering.API.Application.Models -{ - public static class BasketItemExtensions - { - public static IEnumerable ToOrderItemsDTO(this IEnumerable basketItems) - { - foreach (var item in basketItems) - { - yield return item.ToOrderItemDTO(); - } - } - - public static OrderItemDTO ToOrderItemDTO(this BasketItem item) - { - return new OrderItemDTO() - { - ProductId = int.TryParse(item.ProductId, out int id) ? id : -1, - ProductName = item.ProductName, - PictureUrl = item.PictureUrl, - UnitPrice = item.UnitPrice, - Units = item.Quantity - }; - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Properties/launchSettings.json b/src/Services/Ordering/Ordering.API/Properties/launchSettings.json index 9d9a76490..a6e47ca2d 100644 --- a/src/Services/Ordering/Ordering.API/Properties/launchSettings.json +++ b/src/Services/Ordering/Ordering.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:55102/", + "applicationUrl": "http://localhost:5102/", "sslPort": 0 } }, @@ -19,7 +19,7 @@ "Microsoft.eShopOnContainers.Services.Ordering.API": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "http://localhost:55102/", + "launchUrl": "http://localhost:5000/api/environmentInfo/machinename", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs index b3b7435e3..1b7896dcc 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs @@ -41,7 +41,13 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O _pictureUrl = PictureUrl; } - public string GetPictureUri() => _pictureUrl; + public void SetPictureUri(string pictureUri) + { + if (!String.IsNullOrWhiteSpace(pictureUri)) + { + _pictureUrl = pictureUri; + } + } public decimal GetCurrentDiscount() { diff --git a/src/Services/Payment/Payment.API/Properties/launchSettings.json b/src/Services/Payment/Payment.API/Properties/launchSettings.json index 5eac4c092..faf310f83 100644 --- a/src/Services/Payment/Payment.API/Properties/launchSettings.json +++ b/src/Services/Payment/Payment.API/Properties/launchSettings.json @@ -1,9 +1,9 @@ -{ +{ "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:63336/", + "applicationUrl": "http://localhost:3330/", "sslPort": 0 } }, @@ -26,4 +26,4 @@ "applicationUrl": "http://localhost:3331" } } -} \ No newline at end of file +} diff --git a/src/Web/WebMVC/Controllers/CartController.cs b/src/Web/WebMVC/Controllers/CartController.cs index 660da1d56..8b41c5320 100644 --- a/src/Web/WebMVC/Controllers/CartController.cs +++ b/src/Web/WebMVC/Controllers/CartController.cs @@ -49,8 +49,11 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers { var user = _appUserParser.Parse(HttpContext.User); var basket = await _basketSvc.SetQuantities(user, quantities); + var vm = await _basketSvc.UpdateBasket(basket); + if (action == "[ Checkout ]") { + var order = _basketSvc.MapBasketToOrder(basket); return RedirectToAction("Create", "Order"); } } @@ -67,11 +70,19 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers { try { - if (productDetails?.Id != null) + if (productDetails.Id != null) { var user = _appUserParser.Parse(HttpContext.User); - await _basketSvc.AddItemToBasket(user, productDetails.Id); - //await _basketSvc.AddItemToBasket(user, product); + var product = new BasketItem() + { + Id = Guid.NewGuid().ToString(), + Quantity = 1, + ProductName = productDetails.Name, + PictureUrl = productDetails.PictureUri, + UnitPrice = productDetails.Price, + ProductId = productDetails.Id + }; + await _basketSvc.AddItemToBasket(user, product); } return RedirectToAction("Index", "Catalog"); } diff --git a/src/Web/WebMVC/Controllers/OrderController.cs b/src/Web/WebMVC/Controllers/OrderController.cs index a5bf4785e..11e688728 100644 --- a/src/Web/WebMVC/Controllers/OrderController.cs +++ b/src/Web/WebMVC/Controllers/OrderController.cs @@ -27,9 +27,9 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers public async Task Create() { - var user = _appUserParser.Parse(HttpContext.User); - var order = await _basketSvc.GetOrderDraft(user.Id); + var basket = await _basketSvc.GetBasket(user); + var order = _basketSvc.MapBasketToOrder(basket); var vm = _orderSvc.MapUserInfoIntoOrder(user, order); vm.CardExpirationShortFormat(); diff --git a/src/Web/WebMVC/Controllers/TestController.cs b/src/Web/WebMVC/Controllers/TestController.cs deleted file mode 100644 index 1b35d5d2b..000000000 --- a/src/Web/WebMVC/Controllers/TestController.cs +++ /dev/null @@ -1,56 +0,0 @@ -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; -using Microsoft.eShopOnContainers.WebMVC.Services; -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace WebMVC.Controllers -{ - class TestPayload - { - public int CatalogItemId { get; set; } - public string BasketId { get; set; } - - public int Quantity { get; set; } - } - - [Authorize] - public class TestController : Controller - { - private readonly IHttpClient _client; - private readonly IIdentityParser _appUserParser; - public TestController(IHttpClient client, IIdentityParser identityParser) - { - _client = client; - _appUserParser = identityParser; - } - - public async Task Ocelot() - { - var url = "http://apigw/shopping/api/v1/basket/items"; - var payload = new TestPayload() - { - CatalogItemId = 1, - Quantity = 1, - BasketId = _appUserParser.Parse(User).Id - }; - var token = await HttpContext.GetTokenAsync("access_token"); - var response = await _client.PostAsync(url, payload, token); - - if (response.IsSuccessStatusCode) - { - var str = await response.Content.ReadAsStringAsync(); - return Ok(str); - } - else - { - return Ok(new { response.StatusCode, response.ReasonPhrase }); - } - } - } -} diff --git a/src/Web/WebMVC/Infrastructure/API.cs b/src/Web/WebMVC/Infrastructure/API.cs index d6f485e21..edb2c5ed5 100644 --- a/src/Web/WebMVC/Infrastructure/API.cs +++ b/src/Web/WebMVC/Infrastructure/API.cs @@ -4,21 +4,27 @@ namespace WebMVC.Infrastructure { public static class API { - - public static class Purchase + public static class Basket { - public static string AddItemToBasket(string baseUri) => $"{baseUri}/basket/items"; - public static string UpdateBasketItem(string baseUri) => $"{baseUri}/basket/items"; + public static string GetBasket(string baseUri, string basketId) + { + return $"{baseUri}/{basketId}"; + } - public static string GetOrderDraft(string baseUri, string basketId) => $"{baseUri}/order/draft/{basketId}"; - } + public static string UpdateBasket(string baseUri) + { + return baseUri; + } - public static class Basket - { - public static string GetBasket(string baseUri, string basketId) => $"{baseUri}/{basketId}"; - public static string UpdateBasket(string baseUri) => baseUri; - public static string CheckoutBasket(string baseUri) => $"{baseUri}/checkout"; - public static string CleanBasket(string baseUri, string basketId) => $"{baseUri}/{basketId}"; + public static string CheckoutBasket(string baseUri) + { + return $"{baseUri}/checkout"; + } + + public static string CleanBasket(string baseUri, string basketId) + { + return $"{baseUri}/{basketId}"; + } } public static class Order @@ -94,7 +100,7 @@ namespace WebMVC.Infrastructure public static string CreateOrUpdateUserLocation(string baseUri) { return baseUri; - } + } } } } \ No newline at end of file diff --git a/src/Web/WebMVC/Services/BasketService.cs b/src/Web/WebMVC/Services/BasketService.cs index 54287a796..6c8524800 100644 --- a/src/Web/WebMVC/Services/BasketService.cs +++ b/src/Web/WebMVC/Services/BasketService.cs @@ -5,7 +5,6 @@ using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.Extensions.Options; using Newtonsoft.Json; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using WebMVC.Infrastructure; using WebMVC.Models; @@ -15,19 +14,14 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public class BasketService : IBasketService { private readonly IOptionsSnapshot _settings; - private readonly IHttpClient _apiClient; - private readonly string _basketByPassUrl; - private readonly string _purchaseUrl; - private readonly IHttpContextAccessor _httpContextAccesor; + private IHttpClient _apiClient; + private readonly string _remoteServiceBaseUrl; + private IHttpContextAccessor _httpContextAccesor; - private readonly string _bffUrl; - - public BasketService(IOptionsSnapshot settings, - IHttpContextAccessor httpContextAccesor, IHttpClient httpClient) + public BasketService(IOptionsSnapshot settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient) { _settings = settings; - _basketByPassUrl = $"{_settings.Value.PurchaseUrl}/api/v1/b/basket"; - _purchaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1"; + _remoteServiceBaseUrl = $"{_settings.Value.BasketUrl}/api/v1/basket"; _httpContextAccesor = httpContextAccesor; _apiClient = httpClient; } @@ -35,19 +29,24 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public async Task GetBasket(ApplicationUser user) { var token = await GetUserTokenAsync(); - var getBasketUri = API.Basket.GetBasket(_basketByPassUrl, user.Id); + var getBasketUri = API.Basket.GetBasket(_remoteServiceBaseUrl, user.Id); var dataString = await _apiClient.GetStringAsync(getBasketUri, token); - return string.IsNullOrEmpty(dataString) ? - new Basket() { BuyerId = user.Id} : - JsonConvert.DeserializeObject(dataString); + // Use the ?? Null conditional operator to simplify the initialization of response + var response = JsonConvert.DeserializeObject(dataString) ?? + new Basket() + { + BuyerId = user.Id + }; + + return response; } public async Task UpdateBasket(Basket basket) { var token = await GetUserTokenAsync(); - var updateBasketUri = API.Basket.UpdateBasket(_basketByPassUrl); + var updateBasketUri = API.Basket.UpdateBasket(_remoteServiceBaseUrl); var response = await _apiClient.PostAsync(updateBasketUri, basket, token); @@ -59,7 +58,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public async Task Checkout(BasketDTO basket) { var token = await GetUserTokenAsync(); - var updateBasketUri = API.Basket.CheckoutBasket(_basketByPassUrl); + var updateBasketUri = API.Basket.CheckoutBasket(_remoteServiceBaseUrl); var response = await _apiClient.PostAsync(updateBasketUri, basket, token); @@ -68,50 +67,60 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public async Task SetQuantities(ApplicationUser user, Dictionary quantities) { + var basket = await GetBasket(user); - var token = await GetUserTokenAsync(); - var updateBasketUri = API.Purchase.UpdateBasketItem(_purchaseUrl); - var userId = user.Id; - - var response = await _apiClient.PutAsync(updateBasketUri, new + basket.Items.ForEach(x => { - BasketId = userId, - Updates = quantities.Select(kvp => new + // Simplify this logic by using the + // new out variable initializer. + if (quantities.TryGetValue(x.Id, out var quantity)) { - BasketItemId = kvp.Key, - NewQty = kvp.Value - }).ToArray() - }, token); + x.Quantity = quantity; + } + }); - response.EnsureSuccessStatusCode(); - var jsonResponse = await response.Content.ReadAsStringAsync(); - return JsonConvert.DeserializeObject(jsonResponse); + return basket; } - public async Task GetOrderDraft(string basketId) + public Order MapBasketToOrder(Basket basket) { - var token = await GetUserTokenAsync(); - var draftOrderUri = API.Purchase.GetOrderDraft(_purchaseUrl, basketId); - var json = await _apiClient.GetStringAsync(draftOrderUri, token); - return JsonConvert.DeserializeObject(json); - } + var order = new Order(); + order.Total = 0; + basket.Items.ForEach(x => + { + order.OrderItems.Add(new OrderItem() + { + ProductId = int.Parse(x.ProductId), + PictureUrl = x.PictureUrl, + ProductName = x.ProductName, + Units = x.Quantity, + UnitPrice = x.UnitPrice + }); + order.Total += (x.Quantity * x.UnitPrice); + }); + + return order; + } - public async Task AddItemToBasket(ApplicationUser user, int productId) + public async Task AddItemToBasket(ApplicationUser user, BasketItem product) { - var token = await GetUserTokenAsync(); - var updateBasketUri = API.Purchase.AddItemToBasket(_purchaseUrl); - var userId = user.Id; + var basket = await GetBasket(user); - var response = await _apiClient.PostAsync(updateBasketUri, new + if (basket == null) { - CatalogItemId = productId, - BasketId = userId, - Quantity = 1 - }, token); + basket = new Basket() + { + BuyerId = user.Id, + Items = new List() + }; + } - } + basket.Items.Add(product); + + await UpdateBasket(basket); + } async Task GetUserTokenAsync() { diff --git a/src/Web/WebMVC/Services/CampaignService.cs b/src/Web/WebMVC/Services/CampaignService.cs index 7d61c9e7a..6190e74d6 100644 --- a/src/Web/WebMVC/Services/CampaignService.cs +++ b/src/Web/WebMVC/Services/CampaignService.cs @@ -26,7 +26,7 @@ _apiClient = httpClient; _logger = logger; - _remoteServiceBaseUrl = $"{_settings.Value.MarketingUrl}/api/v1/m/campaigns/"; + _remoteServiceBaseUrl = $"{_settings.Value.MarketingUrl}/api/v1/campaigns/"; _httpContextAccesor = httpContextAccesor ?? throw new ArgumentNullException(nameof(httpContextAccesor)); } diff --git a/src/Web/WebMVC/Services/CatalogService.cs b/src/Web/WebMVC/Services/CatalogService.cs index 5b6fbe26b..2af428e2e 100644 --- a/src/Web/WebMVC/Services/CatalogService.cs +++ b/src/Web/WebMVC/Services/CatalogService.cs @@ -25,7 +25,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services _apiClient = httpClient; _logger = logger; - _remoteServiceBaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1/c/catalog/"; + _remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/"; } public async Task GetCatalogItems(int page, int take, int? brand, int? type) diff --git a/src/Web/WebMVC/Services/IBasketService.cs b/src/Web/WebMVC/Services/IBasketService.cs index cfbea5ff0..13921909a 100644 --- a/src/Web/WebMVC/Services/IBasketService.cs +++ b/src/Web/WebMVC/Services/IBasketService.cs @@ -10,10 +10,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public interface IBasketService { Task GetBasket(ApplicationUser user); - Task AddItemToBasket(ApplicationUser user, int productId); + Task AddItemToBasket(ApplicationUser user, BasketItem product); Task UpdateBasket(Basket basket); Task Checkout(BasketDTO basket); Task SetQuantities(ApplicationUser user, Dictionary quantities); - Task GetOrderDraft(string basketId); + Order MapBasketToOrder(Basket basket); } } diff --git a/src/Web/WebMVC/Services/LocationService.cs b/src/Web/WebMVC/Services/LocationService.cs index 8bbdf743a..652484f4b 100644 --- a/src/Web/WebMVC/Services/LocationService.cs +++ b/src/Web/WebMVC/Services/LocationService.cs @@ -27,7 +27,7 @@ namespace WebMVC.Services _apiClient = httpClient; _logger = logger; - _remoteServiceBaseUrl = $"{_settings.Value.MarketingUrl}/api/v1/l/locations/"; + _remoteServiceBaseUrl = $"{_settings.Value.LocationsUrl}/api/v1/locations/"; _httpContextAccesor = httpContextAccesor ?? throw new ArgumentNullException(nameof(httpContextAccesor)); } diff --git a/src/Web/WebMVC/Services/OrderingService.cs b/src/Web/WebMVC/Services/OrderingService.cs index ec9d2e8fd..f36f1410d 100644 --- a/src/Web/WebMVC/Services/OrderingService.cs +++ b/src/Web/WebMVC/Services/OrderingService.cs @@ -21,7 +21,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public OrderingService(IOptionsSnapshot settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient) { - _remoteServiceBaseUrl = $"{settings.Value.PurchaseUrl}/api/v1/o/orders"; + _remoteServiceBaseUrl = $"{settings.Value.OrderingUrl}/api/v1/orders"; _settings = settings; _httpContextAccesor = httpContextAccesor; _apiClient = httpClient; diff --git a/src/Web/WebMVC/ViewModels/CatalogItem.cs b/src/Web/WebMVC/ViewModels/CatalogItem.cs index c869b7382..6dd216d1d 100644 --- a/src/Web/WebMVC/ViewModels/CatalogItem.cs +++ b/src/Web/WebMVC/ViewModels/CatalogItem.cs @@ -4,7 +4,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.ViewModels { public class CatalogItem { - public int Id { get; set; } + public string Id { get; set; } public string Name { get; set; } public string Description { get; set; } public decimal Price { get; set; } diff --git a/src/Web/WebMVC/Views/Catalog/_product.cshtml b/src/Web/WebMVC/Views/Catalog/_product.cshtml index 0fb1c39c4..11138b55d 100644 --- a/src/Web/WebMVC/Views/Catalog/_product.cshtml +++ b/src/Web/WebMVC/Views/Catalog/_product.cshtml @@ -12,5 +12,13 @@
@Model.Price.ToString("N2")
+ + + + + + + + diff --git a/src/Web/WebSPA/Client/modules/basket/basket.service.ts b/src/Web/WebSPA/Client/modules/basket/basket.service.ts index fef74974e..864915541 100644 --- a/src/Web/WebSPA/Client/modules/basket/basket.service.ts +++ b/src/Web/WebSPA/Client/modules/basket/basket.service.ts @@ -23,7 +23,6 @@ import { Subject } from 'rxjs/Subject'; @Injectable() export class BasketService { private basketUrl: string = ''; - private purchaseUrl: string = ''; basket: IBasket = { buyerId: '', items: [] @@ -41,14 +40,12 @@ export class BasketService { if (this.authService.UserData) { this.basket.buyerId = this.authService.UserData.sub; if (this.configurationService.isReady) { - this.basketUrl = this.configurationService.serverSettings.purchaseUrl; - this.purchaseUrl = this.configurationService.serverSettings.purchaseUrl; + this.basketUrl = this.configurationService.serverSettings.basketUrl; this.loadData(); } else { this.configurationService.settingsLoaded$.subscribe(x => { - this.basketUrl = this.configurationService.serverSettings.purchaseUrl; - this.purchaseUrl = this.configurationService.serverSettings.purchaseUrl; + this.basketUrl = this.configurationService.serverSettings.basketUrl; this.loadData(); }); } @@ -66,7 +63,7 @@ export class BasketService { } setBasket(basket): Observable { - let url = this.purchaseUrl + '/api/v1/basket/'; + let url = this.basketUrl + '/api/v1/basket/'; this.basket = basket; return this.service.post(url, basket).map((response: Response) => { return true; @@ -74,7 +71,7 @@ export class BasketService { } setBasketCheckout(basketCheckout): Observable { - let url = this.basketUrl + '/api/v1/b/basket/checkout'; + let url = this.basketUrl + '/api/v1/basket/checkout'; return this.service.postWithId(url, basketCheckout).map((response: Response) => { this.basketEvents.orderCreated(); return true; @@ -82,7 +79,7 @@ export class BasketService { } getBasket(): Observable { - let url = this.basketUrl + '/api/v1/b/basket/' + this.basket.buyerId; + let url = this.basketUrl + '/api/v1/basket/' + this.basket.buyerId; return this.service.get(url).map((response: Response) => { if (response.status === 204) { return null; diff --git a/src/Web/WebSPA/Client/modules/campaigns/campaigns.service.ts b/src/Web/WebSPA/Client/modules/campaigns/campaigns.service.ts index 2a8973322..bd1678f44 100644 --- a/src/Web/WebSPA/Client/modules/campaigns/campaigns.service.ts +++ b/src/Web/WebSPA/Client/modules/campaigns/campaigns.service.ts @@ -33,7 +33,7 @@ export class CampaignsService { } getCampaigns(pageIndex: number, pageSize: number): Observable { - let url = this.marketingUrl + '/api/v1/m/campaigns/user'; + let url = this.marketingUrl + '/api/v1/campaigns/user'; url = url + '?pageIndex=' + pageIndex + '&pageSize=' + pageSize; return this.service.get(url).map((response: Response) => { @@ -42,7 +42,7 @@ export class CampaignsService { } getCampaign(id: number): Observable { - let url = this.marketingUrl + '/api/v1/m/campaigns/' + id; + let url = this.marketingUrl + '/api/v1/campaigns/' + id; return this.service.get(url).map((response: Response) => { return response.json(); diff --git a/src/Web/WebSPA/Client/modules/catalog/catalog.service.ts b/src/Web/WebSPA/Client/modules/catalog/catalog.service.ts index fc5bc4c5e..bdcb9d664 100644 --- a/src/Web/WebSPA/Client/modules/catalog/catalog.service.ts +++ b/src/Web/WebSPA/Client/modules/catalog/catalog.service.ts @@ -21,9 +21,9 @@ export class CatalogService { constructor(private service: DataService, private configurationService: ConfigurationService) { this.configurationService.settingsLoaded$.subscribe(x => { - this.catalogUrl = this.configurationService.serverSettings.purchaseUrl + '/api/v1/c/catalog/items'; - this.brandUrl = this.configurationService.serverSettings.purchaseUrl + '/api/v1/c/catalog/catalogbrands'; - this.typesUrl = this.configurationService.serverSettings.purchaseUrl + '/api/v1/c/catalog/catalogtypes'; + this.catalogUrl = this.configurationService.serverSettings.catalogUrl + '/api/v1/catalog/items'; + this.brandUrl = this.configurationService.serverSettings.catalogUrl + '/api/v1/catalog/catalogbrands'; + this.typesUrl = this.configurationService.serverSettings.catalogUrl + '/api/v1/catalog/catalogtypes'; }); } diff --git a/src/Web/WebSPA/Client/modules/orders/orders.service.ts b/src/Web/WebSPA/Client/modules/orders/orders.service.ts index 5c563f836..5eda7c8ce 100644 --- a/src/Web/WebSPA/Client/modules/orders/orders.service.ts +++ b/src/Web/WebSPA/Client/modules/orders/orders.service.ts @@ -22,14 +22,14 @@ export class OrdersService { constructor(private service: DataService, private basketService: BasketWrapperService, private identityService: SecurityService, private configurationService: ConfigurationService) { if (this.configurationService.isReady) - this.ordersUrl = this.configurationService.serverSettings.purchaseUrl; + this.ordersUrl = this.configurationService.serverSettings.orderingUrl; else - this.configurationService.settingsLoaded$.subscribe(x => this.ordersUrl = this.configurationService.serverSettings.purchaseUrl); + this.configurationService.settingsLoaded$.subscribe(x => this.ordersUrl = this.configurationService.serverSettings.orderingUrl); } getOrders(): Observable { - let url = this.ordersUrl + '/api/v1/o/orders'; + let url = this.ordersUrl + '/api/v1/orders'; return this.service.get(url).map((response: Response) => { return response.json(); @@ -37,7 +37,7 @@ export class OrdersService { } getOrder(id: number): Observable { - let url = this.ordersUrl + '/api/v1/o/orders/' + id; + let url = this.ordersUrl + '/api/v1/orders/' + id; return this.service.get(url).map((response: Response) => { return response.json(); diff --git a/src/Web/WebSPA/Properties/launchSettings.json b/src/Web/WebSPA/Properties/launchSettings.json index eff752f63..fd33f59ec 100644 --- a/src/Web/WebSPA/Properties/launchSettings.json +++ b/src/Web/WebSPA/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:58018/", + "applicationUrl": "http://localhost:5104/", "sslPort": 0 } }, diff --git a/src/Web/WebSPA/appsettings.json b/src/Web/WebSPA/appsettings.json index 75f17ac35..7b1930f84 100644 --- a/src/Web/WebSPA/appsettings.json +++ b/src/Web/WebSPA/appsettings.json @@ -1,8 +1,10 @@ { + "CatalogUrl": "http://localhost:5101", + "OrderingUrl": "http://localhost:5102", + "BasketUrl": "http://localhost:5103", "IdentityUrl": "http://localhost:5105", "MarketingUrl": "http://localhost:5110", "CallBackUrl": "http://localhost:5104/", - "PurchaseUrl": "http://localhost:5200", "UseCustomizationData": true, "IsClusterEnv": "False", "ActivateCampaignDetailFunction": true, diff --git a/src/Web/WebSPA/package-lock.json b/src/Web/WebSPA/package-lock.json index 029914660..1e8a7df95 100644 --- a/src/Web/WebSPA/package-lock.json +++ b/src/Web/WebSPA/package-lock.json @@ -1195,7 +1195,6 @@ "requires": { "anymatch": "1.3.2", "async-each": "1.0.1", - "fsevents": "1.1.3", "glob-parent": "2.0.0", "inherits": "2.0.3", "is-binary-path": "1.0.1", @@ -2826,910 +2825,6 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "fsevents": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", - "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", - "dev": true, - "optional": true, - "requires": { - "nan": "2.6.2", - "node-pre-gyp": "0.6.39" - }, - "dependencies": { - "abbrev": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "ajv": { - "version": "4.11.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.9" - } - }, - "asn1": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "assert-plus": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "balanced-match": { - "version": "0.4.2", - "bundled": true, - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "boom": { - "version": "2.10.1", - "bundled": true, - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "0.4.2", - "concat-map": "0.0.1" - } - }, - "buffer-shims": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true - }, - "co": { - "version": "4.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, - "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "debug": { - "version": "2.6.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.4.2", - "bundled": true, - "dev": true, - "optional": true - }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "extend": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "extsprintf": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "optional": true - }, - "form-data": { - "version": "2.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" - } - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "1.1.1", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, - "dev": true - }, - "har-schema": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "hawk": { - "version": "3.1.3", - "bundled": true, - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "bundled": true, - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.4", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "jodid25519": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "jsonify": { - "version": "0.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "jsprim": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "mime-db": { - "version": "1.27.0", - "bundled": true, - "dev": true - }, - "mime-types": { - "version": "2.1.15", - "bundled": true, - "dev": true, - "requires": { - "mime-db": "1.27.0" - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "node-pre-gyp": { - "version": "0.6.39", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "1.0.2", - "hawk": "3.1.3", - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", - "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" - } - }, - "npmlog": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true, - "dev": true - }, - "punycode": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true - }, - "qs": { - "version": "6.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.2.9", - "bundled": true, - "dev": true, - "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", - "util-deprecate": "1.0.2" - } - }, - "request": { - "version": "2.81.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" - } - }, - "rimraf": { - "version": "2.6.1", - "bundled": true, - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "safe-buffer": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "semver": { - "version": "5.3.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sntp": { - "version": "1.0.9", - "bundled": true, - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "sshpk": { - "version": "1.13.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "stringstream": { - "version": "0.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "dev": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-pack": { - "version": "3.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" - } - }, - "tough-cookie": { - "version": "2.3.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "dev": true, - "optional": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "uuid": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "verror": { - "version": "1.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "extsprintf": "1.0.2" - } - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - } - } - }, "fstream": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", diff --git a/test/Services/UnitTest/Basket/Application/CartControllerTest.cs b/test/Services/UnitTest/Basket/Application/CartControllerTest.cs index 63f74cf35..6bdd2c43c 100644 --- a/test/Services/UnitTest/Basket/Application/CartControllerTest.cs +++ b/test/Services/UnitTest/Basket/Application/CartControllerTest.cs @@ -92,7 +92,7 @@ namespace UnitTest.Basket.Application //Arrange var fakeCatalogItem = GetFakeCatalogItem(); - _basketServiceMock.Setup(x => x.AddItemToBasket(It.IsAny(), It.IsAny())) + _basketServiceMock.Setup(x => x.AddItemToBasket(It.IsAny(), It.IsAny())) .Returns(Task.FromResult(1)); //Act @@ -118,7 +118,7 @@ namespace UnitTest.Basket.Application { return new CatalogItem() { - Id = 1, + Id = "1", Name = "fakeName", CatalogBrand = "fakeBrand", CatalogType = "fakeType", diff --git a/test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs b/test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs index 7410551e4..58d32c212 100644 --- a/test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs +++ b/test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs @@ -67,19 +67,19 @@ namespace UnitTest.Catalog.Application { new CatalogItem() { - Id = 1, + Id = "1", Name = "fakeItemA", CatalogTypeId = 1 }, new CatalogItem() { - Id = 2, + Id = "2", Name = "fakeItemB", CatalogTypeId = 1 }, new CatalogItem() { - Id = 3, + Id = "3", Name = "fakeItemC", CatalogTypeId = 1 } diff --git a/test/Services/UnitTest/Ordering/Application/OrderControllerTest.cs b/test/Services/UnitTest/Ordering/Application/OrderControllerTest.cs index a60ce3bb3..12f2be395 100644 --- a/test/Services/UnitTest/Ordering/Application/OrderControllerTest.cs +++ b/test/Services/UnitTest/Ordering/Application/OrderControllerTest.cs @@ -68,7 +68,40 @@ namespace UnitTest.Ordering.Application Assert.IsAssignableFrom(viewResult.ViewData.Model); } - + [Fact] + public async Task Get_create_order_success() + { + //Arrange + var fakeBuyerId = "1"; + var fakeBasket = GetFakeBasket(fakeBuyerId); + var fakeOrder = GetFakeOrder(); + + _basketServiceMock.Setup(x => x.GetBasket(It.IsAny())) + .Returns(Task.FromResult(fakeBasket)); + + _basketServiceMock.Setup(x => x.MapBasketToOrder(It.IsAny())) + .Returns(fakeOrder); + + _orderServiceMock.Setup(x => x.MapUserInfoIntoOrder(It.IsAny(), It.IsAny())) + .Returns(fakeOrder); + + //Act + var orderController = new OrderController(_orderServiceMock.Object, _basketServiceMock.Object, _identityParserMock.Object); + orderController.ControllerContext.HttpContext = _contextMock.Object; + var actionResult = await orderController.Create(); + + //Assert + var viewResult = Assert.IsType(actionResult); + Assert.IsAssignableFrom(viewResult.ViewData.Model); + } + + private BasketModel GetFakeBasket(string buyerId) + { + return new BasketModel() + { + BuyerId = buyerId + }; + } private Order GetFakeOrder() { diff --git a/xglobal.json b/xglobal.json deleted file mode 100644 index 2ab18dceb..000000000 --- a/xglobal.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version":"2.1.2" - } -} \ No newline at end of file