Music store updates, polish, add Tye

This commit is contained in:
Tim Hess 2020-10-28 11:20:07 -04:00
Родитель be85fc30c2
Коммит 53f6a67a73
52 изменённых файлов: 407 добавлений и 2377 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -221,3 +221,4 @@ pivnet*
pivotal*.zip
GeneratedCertificates/
.tye/

Просмотреть файл

@ -16,6 +16,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
..\.editorconfig = ..\.editorconfig
..\nuget.config = ..\nuget.config
README.md = README.md
tye.yaml = tye.yaml
..\config\versions.props = ..\config\versions.props
EndProjectSection
EndProject
@ -63,30 +64,30 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Kubernetes", "Kubernetes",
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GCP", "GCP", "{57E0407E-8053-4272-A772-EF9A37B0DD71}"
ProjectSection(SolutionItems) = preProject
deployment\GCP\gcp_deploy.ps1 = deployment\GCP\gcp_deploy.ps1
deployment\GCP\gcp_undeploy.ps1 = deployment\GCP\gcp_undeploy.ps1
EndProjectSection
ProjectSection(SolutionItems) = preProject
deployment\GCP\gcp_deploy.ps1 = deployment\GCP\gcp_deploy.ps1
deployment\GCP\gcp_undeploy.ps1 = deployment\GCP\gcp_undeploy.ps1
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AWS", "AWS", "{88DC4F07-1090-445C-AEEC-534FE1FAAF8D}"
ProjectSection(SolutionItems) = preProject
deployment\AWS\eks_deploy.ps1 = deployment\AWS\eks_deploy.ps1
EndProjectSection
ProjectSection(SolutionItems) = preProject
deployment\AWS\eks_deploy.ps1 = deployment\AWS\eks_deploy.ps1
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docker", "Docker", "{FDFDF2F0-B965-455B-9F29-380921F6FB19}"
ProjectSection(SolutionItems) = preProject
deployment\Docker\dockerrun-configserver.cmd = deployment\Docker\dockerrun-configserver.cmd
deployment\Docker\dockerrun-configserver.sh = deployment\Docker\dockerrun-configserver.sh
deployment\Docker\dockerrun-eurekaserver.cmd = deployment\Docker\dockerrun-eurekaserver.cmd
deployment\Docker\dockerrun-eurekaserver.sh = deployment\Docker\dockerrun-eurekaserver.sh
deployment\Docker\dockerrun-mysqlserver.cmd = deployment\Docker\dockerrun-mysqlserver.cmd
deployment\Docker\dockerrun-mysqlserver.sh = deployment\Docker\dockerrun-mysqlserver.sh
EndProjectSection
ProjectSection(SolutionItems) = preProject
deployment\Docker\dockerrun-configserver.cmd = deployment\Docker\dockerrun-configserver.cmd
deployment\Docker\dockerrun-configserver.sh = deployment\Docker\dockerrun-configserver.sh
deployment\Docker\dockerrun-eurekaserver.cmd = deployment\Docker\dockerrun-eurekaserver.cmd
deployment\Docker\dockerrun-eurekaserver.sh = deployment\Docker\dockerrun-eurekaserver.sh
deployment\Docker\dockerrun-mysqlserver.cmd = deployment\Docker\dockerrun-mysqlserver.cmd
deployment\Docker\dockerrun-mysqlserver.sh = deployment\Docker\dockerrun-mysqlserver.sh
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PKS", "PKS", "{AFFFEC3B-3938-4397-85B5-772507B5AAED}"
ProjectSection(SolutionItems) = preProject
deployment\PKS\pks_deploy.ps1 = deployment\PKS\pks_deploy.ps1
EndProjectSection
ProjectSection(SolutionItems) = preProject
deployment\PKS\pks_deploy.ps1 = deployment\PKS\pks_deploy.ps1
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

Просмотреть файл

@ -1,13 +1,13 @@
# Running the Music Store on Cloud Foundry
## Pre-requisites - CloudFoundry
1. Install Spring Cloud Services
1. (Optional) Install Redis service - for sharing Session and KeyRing storage between app instances.
1. Install Pivotal Apps Manager to access Management endpoints from Apps Manager.
1. Install Redis service - for sharing Session and KeyRing storage between app instances.
## Setup Services on CloudFoundry
As mentioned above, the application is dependent on the following services:
The application is dependent on the following services:
* Spring Cloud Config Server
* Spring Cloud Eureka Server

Просмотреть файл

@ -1,6 +1,6 @@
# Steeltoe MusicStore Sample Application
This repo tree contains a sample app illustrating how to use all of the Steeltoe components together in a ASP.NET Core application. This application is based on the ASP.NET Core reference app [MusicStore](https://github.com/aspnet/MusicStore) provided by Microsoft.
This repo tree contains a sample app illustrating how to use all of the Steeltoe components together in a ASP.NET Core application. This application is based on the ASP.NET Core reference app [MusicStore](https://github.com/dotnet/aspnetcore/tree/release/3.1/src/MusicStore) provided by Microsoft.
In creating this application, we took the Microsoft reference application and broke it up into multiple independent services:
@ -17,9 +17,10 @@ This application makes use of the following Steeltoe components:
* Spring Cloud Eureka Server Client for service discovery
* Steeltoe Connector for connecting to MySql using EFCore
* Steeltoe CircuitBreaker to help prevent cascading failures from lower level service failures
* Steeltoe Management for enabling management actuator endpoints that can be used by the Pivotal Apps Manager
* Optionally uses Steeltoe Redis Connector to connect to a Redis cache for Session storage. Note: This is required if you want to scale the MusicStoreUI component to multiple instances.
* Optionally uses Steeltoe Redis DataProtection provider to the cause the DataProtection KeyRing to be stored in a Redis cache. Note: This is also required if you want to scale the MusicStoreUI component to multiple instances.
* Steeltoe Management for enabling management actuator endpoints
* Spring Boot Admin for interacting with management actuators and viewing detailed service status
* Steeltoe Redis Connector to connect to a Redis cache for Session storage. Note: This is required if you want to scale the MusicStoreUI component to multiple instances.
* Steeltoe Redis DataProtection provider to the cause the DataProtection KeyRing to be stored in a Redis cache. Note: This is also required if you want to scale the MusicStoreUI component to multiple instances.
* Optionally uses Hystrix Dashboard for monitoring Circuit Breakers
The default is to NOT use a Redis cache for Session storage or DataProtection KeyRing storage. Details on how to enable it are provided below.
@ -28,122 +29,22 @@ The default is to NOT use a Redis cache for Session storage or DataProtection Ke
* Clone the Samples repo. (i.e. git clone <https://github.com/SteeltoeOSS/Samples>)
## Pre-requisites - Local
1. Installed .NET Core SDK.
1. You need running instances of the following external services on your local machine:
* Spring Cloud Config Server - listening @ `http://localhost:8888`
* Spring Cloud Eureka Server - listening @ `http://localhost:8761/eureka/`
* MySql Database Server - listening @ `localhost:3306` username: `root`, password: `steeltoe`
* Redis Cache - Optional, can be used for Session state backing store and KeyRing storage.
You have a three options to choose from in order to get these services up and running locally:
* Use Docker images
* Install each service manually.
Currently, the simplest way to get these up and running is to use the first option above:
### Pre-requisites - Using Docker images
### Using Docker compose
1. `cd Samples/MusicStore`
1. `docker-compose up` (currently only works if using Linux containers)
1. `docker-compose up`
## Building & Running MusicStore App - Locally
Once you have the pre-requisite services up and running then you are ready to build and run the various MusicStore services locally. The simplest way is to use the provided `run*.cmd or run*.sh` files.
For example, to startup the MusicStoreService:
### Using Project Tye
1. [Install Tye](https://github.com/dotnet/tye/blob/master/docs/getting_started.md)
1. `cd Samples/MusicStore`
1. `runMusicStoreService.cmd` or `./runMusicStoreService.sh`
1. `tye run --docker`
1. Browse to the [local Tye dashboard](http://localhost:8000) to see the status of all the services and find the URL of the Music Store UI
Its probably best to startup the `MusicStoreService`, `OrderService` and `ShoppingCartService` first and then follow up with the `MusicStoreUI` last.
## Cloud Foundry
The `run*.*` commands will `dotnet run -f netcoreapp2.1` (i.e. target .NET Core).
See [the Cloud Foundry readme](./README-CloudFoundry.md)
If all the services startup cleanly, you should be able to hit: <http://localhost:5555/> to see the Music Store.
## Other Platforms
## Debugging/Developing Locally on Windows
You should have no problem using the provided solution to launch the individual services in the debugger and set break points and walk through code as needed.
## Pre-requisites - CloudFoundry
1. Install Pivotal Cloud Foundry
1. Install Spring Cloud Services
1. Install .NET Core SDK.
1. Install Redis service if you want to use Redis for Session storage and KeyRing storage.
1. Install Pivotal Apps Manager 1.11+ if you want to access Management endpoints from Apps Manager.
## Setup Services on CloudFoundry
As mentioned above, the application is dependent on the following services:
* Spring Cloud Config Server
* Spring Cloud Eureka Server
* MySql Database Server - Default database used by all MusicStore services.
* Redis Cache - Optional! Note you have to specifically build/publish MusicStoreUI service to use Redis (Details below).
> Note: Redis Cache is required if you want to scale the MusicStoreUI app to multiple instances (e.g. cf scale musicui -i 2+). Redis is not required to scale the other microservices.
Before pushing the application to CloudFoundry you need to create those services. If you plan on using Redis, set the environment variable USE_REDIS_CACHE=true before running these command.
> Note: MySQL v2 uses different naming conventions by default than v1. If your environment uses MySQL v2, you may need to alter the createCloudFoundryServices script accordingly!
1. `cf target -o myOrg -s mySpace`
1. `cd Samples/MusicStore`
1. Optionally - `SET USE_REDIS_CACHE=true` or `export USE_REDIS_CACHE=true`
1. `start createCloudFoundryServices.cmd` or `./createCloudFoundryServices.sh`
This will create all of the services needed by the application. Specifically, it creates:
* mStoreConfig - Spring Cloud Config Server instance
* mStoreRegistry - Spring Cloud Eureka Server instance
* mStoreAccountsDB - MySql database instance for Users and Roles (Identity)
* mStoreOrdersDB - MySql database instance for Orders
* mStoreCartDB - MySql database instance for ShoppingCarts
* mStoreStoreDB - MySql database instance for MusicStore
* mStoreRedis(optionally) - Redis cache instance used by MusicStoreUI for storing Session state
> Note: The Spring Cloud Config Server instance created by the above script configures the Config Server instance to use the git repo: <https://github.com/SteeltoeOSS/musicStore-config.git>. This repo contains the same configuration files as those found in `Samples/MusicStore/config`.
No changes are required to the application configuration files before pushing the app to CloudFoundry.
> Note: If you wish to change what github repo the Config server instance uses, you can modify config-server.json before using the `createCloudFoundryServices` script above.
## Building & Pushing App - CloudFoundry
Once the services have been created and ready on CloudFoundry (i.e. check via `cf services`) then you can use the provided `push*.cmd or push*.sh` commands to startup the individual application services on CloudFoundry. For example to start the ShoppingCart service:
1. `cd Samples/MusicStore`
1. `pushShoppingCartService.cmd win10-x64 netcoreapp2.1` or `./pushShoppingCartService.sh ubuntu.16.04-x64 netcoreapp2.1`
Note: If you wish to use the Redis cache for storing Session state, you will have to set ENVIRONMENT variable `DefineConstants=USE_REDIS_CACHE` before building and pushing the MusicUI application.
Each of the `push*.*` scripts `dotnet publish` the MusicStore service targeting the `framework` and `runtime` you specify. They then push the MusicStore service using the appropriate CloudFoundry manifest found in the projects directory (e.g. `manifest-windows.yml`, `manifest.yml` ).
Note: If you are using self-signed certificates it is possible that you might run into SSL certificate validation issues when pushing these apps. The simplest way to fix this:
1. Disable certificate validation for the Spring Cloud Config Client. You can do this by editing `appsettings.json` and add `spring:cloud:config:validate_certificates=false`. You will need to do this for each of the applications.
Once you have pushed all the applications to Cloud Foundry, if you do a `cf a`, you should see the following applications:
* musicui - Music store User Interface
* musicstore - Music store database micro-service
* orderprocessing - Order processing micro-service
* shoppingcart - Shopping cart micro-service
```bash
name requested state instances memory disk urls
musicstore started 1/1 1G 1G musicstore.apps.testcloud.com
musicui started 1/1 1G 1G musicui.apps.testcloud.com
orderprocessing started 1/1 1G 1G orderprocessing.apps.testcloud.com
shoppingcart started 1/1 1G 1G shoppingcart.apps.testcloud.com
```
## Known Limitations
## Sample Databases
All MusicStore services (i.e. MusicStoreUI, OrderService, etc.) have their own database instance for persisting data. When a MusicStore service is started locally, it will always drop and recreate its database upon startup. When a MusicStore service is started on CloudFoundry, only the first instance (i.e. CF_INSTANCE_INDEX=0) will drop and recreate its database. Note then, the service is not fully ready until the first instance has finished initializing its database, even though other instances are ready.
Review the resources in the [deployment folder](./deployment) for templates and scripts for deploying to other platforms like Kubernetes

Просмотреть файл

@ -1,6 +1,6 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 5000
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src

Просмотреть файл

@ -1,116 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MusicStore.Models;
namespace MusicStoreService.Migrations
{
[DbContext(typeof(MusicStoreContext))]
[Migration("20190911151205_InitialCreate")]
partial class InitialCreate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0-preview9.19423.6")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("MusicStore.Models.Album", b =>
{
b.Property<int>("AlbumId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("AlbumArtUrl")
.HasColumnType("nvarchar(1024)")
.HasMaxLength(1024);
b.Property<int>("ArtistId")
.HasColumnType("int");
b.Property<DateTime>("Created")
.HasColumnType("datetime2");
b.Property<int>("GenreId")
.HasColumnType("int");
b.Property<int>("OrderCount")
.HasColumnType("int");
b.Property<decimal>("Price")
.HasColumnType("decimal(4,2)");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("nvarchar(160)")
.HasMaxLength(160);
b.HasKey("AlbumId");
b.HasIndex("ArtistId");
b.HasIndex("GenreId");
b.ToTable("Albums");
});
modelBuilder.Entity("MusicStore.Models.Artist", b =>
{
b.Property<int>("ArtistId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ArtistId");
b.ToTable("Artists");
});
modelBuilder.Entity("MusicStore.Models.Genre", b =>
{
b.Property<int>("GenreId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("GenreId");
b.ToTable("Genres");
});
modelBuilder.Entity("MusicStore.Models.Album", b =>
{
b.HasOne("MusicStore.Models.Artist", "Artist")
.WithMany()
.HasForeignKey("ArtistId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MusicStore.Models.Genre", "Genre")
.WithMany("Albums")
.HasForeignKey("GenreId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

Просмотреть файл

@ -1,91 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace MusicStoreService.Migrations
{
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Artists",
columns: table => new
{
ArtistId = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Artists", x => x.ArtistId);
});
migrationBuilder.CreateTable(
name: "Genres",
columns: table => new
{
GenreId = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(nullable: false),
Description = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Genres", x => x.GenreId);
});
migrationBuilder.CreateTable(
name: "Albums",
columns: table => new
{
AlbumId = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
GenreId = table.Column<int>(nullable: false),
ArtistId = table.Column<int>(nullable: false),
Title = table.Column<string>(maxLength: 160, nullable: false),
Price = table.Column<decimal>(type: "decimal(4,2)", nullable: false),
AlbumArtUrl = table.Column<string>(maxLength: 1024, nullable: true),
OrderCount = table.Column<int>(nullable: false),
Created = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Albums", x => x.AlbumId);
table.ForeignKey(
name: "FK_Albums_Artists_ArtistId",
column: x => x.ArtistId,
principalTable: "Artists",
principalColumn: "ArtistId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Albums_Genres_GenreId",
column: x => x.GenreId,
principalTable: "Genres",
principalColumn: "GenreId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Albums_ArtistId",
table: "Albums",
column: "ArtistId");
migrationBuilder.CreateIndex(
name: "IX_Albums_GenreId",
table: "Albums",
column: "GenreId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Albums");
migrationBuilder.DropTable(
name: "Artists");
migrationBuilder.DropTable(
name: "Genres");
}
}
}

Просмотреть файл

@ -1,114 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MusicStore.Models;
namespace MusicStoreService.Migrations
{
[DbContext(typeof(MusicStoreContext))]
partial class MusicStoreContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0-preview9.19423.6")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("MusicStore.Models.Album", b =>
{
b.Property<int>("AlbumId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("AlbumArtUrl")
.HasColumnType("nvarchar(1024)")
.HasMaxLength(1024);
b.Property<int>("ArtistId")
.HasColumnType("int");
b.Property<DateTime>("Created")
.HasColumnType("datetime2");
b.Property<int>("GenreId")
.HasColumnType("int");
b.Property<int>("OrderCount")
.HasColumnType("int");
b.Property<decimal>("Price")
.HasColumnType("decimal(4,2)");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("nvarchar(160)")
.HasMaxLength(160);
b.HasKey("AlbumId");
b.HasIndex("ArtistId");
b.HasIndex("GenreId");
b.ToTable("Albums");
});
modelBuilder.Entity("MusicStore.Models.Artist", b =>
{
b.Property<int>("ArtistId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ArtistId");
b.ToTable("Artists");
});
modelBuilder.Entity("MusicStore.Models.Genre", b =>
{
b.Property<int>("GenreId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("GenreId");
b.ToTable("Genres");
});
modelBuilder.Entity("MusicStore.Models.Album", b =>
{
b.HasOne("MusicStore.Models.Artist", "Artist")
.WithMany()
.HasForeignKey("ArtistId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MusicStore.Models.Genre", "Genre")
.WithMany("Albums")
.HasForeignKey("GenreId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

Просмотреть файл

@ -15,37 +15,27 @@
</None>
</ItemGroup>
<ItemGroup>
<!-- GitInfo provides $(Git*) properties used below -->
<PackageReference Include="Azure.Identity" Version="1.1.1" />
<PackageReference Include="GitInfo" Version="2.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
<!-- <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" /> -->
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureAppConfiguration" Version="3.0.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
<PackageReference Include="Steeltoe.Common.Hosting" Version="3.0.0-2430" />
<!--<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(ExtensionsVersion)" />-->
<!--<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="$(PomeloMySqlEFCoreVersion)" />-->
<PackageReference Include="Steeltoe.Extensions.Configuration.ConfigServerCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Connector.EFCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Discovery.ClientCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Management.CloudFoundryCore" Version="3.0.0-2430" />
<!--<PackageReference Include="Steeltoe.Management.ExporterCore" Version="3.0.0-1656" />-->
<PackageReference Include="Steeltoe.Management.TracingCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Extensions.Configuration.ConfigServerCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Connector.EFCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Discovery.Eureka" Version="3.0.1" />
<PackageReference Include="Steeltoe.Management.CloudFoundryCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Management.TracingCore" Version="3.0.1" />
<!-- GitInfo provides $(Git*) properties used below -->
<PackageReference Include="GitInfo" Version="2.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<!--<ItemGroup>
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Configuration\src\ConfigServerCore\Steeltoe.Extensions.Configuration.ConfigServerCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Connectors\src\Connector.EFCore\Steeltoe.CloudFoundry.Connector.EFCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Discovery\src\ClientCore\Steeltoe.Discovery.ClientCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Management\src\CloudFoundryCore\Steeltoe.Management.CloudFoundryCore.csproj" />
</ItemGroup>-->
<Target Name="_GitProperties" AfterTargets="CoreCompile">
<WriteLinesToFile File="git.properties" Lines="git.remote.origin.url=$(GitRoot)" Overwrite="true" />

Просмотреть файл

@ -6,9 +6,9 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MusicStore.Models;
using Steeltoe.Common.Hosting;
using Steeltoe.Discovery.Client;
using Steeltoe.Extensions.Configuration.ConfigServer;
using Steeltoe.Extensions.Logging;
using Steeltoe.Management.Endpoint;
using System;
namespace MusicStore
@ -26,49 +26,43 @@ namespace MusicStore
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webbuilder =>
{
webbuilder
.ConfigureKestrel(options =>
{
options.AllowSynchronousIO = true;
})
.UseStartup<Startup>()
.UseCloudHosting(5000);
})
.ConfigureAppConfiguration((builderContext, configBuilder) =>
{
if (builderContext.HostingEnvironment.EnvironmentName.Contains("Azure"))
{
var settings = configBuilder.Build();
configBuilder.AddAzureAppConfiguration(options => options.Connect(new Uri(settings["AppConfig:Endpoint"]), new ManagedIdentityCredential()));
}
else
{
configBuilder.AddConfigServer(builderContext.HostingEnvironment.EnvironmentName);
}
configBuilder.AddEnvironmentVariables();
})
.ConfigureLogging((context, builder) =>
{
builder.ClearProviders();
builder.AddDynamicConsole();
});
.ConfigureWebHostDefaults(webbuilder => webbuilder.UseStartup<Startup>())
.ConfigureAppConfiguration(AddRemoteConfiguration)
.AddAllActuators()
.AddDiscoveryClient();
private static void SeedDatabase(IHost host)
{
using var scope = host.Services.CreateScope();
var services = scope.ServiceProvider;
SampleData.InitializeMusicStoreDatabase(services);
}
try
private static Action<HostBuilderContext, IConfigurationBuilder> AddRemoteConfiguration =>
(builderContext, configBuilder) =>
{
SampleData.InitializeMusicStoreDatabase(services);
}
catch (Exception ex)
if (builderContext.HostingEnvironment.EnvironmentName.Contains("Azure"))
{
var settings = configBuilder.Build();
configBuilder.AddAzureAppConfiguration(options => options.Connect(new Uri(settings["AppConfig:Endpoint"]), new ManagedIdentityCredential()));
}
else
{
configBuilder.AddConfigServer(builderContext.HostingEnvironment.EnvironmentName, GetLoggerFactory());
}
configBuilder.AddEnvironmentVariables();
};
private static ILoggerFactory GetLoggerFactory()
{
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder => builder.SetMinimumLevel(LogLevel.Trace));
serviceCollection.AddLogging(builder => builder.AddConsole((opts) =>
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
opts.DisableColors = true;
}));
serviceCollection.AddLogging(builder => builder.AddDebug());
return serviceCollection.BuildServiceProvider().GetService<ILoggerFactory>();
}
}
}

Просмотреть файл

@ -1,15 +1,8 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MusicStore.Models;
using Steeltoe.Connector.SqlServer.EFCore;
using Steeltoe.Common;
using Steeltoe.Discovery.Client;
using Steeltoe.Extensions.Configuration.CloudFoundry;
using Steeltoe.Management.CloudFoundry;
using Steeltoe.Management.Endpoint.Env;
using Steeltoe.Management.Endpoint.Refresh;
using Steeltoe.Connector.MySql.EFCore;
using Steeltoe.Management.Tracing;
namespace MusicStore
@ -26,32 +19,12 @@ namespace MusicStore
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// this should be done automatically by Steeltoe somewhere else! Zipkin throws without it
if (Platform.IsCloudFoundry)
{
services.RegisterCloudFoundryApplicationInstanceInfo();
}
else
{
services.GetApplicationInstanceInfo();
}
// Add Steeltoe Management services
services.AddCloudFoundryActuators(Configuration);
services.AddEnvActuator(Configuration);
services.AddRefreshActuator(Configuration);
// Add framework services.
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
// Steeltoe Service Discovery
if (!Configuration.GetValue<bool>("DisableServiceDiscovery"))
{
services.AddDiscoveryClient(Configuration);
}
// Steeltoe MySQL Connector
services.AddDbContext<MusicStoreContext>(options => options.UseSqlServer(Configuration));
//services.AddDbContext<MusicStoreContext>(options => options.UseSqlServer(Configuration));
services.AddDbContext<MusicStoreContext>(options => options.UseMySql(Configuration));
services.AddDistributedTracing(Configuration, builder => builder.UseZipkinWithTraceOptions(services));
@ -64,23 +37,12 @@ namespace MusicStore
{
app.UseRouting();
// Add Steeltoe Management endpoints into pipeline
app.UseCloudFoundryActuators();
app.UseEnvActuator();
app.UseRefreshActuator();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
// Start Steeltoe Discovery services
if (!Configuration.GetValue<bool>("DisableServiceDiscovery"))
{
app.UseDiscoveryClient();
}
}
}
}

Просмотреть файл

@ -6,38 +6,24 @@
"Default": "Information"
}
},
"Spring": {
"Application": {
"Name": "musicservice"
},
"Cloud": {
"Config": {
"uri": "http://localhost:8888",
"ValidateCertificates": false
}
}
},
"Management": {
"Endpoints": {
"CloudFoundry": {
"ValidateCertificates": false
}
},
"tracing":{
"alwaysSample": true,
"useShortTraceIds": true,
"exporter": {
"zipkin": {
"endpoint": "http://zipkinserver:9411/api/v2/spans",
"validateCertificates": false,
"useShortTraceIds ": true
}
}
}
},
"SqlServer": {
"Credentials": {
"Database": "MusicService"
"Spring": {
"Cloud": {
"Config": {
"Uri": "http://configserver:8888",
"FailFast": true
}
}
}
}
}

Просмотреть файл

@ -1,6 +1,6 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 5555
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src

Просмотреть файл

@ -1,295 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MusicStoreUI.Models;
namespace MusicStoreUI.Migrations
{
[DbContext(typeof(AccountsContext))]
[Migration("20190911191239_InitialCreate")]
partial class InitialCreate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0-preview9.19423.6")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.HasColumnType("nvarchar(255)")
.HasMaxLength(255);
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasName("RoleNameIndex")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles");
b.HasData(
new
{
Id = "1",
ConcurrencyStamp = "e871b497-2d5f-4709-bdb6-ff52a320f53e",
Name = "Administrator"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderKey")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("RoleId")
.HasColumnType("nvarchar(450)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("Name")
.HasColumnType("nvarchar(450)");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("MusicStoreUI.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.HasColumnType("bit");
b.Property<bool>("LockoutEnabled")
.HasColumnType("bit");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<string>("NormalizedEmail")
.HasColumnType("nvarchar(255)")
.HasMaxLength(255);
b.Property<string>("NormalizedUserName")
.HasColumnType("nvarchar(255)")
.HasMaxLength(255);
b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.HasColumnType("nvarchar(max)");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit");
b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("bit");
b.Property<string>("UserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");
b.ToTable("AspNetUsers");
b.HasData(
new
{
Id = "b4c4883a-7f1f-45d7-9029-ea5d8cf983d7",
AccessFailedCount = 0,
ConcurrencyStamp = "59494ece-76bb-4ce2-a589-fdfc66546a24",
EmailConfirmed = false,
LockoutEnabled = false,
PhoneNumberConfirmed = false,
SecurityStamp = "4247420a-26cc-41de-9664-2bae024f41bf",
TwoFactorEnabled = false,
UserName = "Administrator@test.com"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("MusicStoreUI.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("MusicStoreUI.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MusicStoreUI.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("MusicStoreUI.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

Просмотреть файл

@ -1,229 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace MusicStoreUI.Migrations
{
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<string>(nullable: false),
Name = table.Column<string>(maxLength: 256, nullable: true),
NormalizedName = table.Column<string>(maxLength: 255, nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetUsers",
columns: table => new
{
Id = table.Column<string>(nullable: false),
UserName = table.Column<string>(maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(maxLength: 255, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 255, nullable: true),
EmailConfirmed = table.Column<bool>(nullable: false),
PasswordHash = table.Column<string>(nullable: true),
SecurityStamp = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
PhoneNumber = table.Column<string>(nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
LockoutEnabled = table.Column<bool>(nullable: false),
AccessFailedCount = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
RoleId = table.Column<string>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserClaims",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
UserId = table.Column<string>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserLogins",
columns: table => new
{
LoginProvider = table.Column<string>(nullable: false),
ProviderKey = table.Column<string>(nullable: false),
ProviderDisplayName = table.Column<string>(nullable: true),
UserId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
table.ForeignKey(
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
UserId = table.Column<string>(nullable: false),
RoleId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserTokens",
columns: table => new
{
UserId = table.Column<string>(nullable: false),
LoginProvider = table.Column<string>(nullable: false),
Name = table.Column<string>(nullable: false),
Value = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
table.ForeignKey(
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "AspNetRoles",
columns: new[] { "Id", "ConcurrencyStamp", "Name", "NormalizedName" },
values: new object[] { "1", "e871b497-2d5f-4709-bdb6-ff52a320f53e", "Administrator", null });
migrationBuilder.InsertData(
table: "AspNetUsers",
columns: new[] { "Id", "AccessFailedCount", "ConcurrencyStamp", "Email", "EmailConfirmed", "LockoutEnabled", "LockoutEnd", "NormalizedEmail", "NormalizedUserName", "PasswordHash", "PhoneNumber", "PhoneNumberConfirmed", "SecurityStamp", "TwoFactorEnabled", "UserName" },
values: new object[] { "b4c4883a-7f1f-45d7-9029-ea5d8cf983d7", 0, "59494ece-76bb-4ce2-a589-fdfc66546a24", null, false, false, null, null, null, null, null, false, "4247420a-26cc-41de-9664-2bae024f41bf", false, "Administrator@test.com" });
migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId",
table: "AspNetRoleClaims",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "RoleNameIndex",
table: "AspNetRoles",
column: "NormalizedName",
unique: true,
filter: "[NormalizedName] IS NOT NULL");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserClaims_UserId",
table: "AspNetUserClaims",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserLogins_UserId",
table: "AspNetUserLogins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserRoles_RoleId",
table: "AspNetUserRoles",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "AspNetUsers",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "AspNetUsers",
column: "NormalizedUserName",
unique: true,
filter: "[NormalizedUserName] IS NOT NULL");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AspNetRoleClaims");
migrationBuilder.DropTable(
name: "AspNetUserClaims");
migrationBuilder.DropTable(
name: "AspNetUserLogins");
migrationBuilder.DropTable(
name: "AspNetUserRoles");
migrationBuilder.DropTable(
name: "AspNetUserTokens");
migrationBuilder.DropTable(
name: "AspNetRoles");
migrationBuilder.DropTable(
name: "AspNetUsers");
}
}
}

Просмотреть файл

@ -1,293 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MusicStoreUI.Models;
namespace MusicStoreUI.Migrations
{
[DbContext(typeof(AccountsContext))]
partial class AccountsContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0-preview9.19423.6")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.HasColumnType("nvarchar(255)")
.HasMaxLength(255);
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasName("RoleNameIndex")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles");
b.HasData(
new
{
Id = "1",
ConcurrencyStamp = "e871b497-2d5f-4709-bdb6-ff52a320f53e",
Name = "Administrator"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderKey")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("RoleId")
.HasColumnType("nvarchar(450)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("Name")
.HasColumnType("nvarchar(450)");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("MusicStoreUI.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.HasColumnType("bit");
b.Property<bool>("LockoutEnabled")
.HasColumnType("bit");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<string>("NormalizedEmail")
.HasColumnType("nvarchar(255)")
.HasMaxLength(255);
b.Property<string>("NormalizedUserName")
.HasColumnType("nvarchar(255)")
.HasMaxLength(255);
b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.HasColumnType("nvarchar(max)");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit");
b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("bit");
b.Property<string>("UserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");
b.ToTable("AspNetUsers");
b.HasData(
new
{
Id = "b4c4883a-7f1f-45d7-9029-ea5d8cf983d7",
AccessFailedCount = 0,
ConcurrencyStamp = "59494ece-76bb-4ce2-a589-fdfc66546a24",
EmailConfirmed = false,
LockoutEnabled = false,
PhoneNumberConfirmed = false,
SecurityStamp = "4247420a-26cc-41de-9664-2bae024f41bf",
TwoFactorEnabled = false,
UserName = "Administrator@test.com"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("MusicStoreUI.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("MusicStoreUI.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MusicStoreUI.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("MusicStoreUI.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

Просмотреть файл

@ -21,12 +21,10 @@ namespace MusicStoreUI.Models
if (ShouldDropCreateDatabase())
{
using (var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var db = serviceScope.ServiceProvider.GetService<AccountsContext>();
db.Database.EnsureCreated();
CreateAdminUser(serviceProvider, configuration).Wait();
}
using var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope();
var db = serviceScope.ServiceProvider.GetService<AccountsContext>();
db.Database.EnsureCreated();
CreateAdminUser(serviceProvider, configuration).GetAwaiter().GetResult();
}
}
@ -41,10 +39,12 @@ namespace MusicStoreUI.Models
await roleManager.CreateAsync(new IdentityRole(adminRole));
}
var user = await userManager.FindByNameAsync(configuration[defaultAdminUserName]);
var defaultadminUser = configuration[defaultAdminUserName];
Console.WriteLine("User to find: {0}", defaultadminUser);
var user = await userManager.FindByNameAsync(defaultadminUser ?? defaultAdminUserName);
if (user == null)
{
user = new ApplicationUser { UserName = configuration[defaultAdminUserName] };
user = new ApplicationUser { UserName = defaultadminUser };
await userManager.CreateAsync(user, configuration[defaultAdminPassword]);
await userManager.AddToRoleAsync(user, adminRole);
await userManager.AddClaimAsync(user, new Claim("ManageStore", "Allowed"));

Просмотреть файл

@ -19,56 +19,45 @@
</None>
</ItemGroup>
<ItemGroup>
<!-- GitInfo provides $(Git*) properties used below -->
<PackageReference Include="Azure.Identity" Version="1.1.1" />
<PackageReference Include="GitInfo" Version="2.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
<!--<PackageReference Include="Microsoft.Extensions.Caching.Redis" Version="$(AspNetCoreVersion)" />-->
<!-- <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" /> -->
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureAppConfiguration" Version="3.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.3" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
<PackageReference Include="Steeltoe.Common.Hosting" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.CircuitBreaker.HystrixCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Connector.EFCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Discovery.ClientCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Extensions.Configuration.ConfigServerCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Management.CloudFoundryCore" Version="3.0.0-2430" />
<!--<PackageReference Include="Steeltoe.Management.ExporterCore" Version="3.0.0-m1" />-->
<PackageReference Include="Steeltoe.Management.TracingCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Security.DataProtection.RedisCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.CircuitBreaker.HystrixCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Connector.ConnectorCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Connector.EFCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Discovery.Eureka" Version="3.0.1" />
<PackageReference Include="Steeltoe.Extensions.Configuration.ConfigServerCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Management.CloudFoundryCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Management.TracingCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Security.DataProtection.RedisCore" Version="3.0.1" />
<!-- GitInfo provides $(Git*) properties used below -->
<PackageReference Include="GitInfo" Version="2.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<!--<ItemGroup Condition="'$(CONFIGURATION)' == 'Release'">
<PackageReference Include="RabbitMQ.Client" Version="$(RabbitMQVersion)" />
<PackageReference Include="Steeltoe.CircuitBreaker.Hystrix.MetricsStreamCore" Version="3.0.0-manual" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\CircuitBreaker\src\Hystrix.MetricsStreamCore\Steeltoe.CircuitBreaker.Hystrix.MetricsStreamCore.csproj" />
<PackageReference Include="Steeltoe.CircuitBreaker.Hystrix.MetricsStreamCore" Version="3.0.1" />
</ItemGroup>-->
<ItemGroup> <!--Condition="'$(CONFIGURATION)' == 'Debug'"-->
<PackageReference Include="Steeltoe.CircuitBreaker.Hystrix.MetricsEventsCore" Version="3.0.0-2430" />
<!--<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\CircuitBreaker\src\Hystrix.MetricsEventsCore\Steeltoe.CircuitBreaker.Hystrix.MetricsEventsCore.csproj" />-->
<PackageReference Include="Steeltoe.CircuitBreaker.Hystrix.MetricsEventsCore" Version="3.0.1" />
</ItemGroup>
<!--<ItemGroup>
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\CircuitBreaker\src\HystrixCore\Steeltoe.CircuitBreaker.HystrixCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Configuration\src\ConfigServerCore\Steeltoe.Extensions.Configuration.ConfigServerCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Connectors\src\Connector.EFCore\Steeltoe.CloudFoundry.Connector.EFCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Discovery\src\ClientCore\Steeltoe.Discovery.ClientCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Management\src\CloudFoundryCore\Steeltoe.Management.CloudFoundryCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Security\src\DataProtection.RedisCore\Steeltoe.Security.DataProtection.RedisCore.csproj" />
</ItemGroup>-->
<Target Name="_GitProperties" AfterTargets="CoreCompile">
<WriteLinesToFile File="git.properties" Lines="git.remote.origin.url=$(GitRoot)" Overwrite="true" />
<WriteLinesToFile File="git.properties" Lines="git.build.version=$(GitBaseVersion)" Overwrite="false" />

Просмотреть файл

@ -5,9 +5,9 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MusicStoreUI.Models;
using Steeltoe.Common.Hosting;
using Steeltoe.Discovery.Client;
using Steeltoe.Extensions.Configuration.ConfigServer;
using Steeltoe.Extensions.Logging;
using Steeltoe.Management.Endpoint;
using System;
namespace MusicStoreUI
@ -18,62 +18,53 @@ namespace MusicStoreUI
public static void Main(string[] args)
{
IHost host = CreateHostBuilder(args).Build();
var host = CreateHostBuilder(args).Build();
SeedDatabase(host);
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webbuilder =>
{
webbuilder
.ConfigureKestrel(options =>
{
options.AllowSynchronousIO = true;
})
.UseStartup<Startup>()
.UseCloudHosting(5555);
})
.ConfigureAppConfiguration((builderContext, configBuilder) =>
{
if (builderContext.HostingEnvironment.EnvironmentName.Contains("Azure"))
{
var settings = configBuilder.Build();
configBuilder.AddAzureAppConfiguration(options => options.Connect(new Uri(settings["AppConfig:Endpoint"]), new ManagedIdentityCredential()));
}
else
{
configBuilder.AddConfigServer(builderContext.HostingEnvironment.EnvironmentName);
}
configBuilder.AddEnvironmentVariables();
configuration = configBuilder.Build();
})
.ConfigureLogging((context, builder) =>
{
builder.ClearProviders();
builder.AddDynamicConsole();
});
.ConfigureWebHostDefaults(webbuilder => webbuilder.UseStartup<Startup>())
.ConfigureAppConfiguration(AddRemoteConfiguration)
.AddAllActuators()
.AddDiscoveryClient();
private static void SeedDatabase(IHost host)
{
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
SampleData.InitializeAccountsDatabase(services, configuration);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
using var scope = host.Services.CreateScope();
var services = scope.ServiceProvider;
SampleData.InitializeAccountsDatabase(services, configuration);
SampleData.BuildFallbackData();
}
private static Action<HostBuilderContext, IConfigurationBuilder> AddRemoteConfiguration =>
(builderContext, configBuilder) =>
{
if (builderContext.HostingEnvironment.EnvironmentName.Contains("Azure"))
{
var settings = configBuilder.Build();
configBuilder.AddAzureAppConfiguration(options => options.Connect(new Uri(settings["AppConfig:Endpoint"]), new ManagedIdentityCredential()));
}
else
{
configBuilder.AddConfigServer(builderContext.HostingEnvironment.EnvironmentName, GetLoggerFactory());
}
configBuilder.AddEnvironmentVariables();
configuration = configBuilder.Build();
};
private static ILoggerFactory GetLoggerFactory()
{
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder => builder.SetMinimumLevel(LogLevel.Trace));
serviceCollection.AddLogging(builder => builder.AddConsole((opts) =>
{
opts.DisableColors = true;
}));
serviceCollection.AddLogging(builder => builder.AddDebug());
return serviceCollection.BuildServiceProvider().GetService<ILoggerFactory>();
}
}
}

Просмотреть файл

@ -9,13 +9,13 @@ namespace MusicStoreUI.Services
public class MusicStoreService : BaseDiscoveryService, IMusicStore
{
private const string TOP_SELLING_URL = "http://musicservice/api/Store/TopSelling";
private const string GENRES_URL = "http://musicservice/api/Store/Genres";
private const string GENRE_URL = "http://musicservice/api/Store/Genre";
private const string ALBUMS_URL = "http://musicservice/api/Store/Albums";
private const string ALBUM_URL = "http://musicservice/api/Store/Album";
private const string ARTISTS_URL = "http://musicservice/api/Store/Artists";
private const string ARTIST_URL = "http://musicservice/api/Store/Artist";
private const string TOP_SELLING_URL = "http://musicstoreservice/api/Store/TopSelling";
private const string GENRES_URL = "http://musicstoreservice/api/Store/Genres";
private const string GENRE_URL = "http://musicstoreservice/api/Store/Genre";
private const string ALBUMS_URL = "http://musicstoreservice/api/Store/Albums";
private const string ALBUM_URL = "http://musicstoreservice/api/Store/Album";
private const string ARTISTS_URL = "http://musicstoreservice/api/Store/Artists";
private const string ARTIST_URL = "http://musicstoreservice/api/Store/Artist";
public MusicStoreService(HttpClient client, ILoggerFactory logFactory)
: base(client, logFactory.CreateLogger<MusicStoreService>())

Просмотреть файл

@ -1,32 +1,20 @@
using MusicStoreUI.Services;
using MusicStoreUI.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Steeltoe.Connector.SqlServer.EFCore;
using Steeltoe.Discovery.Client;
#if USE_REDIS_CACHE
using Microsoft.AspNetCore.DataProtection;
using Steeltoe.CloudFoundry.Connector.Redis;
using Steeltoe.Security.DataProtection;
#endif
using Steeltoe.Management.CloudFoundry;
using MusicStoreUI.Models;
using MusicStoreUI.Services;
using Steeltoe.CircuitBreaker.Hystrix;
using Command = MusicStoreUI.Services.HystrixCommands;
using Microsoft.EntityFrameworkCore;
using Steeltoe.Common.Http.Discovery;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Steeltoe.Management.Endpoint.Env;
using Steeltoe.Management.Endpoint.Refresh;
// using Steeltoe.Management.Exporter.Tracing;
using Steeltoe.Connector.MySql.EFCore;
using Steeltoe.Connector.Redis;
using Steeltoe.Management.Tracing;
using Steeltoe.Common;
using Steeltoe.Extensions.Configuration.CloudFoundry;
// using Steeltoe.Management.Exporter.Tracing.Zipkin;
using Steeltoe.Security.DataProtection;
using System;
using Command = MusicStoreUI.Services.HystrixCommands;
namespace MusicStoreUI
{
@ -42,62 +30,42 @@ namespace MusicStoreUI
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// this should be done automatically by Steeltoe somewhere else! Zipkin throws without it
if (Platform.IsCloudFoundry)
// Add framework services.
if (bool.Parse(Environment.GetEnvironmentVariable("USE_REDIS_CACHE")))
{
services.RegisterCloudFoundryApplicationInstanceInfo();
services.AddRedisConnectionMultiplexer(Configuration);
services.AddDataProtection()
.PersistKeysToRedis()
.SetApplicationName("MusicStoreUI");
services.AddDistributedRedisCache(Configuration);
}
else
{
services.GetApplicationInstanceInfo();
Console.WriteLine("NOT Using Redis");
services.AddDistributedMemoryCache();
}
// Add framework services.
#if USE_REDIS_CACHE
services.AddRedisConnectionMultiplexer(Configuration);
services.AddDataProtection()
.PersistKeysToRedis()
.SetApplicationName("MusicStoreUI");
services.AddDistributedRedisCache(Configuration);
#else
services.AddDistributedMemoryCache();
#endif
// Add managment endpoint services
services.AddCloudFoundryActuators(Configuration);
services.AddEnvActuator(Configuration);
services.AddRefreshActuator(Configuration);
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
// var cstring = new ConnectionStringManager(Configuration).Get<SqlServerConnectionInfo>().ConnectionString;
// Console.WriteLine("Using SQL Connection: {0}", cstring);
// services.AddDbContext<AccountsContext>(options => options.UseSqlServer(cstring));
services.AddDbContext<AccountsContext>(options => options.UseSqlServer(Configuration));
services.AddDbContext<AccountsContext>(options => options.UseMySql(Configuration));
services.ConfigureApplicationCookie(options => options.AccessDeniedPath = "/Home/AccessDenied");
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<AccountsContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");
if (!Configuration.GetValue<bool>("DisableServiceDiscovery"))
{
services.AddDiscoveryClient(Configuration);
}
else
{
services.AddConfigurationDiscoveryClient(Configuration);
services.TryAddTransient<DiscoveryHttpMessageHandler>();
}
services.AddDistributedTracing(Configuration, builder => builder.UseZipkinWithTraceOptions(services));
services.AddHttpClient<IMusicStore, MusicStoreService>()
.AddHttpMessageHandler<DiscoveryHttpMessageHandler>();
services.AddHttpClient<IShoppingCart, ShoppingCartService>()
.AddHttpMessageHandler<DiscoveryHttpMessageHandler>();
services.AddHttpClient<IOrderProcessing, OrderProcessingService>()
.AddHttpMessageHandler<DiscoveryHttpMessageHandler>();
services
.AddHttpClient<IMusicStore, MusicStoreService>()
.AddServiceDiscovery();
services
.AddHttpClient<IShoppingCart, ShoppingCartService>()
.AddServiceDiscovery();
services
.AddHttpClient<IOrderProcessing, OrderProcessingService>()
.AddServiceDiscovery();
services.AddHystrixCommand<Command.GetTopAlbums>("MusicStore", Configuration);
@ -114,7 +82,6 @@ namespace MusicStoreUI
// Use call below if you want sticky Sessions on Cloud Foundry
// services.AddSession((options) => options.CookieName = "JSESSIONID");
services.AddSession();
// Configure Auth
@ -139,11 +106,6 @@ namespace MusicStoreUI
// Add Hystrix Metrics context to pipeline
app.UseHystrixRequestContext();
// Add management endpoints into pipeline
app.UseCloudFoundryActuators();
app.UseEnvActuator();
app.UseRefreshActuator();
app.UseSession();
if (env.EnvironmentName == "Development")
@ -175,11 +137,6 @@ namespace MusicStoreUI
pattern: "{controller=Home}/{action=Index}/{id?}");
});
if (!Configuration.GetValue<bool>("DisableServiceDiscovery"))
{
app.UseDiscoveryClient();
}
// Startup Hystrix metrics stream
app.UseHystrixMetricsStream();
}

Просмотреть файл

@ -4,18 +4,7 @@
"IncludeScopes": true,
"LogLevel": {
"Default": "Information",
"Steeltoe": "Trace"
}
},
"Spring": {
"Application": {
"Name": "musicstore"
},
"Cloud": {
"Config": {
"uri": "http://localhost:8888",
"ValidateCertificates": false
}
"Steeltoe": "Information"
}
},
"hystrix": {
@ -25,17 +14,9 @@
"requestVolumeThreshold": 3
}
}
},
"stream": {
"validate_certificates": false
}
},
"Management": {
"Endpoints": {
"CloudFoundry": {
"ValidateCertificates": false
}
},
"tracing":{
"alwaysSample": true,
"useShortTraceIds": true,
@ -48,11 +29,12 @@
}
}
},
"SqlServer": {
"Credentials": {
"Database": "MusicStore"
"Spring": {
"Cloud": {
"Config": {
"Uri": "http://configserver:8888",
"FailFast": true
}
}
},
"DefaultAdminUsername": "Administrator@test.com",
"DefaultAdminPassword": "YouShouldChangeThisPassword1!"
}
}

Просмотреть файл

@ -1,6 +1,6 @@
---
applications:
- name: musicui
- name: musicstoreui
buildpacks:
- dotnet_core_buildpack
memory: 512M

Просмотреть файл

@ -1,6 +1,6 @@
---
applications:
- name: musicui
- name: musicstoreui
memory: 512M
stack: windows
command: .\MusicStoreUI

Просмотреть файл

@ -1,6 +1,6 @@
---
applications:
- name: musicui
- name: musicstoreui
memory: 512M
stack: windows
command: .\MusicStoreUI

Просмотреть файл

@ -1,6 +1,6 @@
---
applications:
- name: musicui
- name: musicstoreui
buildpacks:
- dotnet_core_buildpack
memory: 512M

Просмотреть файл

@ -1,6 +1,6 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 7000
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src

Просмотреть файл

@ -1,126 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using OrderService.Models;
namespace OrderService.Migrations
{
[DbContext(typeof(OrdersContext))]
[Migration("20190911190302_InitialCreate")]
partial class InitialCreate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0-preview9.19423.6")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("OrderService.Models.Order", b =>
{
b.Property<int>("OrderId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(70)")
.HasMaxLength(70);
b.Property<string>("City")
.IsRequired()
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("Country")
.IsRequired()
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(160)")
.HasMaxLength(160);
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("nvarchar(160)")
.HasMaxLength(160);
b.Property<DateTime>("OrderDate")
.HasColumnType("datetime2");
b.Property<string>("Phone")
.IsRequired()
.HasColumnType("nvarchar(24)")
.HasMaxLength(24);
b.Property<string>("PostalCode")
.IsRequired()
.HasColumnType("nvarchar(10)")
.HasMaxLength(10);
b.Property<string>("State")
.IsRequired()
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<decimal>("Total")
.HasColumnType("decimal(18,2)");
b.Property<string>("Username")
.HasColumnType("nvarchar(max)");
b.HasKey("OrderId");
b.ToTable("Orders");
});
modelBuilder.Entity("OrderService.Models.OrderDetail", b =>
{
b.Property<int>("OrderDetailId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("ItemKey")
.HasColumnType("int");
b.Property<int>("OrderId")
.HasColumnType("int");
b.Property<int>("Quantity")
.HasColumnType("int");
b.Property<decimal>("UnitPrice")
.HasColumnType("decimal(18,2)");
b.HasKey("OrderDetailId");
b.HasIndex("OrderId");
b.ToTable("OrderDetails");
});
modelBuilder.Entity("OrderService.Models.OrderDetail", b =>
{
b.HasOne("OrderService.Models.Order", "Order")
.WithMany("OrderDetails")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

Просмотреть файл

@ -1,71 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace OrderService.Migrations
{
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
{
OrderId = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
OrderDate = table.Column<DateTime>(nullable: false),
Username = table.Column<string>(nullable: true),
FirstName = table.Column<string>(maxLength: 160, nullable: false),
LastName = table.Column<string>(maxLength: 160, nullable: false),
Address = table.Column<string>(maxLength: 70, nullable: false),
City = table.Column<string>(maxLength: 40, nullable: false),
State = table.Column<string>(maxLength: 40, nullable: false),
PostalCode = table.Column<string>(maxLength: 10, nullable: false),
Country = table.Column<string>(maxLength: 40, nullable: false),
Phone = table.Column<string>(maxLength: 24, nullable: false),
Email = table.Column<string>(nullable: false),
Total = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.OrderId);
});
migrationBuilder.CreateTable(
name: "OrderDetails",
columns: table => new
{
OrderDetailId = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
OrderId = table.Column<int>(nullable: false),
ItemKey = table.Column<int>(nullable: false),
Quantity = table.Column<int>(nullable: false),
UnitPrice = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_OrderDetails", x => x.OrderDetailId);
table.ForeignKey(
name: "FK_OrderDetails_Orders_OrderId",
column: x => x.OrderId,
principalTable: "Orders",
principalColumn: "OrderId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_OrderDetails_OrderId",
table: "OrderDetails",
column: "OrderId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "OrderDetails");
migrationBuilder.DropTable(
name: "Orders");
}
}
}

Просмотреть файл

@ -1,124 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using OrderService.Models;
namespace OrderService.Migrations
{
[DbContext(typeof(OrdersContext))]
partial class OrdersContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0-preview9.19423.6")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("OrderService.Models.Order", b =>
{
b.Property<int>("OrderId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(70)")
.HasMaxLength(70);
b.Property<string>("City")
.IsRequired()
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("Country")
.IsRequired()
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(160)")
.HasMaxLength(160);
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("nvarchar(160)")
.HasMaxLength(160);
b.Property<DateTime>("OrderDate")
.HasColumnType("datetime2");
b.Property<string>("Phone")
.IsRequired()
.HasColumnType("nvarchar(24)")
.HasMaxLength(24);
b.Property<string>("PostalCode")
.IsRequired()
.HasColumnType("nvarchar(10)")
.HasMaxLength(10);
b.Property<string>("State")
.IsRequired()
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<decimal>("Total")
.HasColumnType("decimal(18,2)");
b.Property<string>("Username")
.HasColumnType("nvarchar(max)");
b.HasKey("OrderId");
b.ToTable("Orders");
});
modelBuilder.Entity("OrderService.Models.OrderDetail", b =>
{
b.Property<int>("OrderDetailId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("ItemKey")
.HasColumnType("int");
b.Property<int>("OrderId")
.HasColumnType("int");
b.Property<int>("Quantity")
.HasColumnType("int");
b.Property<decimal>("UnitPrice")
.HasColumnType("decimal(18,2)");
b.HasKey("OrderDetailId");
b.HasIndex("OrderId");
b.ToTable("OrderDetails");
});
modelBuilder.Entity("OrderService.Models.OrderDetail", b =>
{
b.HasOne("OrderService.Models.Order", "Order")
.WithMany("OrderDetails")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

Просмотреть файл

@ -15,37 +15,27 @@
</None>
</ItemGroup>
<ItemGroup>
<!-- GitInfo provides $(Git*) properties used below -->
<PackageReference Include="Azure.Identity" Version="1.1.1" />
<PackageReference Include="GitInfo" Version="2.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
<!-- <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" /> -->
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureAppConfiguration" Version="3.0.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
<!--
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="$(PomeloMySqlEFCoreVersion)" />-->
<PackageReference Include="Steeltoe.Extensions.Configuration.ConfigServerCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Discovery.ClientCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Connector.EFCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Management.CloudFoundryCore" Version="3.0.0-2430" />
<!--<PackageReference Include="Steeltoe.Management.ExporterCore" Version="3.0.0-1656" />-->
<PackageReference Include="Steeltoe.Management.TracingCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Common.Hosting" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Extensions.Configuration.ConfigServerCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Connector.EFCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Discovery.Eureka" Version="3.0.1" />
<PackageReference Include="Steeltoe.Management.CloudFoundryCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Management.TracingCore" Version="3.0.1" />
<!-- GitInfo provides $(Git*) properties used below -->
<PackageReference Include="GitInfo" Version="2.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<!--<ItemGroup>
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Configuration\src\ConfigServerCore\Steeltoe.Extensions.Configuration.ConfigServerCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Connectors\src\Connector.EFCore\Steeltoe.CloudFoundry.Connector.EFCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Discovery\src\ClientCore\Steeltoe.Discovery.ClientCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Management\src\CloudFoundryCore\Steeltoe.Management.CloudFoundryCore.csproj" />
</ItemGroup>-->
<Target Name="_GitProperties" AfterTargets="CoreCompile">
<WriteLinesToFile File="git.properties" Lines="git.remote.origin.url=$(GitRoot)" Overwrite="true" />

Просмотреть файл

@ -6,9 +6,9 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OrderService.Models;
using Steeltoe.Common.Hosting;
using Steeltoe.Discovery.Client;
using Steeltoe.Extensions.Configuration.ConfigServer;
using Steeltoe.Extensions.Logging;
using Steeltoe.Management.Endpoint;
using System;
namespace OrderService
@ -26,49 +26,43 @@ namespace OrderService
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webbuilder =>
{
webbuilder
.ConfigureKestrel(options =>
{
options.AllowSynchronousIO = true;
})
.UseStartup<Startup>()
.UseCloudHosting(7000);
})
.ConfigureAppConfiguration((builderContext, configBuilder) =>
{
if (builderContext.HostingEnvironment.EnvironmentName.Contains("Azure"))
{
var settings = configBuilder.Build();
configBuilder.AddAzureAppConfiguration(options => options.Connect(new Uri(settings["AppConfig:Endpoint"]), new ManagedIdentityCredential()));
}
else
{
configBuilder.AddConfigServer(builderContext.HostingEnvironment.EnvironmentName);
}
configBuilder.AddEnvironmentVariables();
})
.ConfigureLogging((context, builder) =>
{
builder.ClearProviders();
builder.AddDynamicConsole();
});
.ConfigureWebHostDefaults(webbuilder => webbuilder.UseStartup<Startup>())
.ConfigureAppConfiguration(AddRemoteConfiguration)
.AddAllActuators()
.AddDiscoveryClient();
private static void SeedDatabase(IHost host)
{
using var scope = host.Services.CreateScope();
var services = scope.ServiceProvider;
SampleData.InitializeOrderDatabase(services);
}
try
private static Action<HostBuilderContext, IConfigurationBuilder> AddRemoteConfiguration =>
(builderContext, configBuilder) =>
{
SampleData.InitializeOrderDatabase(services);
}
catch (Exception ex)
if (builderContext.HostingEnvironment.EnvironmentName.Contains("Azure"))
{
var settings = configBuilder.Build();
configBuilder.AddAzureAppConfiguration(options => options.Connect(new Uri(settings["AppConfig:Endpoint"]), new ManagedIdentityCredential()));
}
else
{
configBuilder.AddConfigServer(builderContext.HostingEnvironment.EnvironmentName, GetLoggerFactory());
}
configBuilder.AddEnvironmentVariables();
};
private static ILoggerFactory GetLoggerFactory()
{
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder => builder.SetMinimumLevel(LogLevel.Trace));
serviceCollection.AddLogging(builder => builder.AddConsole((opts) =>
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
opts.DisableColors = true;
}));
serviceCollection.AddLogging(builder => builder.AddDebug());
return serviceCollection.BuildServiceProvider().GetService<ILoggerFactory>();
}
}
}

Просмотреть файл

@ -1,15 +1,8 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OrderService.Models;
using Steeltoe.Common;
using Steeltoe.Connector.SqlServer.EFCore;
using Steeltoe.Discovery.Client;
using Steeltoe.Extensions.Configuration.CloudFoundry;
using Steeltoe.Management.CloudFoundry;
using Steeltoe.Management.Endpoint.Env;
using Steeltoe.Management.Endpoint.Refresh;
using Steeltoe.Connector.MySql.EFCore;
using Steeltoe.Management.Tracing;
namespace OrderService
@ -26,60 +19,26 @@ namespace OrderService
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// this should be done automatically by Steeltoe somewhere else! Zipkin throws without it
if (Platform.IsCloudFoundry)
{
services.RegisterCloudFoundryApplicationInstanceInfo();
}
else
{
services.GetApplicationInstanceInfo();
}
// Add managment endpoint services
services.AddCloudFoundryActuators(Configuration);
services.AddEnvActuator(Configuration);
services.AddRefreshActuator(Configuration);
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
// Add framework services.
services.AddControllers();
if (!Configuration.GetValue<bool>("DisableServiceDiscovery"))
{
services.AddDiscoveryClient(Configuration);
}
services.AddDistributedTracing(Configuration, builder => builder.UseZipkinWithTraceOptions(services));
// var cstring = new ConnectionStringManager(Configuration).Get<SqlServerConnectionInfo>().ConnectionString;
// Console.WriteLine("Using SQL Connection: {0}", cstring);
// services.AddDbContext<OrdersContext>(options => options.UseSqlServer(cstring));
services.AddDbContext<OrdersContext>(options => options.UseSqlServer(Configuration));
services.AddDbContext<OrdersContext>(options => options.UseMySql(Configuration));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
// Add management endpoints into pipeline
app.UseCloudFoundryActuators();
app.UseEnvActuator();
app.UseRefreshActuator();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
if (!Configuration.GetValue<bool>("DisableServiceDiscovery"))
{
app.UseDiscoveryClient();
}
}
}
}

Просмотреть файл

@ -6,24 +6,7 @@
"Default": "Warning"
}
},
"Spring": {
"Application": {
"Name": "orderprocessing"
},
"Cloud": {
"Config": {
"uri": "http://localhost:8888",
"ValidateCertificates": false
}
}
},
"Management": {
"Endpoints": {
"Path": "/cloudfoundryapplication",
"CloudFoundry": {
"ValidateCertificates": false
}
},
"tracing":{
"alwaysSample": true,
"useShortTraceIds": true,
@ -36,9 +19,12 @@
}
}
},
"SqlServer": {
"Credentials": {
"Database": "OrderProcessing"
"Spring": {
"Cloud": {
"Config": {
"Uri": "http://configserver:8888",
"FailFast": true
}
}
}
}

Просмотреть файл

@ -1,6 +1,6 @@
---
applications:
- name: orderprocessing
- name: orderservice
memory: 256M
stack: windows
command: .\OrderService

Просмотреть файл

@ -1,6 +1,6 @@
---
applications:
- name: orderprocessing
- name: orderservice
buildpacks:
- dotnet_core_buildpack
memory: 256M

Просмотреть файл

@ -1,6 +1,6 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 6000
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src

Просмотреть файл

@ -1,69 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using ShoppingCartService.Models;
namespace ShoppingCartService.Migrations
{
[DbContext(typeof(ShoppingCartContext))]
[Migration("20190911190734_InitialCreate")]
partial class InitialCreate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0-preview9.19423.6")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("ShoppingCartService.Models.CartItem", b =>
{
b.Property<int>("CartItemId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreated")
.HasColumnType("datetime2");
b.Property<int>("ItemKey")
.HasColumnType("int");
b.Property<string>("ShoppingCartCartId")
.HasColumnType("nvarchar(450)");
b.HasKey("CartItemId");
b.HasIndex("ShoppingCartCartId");
b.ToTable("CartItems");
});
modelBuilder.Entity("ShoppingCartService.Models.ShoppingCart", b =>
{
b.Property<string>("CartId")
.HasColumnType("nvarchar(450)");
b.HasKey("CartId");
b.ToTable("Carts");
});
modelBuilder.Entity("ShoppingCartService.Models.CartItem", b =>
{
b.HasOne("ShoppingCartService.Models.ShoppingCart", null)
.WithMany("CartItems")
.HasForeignKey("ShoppingCartCartId");
});
#pragma warning restore 612, 618
}
}
}

Просмотреть файл

@ -1,58 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace ShoppingCartService.Migrations
{
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Carts",
columns: table => new
{
CartId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Carts", x => x.CartId);
});
migrationBuilder.CreateTable(
name: "CartItems",
columns: table => new
{
CartItemId = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ItemKey = table.Column<int>(nullable: false),
Count = table.Column<int>(nullable: false),
DateCreated = table.Column<DateTime>(nullable: false),
ShoppingCartCartId = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_CartItems", x => x.CartItemId);
table.ForeignKey(
name: "FK_CartItems_Carts_ShoppingCartCartId",
column: x => x.ShoppingCartCartId,
principalTable: "Carts",
principalColumn: "CartId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_CartItems_ShoppingCartCartId",
table: "CartItems",
column: "ShoppingCartCartId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "CartItems");
migrationBuilder.DropTable(
name: "Carts");
}
}
}

Просмотреть файл

@ -1,67 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using ShoppingCartService.Models;
namespace ShoppingCartService.Migrations
{
[DbContext(typeof(ShoppingCartContext))]
partial class ShoppingCartContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0-preview9.19423.6")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("ShoppingCartService.Models.CartItem", b =>
{
b.Property<int>("CartItemId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreated")
.HasColumnType("datetime2");
b.Property<int>("ItemKey")
.HasColumnType("int");
b.Property<string>("ShoppingCartCartId")
.HasColumnType("nvarchar(450)");
b.HasKey("CartItemId");
b.HasIndex("ShoppingCartCartId");
b.ToTable("CartItems");
});
modelBuilder.Entity("ShoppingCartService.Models.ShoppingCart", b =>
{
b.Property<string>("CartId")
.HasColumnType("nvarchar(450)");
b.HasKey("CartId");
b.ToTable("Carts");
});
modelBuilder.Entity("ShoppingCartService.Models.CartItem", b =>
{
b.HasOne("ShoppingCartService.Models.ShoppingCart", null)
.WithMany("CartItems")
.HasForeignKey("ShoppingCartCartId");
});
#pragma warning restore 612, 618
}
}
}

Просмотреть файл

@ -6,9 +6,9 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ShoppingCartService.Models;
using Steeltoe.Common.Hosting;
using Steeltoe.Discovery.Client;
using Steeltoe.Extensions.Configuration.ConfigServer;
using Steeltoe.Extensions.Logging;
using Steeltoe.Management.Endpoint;
using System;
namespace ShoppingCartService
@ -24,49 +24,43 @@ namespace ShoppingCartService
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webbuilder =>
{
webbuilder
.ConfigureKestrel(options =>
{
options.AllowSynchronousIO = true;
})
.UseStartup<Startup>()
.UseCloudHosting(6000);
})
.ConfigureAppConfiguration((builderContext, configBuilder) =>
{
if (builderContext.HostingEnvironment.EnvironmentName.Contains("Azure"))
{
var settings = configBuilder.Build();
configBuilder.AddAzureAppConfiguration(options => options.Connect(new Uri(settings["AppConfig:Endpoint"]), new ManagedIdentityCredential()));
}
else
{
configBuilder.AddConfigServer(builderContext.HostingEnvironment.EnvironmentName);
}
configBuilder.AddEnvironmentVariables();
})
.ConfigureLogging((context, builder) =>
{
builder.ClearProviders();
builder.AddDynamicConsole();
});
.ConfigureWebHostDefaults(webbuilder => webbuilder.UseStartup<Startup>())
.ConfigureAppConfiguration(AddRemoteConfiguration)
.AddAllActuators()
.AddDiscoveryClient();
private static void SeedDatabase(IHost host)
{
using var scope = host.Services.CreateScope();
var services = scope.ServiceProvider;
SampleData.InitializeShoppingCartDatabase(services);
}
try
private static Action<HostBuilderContext, IConfigurationBuilder> AddRemoteConfiguration =>
(builderContext, configBuilder) =>
{
SampleData.InitializeShoppingCartDatabase(services);
}
catch (Exception ex)
if (builderContext.HostingEnvironment.EnvironmentName.Contains("Azure"))
{
var settings = configBuilder.Build();
configBuilder.AddAzureAppConfiguration(options => options.Connect(new Uri(settings["AppConfig:Endpoint"]), new ManagedIdentityCredential()));
}
else
{
configBuilder.AddConfigServer(builderContext.HostingEnvironment.EnvironmentName, GetLoggerFactory());
}
configBuilder.AddEnvironmentVariables();
};
private static ILoggerFactory GetLoggerFactory()
{
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder => builder.SetMinimumLevel(LogLevel.Trace));
serviceCollection.AddLogging(builder => builder.AddConsole((opts) =>
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
opts.DisableColors = true;
}));
serviceCollection.AddLogging(builder => builder.AddDebug());
return serviceCollection.BuildServiceProvider().GetService<ILoggerFactory>();
}
}
}

Просмотреть файл

@ -15,36 +15,27 @@
</None>
</ItemGroup>
<ItemGroup>
<!-- GitInfo provides $(Git*) properties used below -->
<PackageReference Include="Azure.Identity" Version="1.1.1" />
<PackageReference Include="GitInfo" Version="2.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
<!-- <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" /> -->
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureAppConfiguration" Version="3.0.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
<!--
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="$(PomeloMySqlEFCoreVersion)" />-->
<PackageReference Include="Steeltoe.Extensions.Configuration.ConfigServerCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Discovery.ClientCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Connector.EFCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Management.CloudFoundryCore" Version="3.0.0-2430" />
<!--<PackageReference Include="Steeltoe.Management.ExporterCore" Version="3.0.0-1656" />-->
<PackageReference Include="Steeltoe.Management.TracingCore" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Common.Hosting" Version="3.0.0-2430" />
<PackageReference Include="Steeltoe.Extensions.Configuration.ConfigServerCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Connector.EFCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Discovery.Eureka" Version="3.0.1" />
<PackageReference Include="Steeltoe.Management.CloudFoundryCore" Version="3.0.1" />
<PackageReference Include="Steeltoe.Management.TracingCore" Version="3.0.1" />
<!-- GitInfo provides $(Git*) properties used below -->
<PackageReference Include="GitInfo" Version="2.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<!--<ItemGroup>
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Configuration\src\ConfigServerCore\Steeltoe.Extensions.Configuration.ConfigServerCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Connectors\src\Connector.EFCore\Steeltoe.CloudFoundry.Connector.EFCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Discovery\src\ClientCore\Steeltoe.Discovery.ClientCore.csproj" />
<ProjectReference Include="..\..\..\..\..\SteeltoeOSS\steeltoe\src\Management\src\CloudFoundryCore\Steeltoe.Management.CloudFoundryCore.csproj" />
</ItemGroup>-->
<Target Name="_GitProperties" AfterTargets="CoreCompile">
<WriteLinesToFile File="git.properties" Lines="git.remote.origin.url=$(GitRoot)" Overwrite="true" />

Просмотреть файл

@ -1,15 +1,8 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using ShoppingCartService.Models;
using Steeltoe.Common;
using Steeltoe.Connector.SqlServer.EFCore;
using Steeltoe.Discovery.Client;
using Steeltoe.Extensions.Configuration.CloudFoundry;
using Steeltoe.Management.CloudFoundry;
using Steeltoe.Management.Endpoint.Env;
using Steeltoe.Management.Endpoint.Refresh;
using Steeltoe.Connector.MySql.EFCore;
using Steeltoe.Management.Tracing;
namespace ShoppingCartService
@ -26,39 +19,13 @@ namespace ShoppingCartService
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// this should be done automatically by Steeltoe somewhere else! Zipkin throws without it
if (Platform.IsCloudFoundry)
{
services.RegisterCloudFoundryApplicationInstanceInfo();
}
else
{
services.GetApplicationInstanceInfo();
}
// Add managment endpoint services
services.AddCloudFoundryActuators(Configuration);
services.AddEnvActuator(Configuration);
services.AddRefreshActuator(Configuration);
// Add framework services.
services.AddControllers();
if (!Configuration.GetValue<bool>("DisableServiceDiscovery"))
{
services.AddDiscoveryClient(Configuration);
}
else
{
services.AddConfigurationDiscoveryClient(Configuration);
}
services.AddDistributedTracing(Configuration, builder => builder.UseZipkinWithTraceOptions(services));
// var cstring = new ConnectionStringManager(Configuration).Get<SqlServerConnectionInfo>().ConnectionString;
// Console.WriteLine("Using SQL Connection: {0}", cstring);
// services.AddDbContext<ShoppingCartContext>(options => options.UseSqlServer(cstring));
services.AddDbContext<ShoppingCartContext>(options => options.UseSqlServer(Configuration));
services.AddDbContext<ShoppingCartContext>(options => options.UseMySql(Configuration));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@ -66,23 +33,12 @@ namespace ShoppingCartService
{
app.UseRouting();
// Add management endpoints into pipeline
app.UseCloudFoundryActuators();
app.UseEnvActuator();
app.UseRefreshActuator();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
if (!Configuration.GetValue<bool>("DisableServiceDiscovery"))
{
app.UseDiscoveryClient();
}
}
}
}

Просмотреть файл

@ -5,22 +5,7 @@
"Default": "Warning"
}
},
"Spring": {
"Application": {
"Name": "shoppingcart"
},
"Cloud": {
"Config": {
"ValidateCertificates": false
}
}
},
"Management": {
"Endpoints": {
"CloudFoundry": {
"ValidateCertificates": false
}
},
"tracing":{
"alwaysSample": true,
"useShortTraceIds": true,
@ -33,9 +18,12 @@
}
}
},
"SqlServer": {
"Credentials": {
"Database": "ShoppingCart"
"Spring": {
"Cloud": {
"Config": {
"Uri": "http://configserver:8888",
"FailFast": true
}
}
}
}

Просмотреть файл

@ -1,6 +1,6 @@
---
applications:
- name: shoppingcart
- name: shoppingcartservice
memory: 256M
stack: windows
command: .\ShoppingCartService

Просмотреть файл

@ -1,6 +1,6 @@
---
applications:
- name: shoppingcart
- name: shoppingcartservice
buildpacks:
- dotnet_core_buildpack
memory: 256M

Просмотреть файл

@ -2,15 +2,22 @@ AppSettings:
SiteTitle: Music Store
CacheDbResults: true
Logging:
IncludeScopes: false
LogLevel:
Default: Debug
Default: Information
System: Warning
Microsoft: Warning
Steeltoe: Information
eureka:
client:
serviceUrl: http://eurekaserver:8761/eureka/
validateCertificates: false
instance:
StatusPageUrlPath: /actuator/info
HealthCheckUrlPath: /actuator/health
mysql:
client:
server: mysql
username: root
password: steeltoe
sqlserver:
credentials:
server: sqlserver
@ -18,5 +25,6 @@ sqlserver:
password: SteeltoeR0cks
management:
endpoints:
cloudfoundry:
validateCertificates: false
actuator:
exposure:
include: [ "*" ]

Просмотреть файл

@ -1,13 +1,9 @@
eureka:
client:
shouldFetchRegistry: false
instance:
port: 5000
mysql:
client:
database: steeltoe
username: root
password: steeltoe
database: MusicService
sqlserver:
credentials:
database: MusicService

Просмотреть файл

@ -1,13 +1,14 @@
eureka:
client:
shouldRegisterWithEureka: false
shouldRegisterWithEureka: true
mysql:
client:
database: steeltoe2
username: root
password: steeltoe
database: MusicStore
sqlserver:
credentials:
database: MusicStore
redis:
client:
host: redis
DefaultAdminUsername: Administrator@test.com
DefaultAdminPassword: YouShouldChangeThisPassword1!

Просмотреть файл

@ -1,13 +1,9 @@
eureka:
client:
shouldFetchRegistry: false
instance:
port: 7000
mysql:
client:
database: steeltoe3
username: root
password: steeltoe
database: OrderProcessing
sqlserver:
credentials:
database: OrderProcessing

Просмотреть файл

@ -1,13 +1,9 @@
eureka:
client:
shouldFetchRegistry: false
instance:
port: 6000
mysql:
client:
database: steeltoe1
username: root
password: steeltoe
database: ShoppingCart
sqlserver:
credentials:
database: ShoppingCart

74
MusicStore/tye.yaml Normal file
Просмотреть файл

@ -0,0 +1,74 @@
# tye application configuration file
# read all about it at https://github.com/dotnet/tye
name: musicstore
services:
# setting single-port bindings to force HTTP because Spring Boot Admin doesn't trust the ASP.NET Core Certificates
- name: musicstoreservice
project: src/MusicStoreService/MusicStoreService.csproj
bindings:
- port: 5010
- name: orderservice
project: src/OrderService/OrderService.csproj
bindings:
- port: 5020
- name: shoppingcartservice
project: src/ShoppingCartService/ShoppingCartService.csproj
bindings:
- port: 5030
- name: musicstoreui
project: src/MusicStoreUI/MusicStoreUI.csproj
bindings:
- port: 5000
env:
- name: USE_REDIS_CACHE
value: true
- name: configserver
image: steeltoeoss/configserver:1.3.2
env:
- name: spring.profiles.active
value: native
volumes:
- source: ./src/config/
target: /config
bindings:
- containerPort: 8888
port: 8888
protocol: http
- name: eurekaserver
image: steeltoeoss/eurekaserver:1.4.4
bindings:
- containerPort: 8761
port: 8761
protocol: http
- name: mysql
image: mysql:5.7
bindings:
- port: 3306
protocol: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: steeltoe
- name: MYSQL_DATABASE
value: steeltoe2
- name: MYSQL_USER
value: steeltoe
- name: MYSQL_PASSWORD
value: steeltoe
- name: springbootadmin
image: hananiel/spring-boot-admin-eureka-sample
bindings:
- containerPort: 8080
port: 8889
protocol: http
env:
- name: EUREKA_SERVICE_URL
value: http://eurekaserver:8761
- name: redis
image: redis
bindings:
- port: 6379