Browse Source

Resolved #960: Seed initial data for microservice demo solution.

pull/988/head
Halil ibrahim Kalkan 8 years ago
parent
commit
b395b94729
  1. 53
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/Index.cshtml
  2. 224
      samples/MicroserviceDemo/applications/AuthServer.Host/AuthServerDataSeeder.cs
  3. 10
      samples/MicroserviceDemo/applications/AuthServer.Host/AuthServerHostModule.cs
  4. 1142
      samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190117081756_Initial.Designer.cs
  5. 1150
      samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190208210234_Added_ClientId_And_CorrelationId_To_AuditLogs.Designer.cs
  6. 72
      samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190208210234_Added_ClientId_And_CorrelationId_To_AuditLogs.cs
  7. 1154
      samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190209193341_Added_ApplicationName_To_AuditLogs.Designer.cs
  8. 23
      samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190209193341_Added_ApplicationName_To_AuditLogs.cs
  9. 347
      samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190404130536_Make_IDS4_Entities_Audited.cs
  10. 4
      samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190408114124_Initial.Designer.cs
  11. 42
      samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190408114124_Initial.cs
  12. 216
      samples/MicroserviceDemo/microservices/BloggingService.Host/BlogServiceDataSeeder.cs
  13. 26
      samples/MicroserviceDemo/microservices/BloggingService.Host/BloggingServiceHostModule.cs
  14. BIN
      samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/6b32831845a8807aa8b839ed0f28182c.jpg
  15. BIN
      samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/90974f3f1edb4ab0a10cf9759fd5f9ae.png
  16. BIN
      samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/ec882345a403be325bc539ebda211e79.jpg
  17. 71
      samples/MicroserviceDemo/microservices/ProductService.Host/Migrations/20190121115908_Initial.Designer.cs
  18. 23
      samples/MicroserviceDemo/microservices/ProductService.Host/Migrations/20190307065413_Added_ImageName_To_Product.cs
  19. 4
      samples/MicroserviceDemo/microservices/ProductService.Host/Migrations/20190408114353_Initial.Designer.cs
  20. 3
      samples/MicroserviceDemo/microservices/ProductService.Host/Migrations/20190408114353_Initial.cs
  21. 110
      samples/MicroserviceDemo/microservices/ProductService.Host/ProductServiceDataSeeder.cs
  22. 13
      samples/MicroserviceDemo/microservices/ProductService.Host/ProductServiceHostModule.cs

53
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/Index.cshtml

@ -81,26 +81,29 @@
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName" class="btn btn-primary btn-rounded">@L["ContinueReading"]</a>
</div>
<div class="article-owner">
<div class="article-infos">
<div class="user-card">
<a>
<img gravatar-email="@post.Writer.Email" default-image="Identicon" class="article-avatar" />
</a>
<a>
<strong>@post.Writer.UserName</strong>, @ConvertDatetimeToTimeAgo(post.CreationTime)
</a>
<span class="vs-seperator">|</span>
<a>
<i class="fa fa-eye"></i> @L["WiewsWithCount", post.ReadCount]
</a>
<span class="vs-seperator">|</span>
<a>
<i class="fa fa-comment"></i> @L["CommentWithCount", post.CommentCount]
</a>
@if (post.Writer != null)
{
<div class="article-owner">
<div class="article-infos">
<div class="user-card">
<a>
<img gravatar-email="@post.Writer.Email" default-image="Identicon" class="article-avatar" />
</a>
<a>
<strong>@post.Writer.UserName</strong>, @ConvertDatetimeToTimeAgo(post.CreationTime)
</a>
<span class="vs-seperator">|</span>
<a>
<i class="fa fa-eye"></i> @L["WiewsWithCount", post.ReadCount]
</a>
<span class="vs-seperator">|</span>
<a>
<i class="fa fa-comment"></i> @L["CommentWithCount", post.CommentCount]
</a>
</div>
</div>
</div>
</div>
}
</div>
}
@ -137,7 +140,12 @@
<div class="article-infos">
<div class="user-card">
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName">
<strong>@post.Writer.UserName</strong>, @ConvertDatetimeToTimeAgo(post.CreationTime)
@if (post.Writer != null)
{
<strong>@(post.Writer.UserName),</strong>
}
@ConvertDatetimeToTimeAgo(post.CreationTime)
</a>
</div>
</div>
@ -196,7 +204,12 @@
<img gravatar-email="@post.Writer.Email" default-image="Identicon" class="article-avatar" />
</a>
<a>
<strong>@post.Writer.UserName</strong>, @ConvertDatetimeToTimeAgo(post.CreationTime)
@if (post.Writer != null)
{
<strong>@(post.Writer.UserName),</strong>
}
@ConvertDatetimeToTimeAgo(post.CreationTime)
</a>
<span class="vs-seperator">|</span>
<a>

224
samples/MicroserviceDemo/applications/AuthServer.Host/AuthServerDataSeeder.cs

@ -0,0 +1,224 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
using Volo.Abp.IdentityServer.ApiResources;
using Volo.Abp.IdentityServer.Clients;
using Volo.Abp.IdentityServer.IdentityResources;
using Volo.Abp.PermissionManagement;
using Volo.Abp.Uow;
namespace AuthServer.Host
{
public class AuthServerDataSeeder : IDataSeedContributor, ITransientDependency
{
private readonly IApiResourceRepository _apiResourceRepository;
private readonly IClientRepository _clientRepository;
private readonly IIdentityResourceDataSeeder _identityResourceDataSeeder;
private readonly IGuidGenerator _guidGenerator;
private readonly IPermissionDataSeeder _permissionDataSeeder;
public AuthServerDataSeeder(
IClientRepository clientRepository,
IApiResourceRepository apiResourceRepository,
IIdentityResourceDataSeeder identityResourceDataSeeder,
IGuidGenerator guidGenerator,
IPermissionDataSeeder permissionDataSeeder)
{
_clientRepository = clientRepository;
_apiResourceRepository = apiResourceRepository;
_identityResourceDataSeeder = identityResourceDataSeeder;
_guidGenerator = guidGenerator;
_permissionDataSeeder = permissionDataSeeder;
}
[UnitOfWork]
public virtual async Task SeedAsync(DataSeedContext context)
{
await _identityResourceDataSeeder.CreateStandardResourcesAsync();
await CreateApiResourcesAsync();
await CreateClientsAsync();
}
private async Task CreateApiResourcesAsync()
{
var commonApiUserClaims = new[]
{
"email",
"email_verified",
"name",
"phone_number",
"phone_number_verified",
"role"
};
await CreateApiResourceAsync("IdentityService", commonApiUserClaims);
await CreateApiResourceAsync("BloggingService", commonApiUserClaims);
await CreateApiResourceAsync("ProductService", commonApiUserClaims);
await CreateApiResourceAsync("InternalGateway", commonApiUserClaims);
await CreateApiResourceAsync("BackendAdminAppGateway", commonApiUserClaims);
await CreateApiResourceAsync("PublicWebSiteGateway", commonApiUserClaims);
}
private async Task<ApiResource> CreateApiResourceAsync(string name, IEnumerable<string> claims)
{
var apiResource = await _apiResourceRepository.FindByNameAsync(name);
if (apiResource == null)
{
apiResource = await _apiResourceRepository.InsertAsync(
new ApiResource(
_guidGenerator.Create(),
name,
name + " API"
),
autoSave: true
);
}
foreach (var claim in claims)
{
if (apiResource.FindClaim(claim) == null)
{
apiResource.AddUserClaim(claim);
}
}
return await _apiResourceRepository.UpdateAsync(apiResource);
}
private async Task CreateClientsAsync()
{
const string commonSecret = "E5Xd4yMqjP5kjWFKrYgySBju6JVfCzMyFp7n2QmMrME=";
var commonScopes = new[]
{
"email",
"openid",
"profile",
"role",
"phone",
"address"
};
await CreateClientAsync(
"console-client-demo",
new[] { "BloggingService", "IdentityService", "InternalGateway", "ProductService" },
new[] { "client_credentials", "password" },
commonSecret,
permissions: new[] { IdentityPermissions.Users.Default, "ProductManagement.Product" }
);
await CreateClientAsync(
"backend-admin-app-client",
commonScopes.Union(new[] { "BackendAdminAppGateway", "IdentityService", "ProductService" }),
new[] { "hybrid" },
commonSecret,
redirectUri: "http://localhost:51954/signin-oidc",
postLogoutRedirectUri: "http://localhost:51954/signout-callback-oidc"
);
await CreateClientAsync(
"public-website-client",
commonScopes.Union(new[] { "PublicWebSiteGateway", "BloggingService", "ProductService" }),
new[] { "hybrid" },
commonSecret,
redirectUri: "http://localhost:53435/signin-oidc",
postLogoutRedirectUri: "http://localhost:53435/signout-callback-oidc"
);
await CreateClientAsync(
"blogging-service-client",
new[] { "InternalGateway", "IdentityService" },
new[] { "client_credentials" },
commonSecret,
permissions: new[] { IdentityPermissions.UserLookup.Default }
);
}
private async Task<Client> CreateClientAsync(
string name,
IEnumerable<string> scopes,
IEnumerable<string> grantTypes,
string secret,
string redirectUri = null,
string postLogoutRedirectUri = null,
IEnumerable<string> permissions = null)
{
var client = await _clientRepository.FindByCliendIdAsync(name);
if (client == null)
{
client = await _clientRepository.InsertAsync(
new Client(
_guidGenerator.Create(),
name
)
{
ClientName = name,
ProtocolType = "oidc",
Description = name,
AlwaysIncludeUserClaimsInIdToken = true,
AllowOfflineAccess = true,
AbsoluteRefreshTokenLifetime = 31536000, //365 days
AccessTokenLifetime = 31536000, //365 days
AuthorizationCodeLifetime = 300,
IdentityTokenLifetime = 300,
RequireConsent = false
},
autoSave: true
);
}
foreach (var scope in scopes)
{
if (client.FindScope(scope) == null)
{
client.AddScope(scope);
}
}
foreach (var grantType in grantTypes)
{
if (client.FindGrantType(grantType) == null)
{
client.AddGrantType(grantType);
}
}
if (client.FindSecret(secret) == null)
{
client.AddSecret(secret);
}
if (redirectUri != null)
{
if (client.FindRedirectUri(redirectUri) == null)
{
client.AddRedirectUri(redirectUri);
}
}
if (postLogoutRedirectUri != null)
{
if (client.FindPostLogoutRedirectUri(postLogoutRedirectUri) == null)
{
client.AddPostLogoutRedirectUri(postLogoutRedirectUri);
}
}
if (permissions != null)
{
await _permissionDataSeeder.SeedAsync(
ClientPermissionValueProvider.ProviderName,
name,
permissions
);
}
return await _clientRepository.UpdateAsync(client);
}
}
}

10
samples/MicroserviceDemo/applications/AuthServer.Host/AuthServerHostModule.cs

@ -9,11 +9,11 @@ using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic;
using Volo.Abp.Auditing;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.EventBus.RabbitMq;
using Volo.Abp.Autofac;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Volo.Abp.EventBus.RabbitMq;
using Volo.Abp.Identity;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.IdentityServer.EntityFrameworkCore;
@ -89,15 +89,15 @@ namespace AuthServer.Host
app.UseMvcWithDefaultRouteAndArea();
//TODO: Problem on a clustered environment
using (var scope = context.ServiceProvider.CreateScope())
AsyncHelper.RunSync(async () =>
{
AsyncHelper.RunSync(async () =>
using (var scope = context.ServiceProvider.CreateScope())
{
await scope.ServiceProvider
.GetRequiredService<IDataSeeder>()
.SeedAsync();
});
}
}
});
}
}
}

1142
samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190117081756_Initial.Designer.cs

File diff suppressed because it is too large

1150
samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190208210234_Added_ClientId_And_CorrelationId_To_AuditLogs.Designer.cs

File diff suppressed because it is too large

72
samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190208210234_Added_ClientId_And_CorrelationId_To_AuditLogs.cs

@ -1,72 +0,0 @@
using System.Reflection.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace AuthServer.Host.Migrations
{
public partial class Added_ClientId_And_CorrelationId_To_AuditLogs : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
"PK_IdentityServerClientPostLogoutRedirectUris",
"IdentityServerClientPostLogoutRedirectUris"
);
migrationBuilder.AlterColumn<string>(
name: "PostLogoutRedirectUri",
table: "IdentityServerClientPostLogoutRedirectUris",
maxLength: 200,
nullable: false,
oldClrType: typeof(string),
oldMaxLength: 2000);
migrationBuilder.AddPrimaryKey(
"PK_IdentityServerClientPostLogoutRedirectUris",
"IdentityServerClientPostLogoutRedirectUris",
new[] {"ClientId", "PostLogoutRedirectUri"}
);
migrationBuilder.AddColumn<string>(
name: "ClientId",
table: "AbpAuditLogs",
maxLength: 64,
nullable: true);
migrationBuilder.AddColumn<string>(
name: "CorrelationId",
table: "AbpAuditLogs",
maxLength: 64,
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ClientId",
table: "AbpAuditLogs");
migrationBuilder.DropColumn(
name: "CorrelationId",
table: "AbpAuditLogs");
migrationBuilder.DropPrimaryKey(
"PK_IdentityServerClientPostLogoutRedirectUris",
"IdentityServerClientPostLogoutRedirectUris"
);
migrationBuilder.AlterColumn<string>(
name: "PostLogoutRedirectUri",
table: "IdentityServerClientPostLogoutRedirectUris",
maxLength: 2000,
nullable: false,
oldClrType: typeof(string),
oldMaxLength: 200);
migrationBuilder.AddPrimaryKey(
"PK_IdentityServerClientPostLogoutRedirectUris",
"IdentityServerClientPostLogoutRedirectUris",
new[] { "ClientId", "PostLogoutRedirectUri" }
);
}
}
}

1154
samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190209193341_Added_ApplicationName_To_AuditLogs.Designer.cs

File diff suppressed because it is too large

23
samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190209193341_Added_ApplicationName_To_AuditLogs.cs

@ -1,23 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace AuthServer.Host.Migrations
{
public partial class Added_ApplicationName_To_AuditLogs : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ApplicationName",
table: "AbpAuditLogs",
maxLength: 96,
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ApplicationName",
table: "AbpAuditLogs");
}
}
}

347
samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190404130536_Make_IDS4_Entities_Audited.cs

@ -1,347 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace AuthServer.Host.Migrations
{
public partial class Make_IDS4_Entities_Audited : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "CreationTime",
table: "IdentityServerIdentityResources",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.AddColumn<Guid>(
name: "CreatorId",
table: "IdentityServerIdentityResources",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "DeleterId",
table: "IdentityServerIdentityResources",
nullable: true);
migrationBuilder.AddColumn<DateTime>(
name: "DeletionTime",
table: "IdentityServerIdentityResources",
nullable: true);
migrationBuilder.AddColumn<bool>(
name: "IsDeleted",
table: "IdentityServerIdentityResources",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<DateTime>(
name: "LastModificationTime",
table: "IdentityServerIdentityResources",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "LastModifierId",
table: "IdentityServerIdentityResources",
nullable: true);
migrationBuilder.AlterColumn<string>(
name: "LogoUri",
table: "IdentityServerClients",
maxLength: 300,
nullable: true,
oldClrType: typeof(string),
oldMaxLength: 2000,
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "FrontChannelLogoutUri",
table: "IdentityServerClients",
maxLength: 300,
nullable: true,
oldClrType: typeof(string),
oldMaxLength: 2000,
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "ClientUri",
table: "IdentityServerClients",
maxLength: 300,
nullable: true,
oldClrType: typeof(string),
oldMaxLength: 2000,
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "BackChannelLogoutUri",
table: "IdentityServerClients",
maxLength: 300,
nullable: true,
oldClrType: typeof(string),
oldMaxLength: 2000,
oldNullable: true);
migrationBuilder.AddColumn<DateTime>(
name: "CreationTime",
table: "IdentityServerClients",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.AddColumn<Guid>(
name: "CreatorId",
table: "IdentityServerClients",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "DeleterId",
table: "IdentityServerClients",
nullable: true);
migrationBuilder.AddColumn<DateTime>(
name: "DeletionTime",
table: "IdentityServerClients",
nullable: true);
migrationBuilder.AddColumn<bool>(
name: "IsDeleted",
table: "IdentityServerClients",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<DateTime>(
name: "LastModificationTime",
table: "IdentityServerClients",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "LastModifierId",
table: "IdentityServerClients",
nullable: true);
//migrationBuilder.AlterColumn<string>(
// name: "RedirectUri",
// table: "IdentityServerClientRedirectUris",
// maxLength: 200,
// nullable: false,
// oldClrType: typeof(string),
// oldMaxLength: 2000);
//migrationBuilder.AlterColumn<string>(
// name: "Value",
// table: "IdentityServerClientProperties",
// maxLength: 128,
// nullable: false,
// oldClrType: typeof(string),
// oldMaxLength: 2000);
//migrationBuilder.AlterColumn<string>(
// name: "Key",
// table: "IdentityServerClientProperties",
// maxLength: 64,
// nullable: false,
// oldClrType: typeof(string),
// oldMaxLength: 250);
migrationBuilder.AddColumn<DateTime>(
name: "CreationTime",
table: "IdentityServerApiResources",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.AddColumn<Guid>(
name: "CreatorId",
table: "IdentityServerApiResources",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "DeleterId",
table: "IdentityServerApiResources",
nullable: true);
migrationBuilder.AddColumn<DateTime>(
name: "DeletionTime",
table: "IdentityServerApiResources",
nullable: true);
migrationBuilder.AddColumn<bool>(
name: "IsDeleted",
table: "IdentityServerApiResources",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<DateTime>(
name: "LastModificationTime",
table: "IdentityServerApiResources",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "LastModifierId",
table: "IdentityServerApiResources",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "EntityTenantId",
table: "AbpEntityChanges",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "TenantName",
table: "AbpAuditLogs",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "CreationTime",
table: "IdentityServerIdentityResources");
migrationBuilder.DropColumn(
name: "CreatorId",
table: "IdentityServerIdentityResources");
migrationBuilder.DropColumn(
name: "DeleterId",
table: "IdentityServerIdentityResources");
migrationBuilder.DropColumn(
name: "DeletionTime",
table: "IdentityServerIdentityResources");
migrationBuilder.DropColumn(
name: "IsDeleted",
table: "IdentityServerIdentityResources");
migrationBuilder.DropColumn(
name: "LastModificationTime",
table: "IdentityServerIdentityResources");
migrationBuilder.DropColumn(
name: "LastModifierId",
table: "IdentityServerIdentityResources");
migrationBuilder.DropColumn(
name: "CreationTime",
table: "IdentityServerClients");
migrationBuilder.DropColumn(
name: "CreatorId",
table: "IdentityServerClients");
migrationBuilder.DropColumn(
name: "DeleterId",
table: "IdentityServerClients");
migrationBuilder.DropColumn(
name: "DeletionTime",
table: "IdentityServerClients");
migrationBuilder.DropColumn(
name: "IsDeleted",
table: "IdentityServerClients");
migrationBuilder.DropColumn(
name: "LastModificationTime",
table: "IdentityServerClients");
migrationBuilder.DropColumn(
name: "LastModifierId",
table: "IdentityServerClients");
migrationBuilder.DropColumn(
name: "CreationTime",
table: "IdentityServerApiResources");
migrationBuilder.DropColumn(
name: "CreatorId",
table: "IdentityServerApiResources");
migrationBuilder.DropColumn(
name: "DeleterId",
table: "IdentityServerApiResources");
migrationBuilder.DropColumn(
name: "DeletionTime",
table: "IdentityServerApiResources");
migrationBuilder.DropColumn(
name: "IsDeleted",
table: "IdentityServerApiResources");
migrationBuilder.DropColumn(
name: "LastModificationTime",
table: "IdentityServerApiResources");
migrationBuilder.DropColumn(
name: "LastModifierId",
table: "IdentityServerApiResources");
migrationBuilder.DropColumn(
name: "EntityTenantId",
table: "AbpEntityChanges");
migrationBuilder.DropColumn(
name: "TenantName",
table: "AbpAuditLogs");
migrationBuilder.AlterColumn<string>(
name: "LogoUri",
table: "IdentityServerClients",
maxLength: 2000,
nullable: true,
oldClrType: typeof(string),
oldMaxLength: 300,
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "FrontChannelLogoutUri",
table: "IdentityServerClients",
maxLength: 2000,
nullable: true,
oldClrType: typeof(string),
oldMaxLength: 300,
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "ClientUri",
table: "IdentityServerClients",
maxLength: 2000,
nullable: true,
oldClrType: typeof(string),
oldMaxLength: 300,
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "BackChannelLogoutUri",
table: "IdentityServerClients",
maxLength: 2000,
nullable: true,
oldClrType: typeof(string),
oldMaxLength: 300,
oldNullable: true);
//migrationBuilder.AlterColumn<string>(
// name: "RedirectUri",
// table: "IdentityServerClientRedirectUris",
// maxLength: 2000,
// nullable: false,
// oldClrType: typeof(string),
// oldMaxLength: 200);
//migrationBuilder.AlterColumn<string>(
// name: "Value",
// table: "IdentityServerClientProperties",
// maxLength: 2000,
// nullable: false,
// oldClrType: typeof(string),
// oldMaxLength: 128);
//migrationBuilder.AlterColumn<string>(
// name: "Key",
// table: "IdentityServerClientProperties",
// maxLength: 250,
// nullable: false,
// oldClrType: typeof(string),
// oldMaxLength: 64);
}
}
}

4
samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190404130536_Make_IDS4_Entities_Audited.Designer.cs → samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190408114124_Initial.Designer.cs

@ -10,8 +10,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace AuthServer.Host.Migrations
{
[DbContext(typeof(AuthServerDbContext))]
[Migration("20190404130536_Make_IDS4_Entities_Audited")]
partial class Make_IDS4_Entities_Audited
[Migration("20190408114124_Initial")]
partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{

42
samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190117081756_Initial.cs → samples/MicroserviceDemo/applications/AuthServer.Host/Migrations/20190408114124_Initial.cs

@ -14,15 +14,19 @@ namespace AuthServer.Host.Migrations
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
ApplicationName = table.Column<string>(maxLength: 96, nullable: true),
UserId = table.Column<Guid>(nullable: true),
UserName = table.Column<string>(maxLength: 256, nullable: true),
TenantId = table.Column<Guid>(nullable: true),
TenantName = table.Column<string>(nullable: true),
ImpersonatorUserId = table.Column<Guid>(nullable: true),
ImpersonatorTenantId = table.Column<Guid>(nullable: true),
ExecutionTime = table.Column<DateTime>(nullable: false),
ExecutionDuration = table.Column<int>(nullable: false),
ClientIpAddress = table.Column<string>(maxLength: 64, nullable: true),
ClientName = table.Column<string>(maxLength: 128, nullable: true),
ClientId = table.Column<string>(maxLength: 64, nullable: true),
CorrelationId = table.Column<string>(maxLength: 64, nullable: true),
BrowserInfo = table.Column<string>(maxLength: 512, nullable: true),
HttpMethod = table.Column<string>(maxLength: 16, nullable: true),
Url = table.Column<string>(maxLength: 256, nullable: true),
@ -147,6 +151,13 @@ namespace AuthServer.Host.Migrations
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
LastModificationTime = table.Column<DateTime>(nullable: true),
LastModifierId = table.Column<Guid>(nullable: true),
IsDeleted = table.Column<bool>(nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(nullable: true),
DeletionTime = table.Column<DateTime>(nullable: true),
Name = table.Column<string>(maxLength: 200, nullable: false),
DisplayName = table.Column<string>(maxLength: 200, nullable: true),
Description = table.Column<string>(maxLength: 1000, nullable: true),
@ -164,11 +175,18 @@ namespace AuthServer.Host.Migrations
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
LastModificationTime = table.Column<DateTime>(nullable: true),
LastModifierId = table.Column<Guid>(nullable: true),
IsDeleted = table.Column<bool>(nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(nullable: true),
DeletionTime = table.Column<DateTime>(nullable: true),
ClientId = table.Column<string>(maxLength: 200, nullable: false),
ClientName = table.Column<string>(maxLength: 200, nullable: true),
Description = table.Column<string>(maxLength: 1000, nullable: true),
ClientUri = table.Column<string>(maxLength: 2000, nullable: true),
LogoUri = table.Column<string>(maxLength: 2000, nullable: true),
ClientUri = table.Column<string>(maxLength: 300, nullable: true),
LogoUri = table.Column<string>(maxLength: 300, nullable: true),
Enabled = table.Column<bool>(nullable: false),
ProtocolType = table.Column<string>(maxLength: 200, nullable: false),
RequireClientSecret = table.Column<bool>(nullable: false),
@ -178,9 +196,9 @@ namespace AuthServer.Host.Migrations
RequirePkce = table.Column<bool>(nullable: false),
AllowPlainTextPkce = table.Column<bool>(nullable: false),
AllowAccessTokensViaBrowser = table.Column<bool>(nullable: false),
FrontChannelLogoutUri = table.Column<string>(maxLength: 2000, nullable: true),
FrontChannelLogoutUri = table.Column<string>(maxLength: 300, nullable: true),
FrontChannelLogoutSessionRequired = table.Column<bool>(nullable: false),
BackChannelLogoutUri = table.Column<string>(maxLength: 2000, nullable: true),
BackChannelLogoutUri = table.Column<string>(maxLength: 300, nullable: true),
BackChannelLogoutSessionRequired = table.Column<bool>(nullable: false),
AllowOfflineAccess = table.Column<bool>(nullable: false),
IdentityTokenLifetime = table.Column<int>(nullable: false),
@ -211,6 +229,13 @@ namespace AuthServer.Host.Migrations
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorId = table.Column<Guid>(nullable: true),
LastModificationTime = table.Column<DateTime>(nullable: true),
LastModifierId = table.Column<Guid>(nullable: true),
IsDeleted = table.Column<bool>(nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(nullable: true),
DeletionTime = table.Column<DateTime>(nullable: true),
Name = table.Column<string>(maxLength: 200, nullable: false),
DisplayName = table.Column<string>(maxLength: 200, nullable: true),
Description = table.Column<string>(maxLength: 1000, nullable: true),
@ -278,6 +303,7 @@ namespace AuthServer.Host.Migrations
TenantId = table.Column<Guid>(nullable: true),
ChangeTime = table.Column<DateTime>(nullable: false),
ChangeType = table.Column<byte>(nullable: false),
EntityTenantId = table.Column<Guid>(nullable: true),
EntityId = table.Column<string>(maxLength: 128, nullable: false),
EntityTypeFullName = table.Column<string>(maxLength: 128, nullable: false),
ExtraProperties = table.Column<string>(nullable: true)
@ -542,7 +568,7 @@ namespace AuthServer.Host.Migrations
columns: table => new
{
ClientId = table.Column<Guid>(nullable: false),
PostLogoutRedirectUri = table.Column<string>(maxLength: 2000, nullable: false)
PostLogoutRedirectUri = table.Column<string>(maxLength: 200, nullable: false)
},
constraints: table =>
{
@ -560,8 +586,8 @@ namespace AuthServer.Host.Migrations
columns: table => new
{
ClientId = table.Column<Guid>(nullable: false),
Key = table.Column<string>(maxLength: 250, nullable: false),
Value = table.Column<string>(maxLength: 2000, nullable: false)
Key = table.Column<string>(maxLength: 64, nullable: false),
Value = table.Column<string>(maxLength: 128, nullable: false)
},
constraints: table =>
{
@ -579,7 +605,7 @@ namespace AuthServer.Host.Migrations
columns: table => new
{
ClientId = table.Column<Guid>(nullable: false),
RedirectUri = table.Column<string>(maxLength: 2000, nullable: false)
RedirectUri = table.Column<string>(maxLength: 200, nullable: false)
},
constraints: table =>
{

216
samples/MicroserviceDemo/microservices/BloggingService.Host/BlogServiceDataSeeder.cs

@ -0,0 +1,216 @@
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.PermissionManagement;
using Volo.Abp.Uow;
using Volo.Blogging;
using Volo.Blogging.Blogs;
using Volo.Blogging.Posts;
namespace BloggingService.Host
{
public class BlogServiceDataSeeder : IDataSeedContributor, ITransientDependency
{
private readonly IBlogRepository _blogRepository;
private readonly IPostRepository _postRepository;
private readonly IGuidGenerator _guidGenerator;
private readonly IPermissionDataSeeder _permissionDataSeeder;
public BlogServiceDataSeeder(
IBlogRepository blogRepository,
IGuidGenerator guidGenerator,
IPostRepository postRepository,
IPermissionDataSeeder permissionDataSeeder)
{
_blogRepository = blogRepository;
_guidGenerator = guidGenerator;
_postRepository = postRepository;
_permissionDataSeeder = permissionDataSeeder;
}
[UnitOfWork]
public virtual async Task SeedAsync(DataSeedContext context)
{
await CreateBlogPostsAsync();
await GrantAdminPermissionsAsync();
}
private async Task GrantAdminPermissionsAsync()
{
await _permissionDataSeeder.SeedAsync(
RolePermissionValueProvider.ProviderName,
"admin",
BloggingPermissions.GetAll()
);
}
private async Task CreateBlogPostsAsync()
{
if (await _blogRepository.GetCountAsync() > 0)
{
return;
}
var abpBlog = await _blogRepository.InsertAsync(
new Blog(
_guidGenerator.Create(),
"ABP",
"abp"
)
);
await _postRepository.InsertAsync(
new Post(
_guidGenerator.Create(),
abpBlog.Id,
"Introduction to ABP vNext",
"/api/blogging/files/www/100d4c0445cbf55f687339ec8e656abb.jpg",
"introduction-to-abp-vnext"
)
{
Content = @"### Introduction
For a while, we were working to design a new major version of the ASP.NET Boilerplate framework. Now, its time to share it with the community. We are too excited and we believe that you are too.
#### Naming
The name of the framework remains same, except we will call it only as ABP instead of ASP.NET Boilerplate. Because, the boilerplate word leads to misunderstandings and does not reflect that it is a framework (instead of some boilerplate code). We continue to use the ABP name since its the successor of the current ASP.NET Boilerplate framework, except its a rewrite.
### How To Start
We have created a startup template. You can just create a new project from https://abp.io/Templates and start your development. For more information, visit [abp.io](https://abp.io).
### Why A Complete Rewrite?
Why we spent our valuable time to rewrite it from scratch instead of incremental changes and improvements. Why?
#### ASP.NET Core
When we first introduced the ABP framework, it was 2013 (5 years ago)! There was no .Net Core & ASP.NET Core and there was no Angular2+. They were all developed from scratch after ABPs release.
ASP.NET Core introduced many built-in solutions (extension libraries) for dependency injection, logging, caching, localization, configuration and so on. These are actually independent from the ASP.NET Core and usable for any type of application.
We were using 3rd-party libraries and our own solutions for these requirements. We immediately integrated to ASP.NET Core features once they were released. But that was an integration, instead of building the ABP framework on top of these extension libraries. For instance, current ASP.NET Boilerplate still depends on Castle Windsor for dependency injection even its integrated to ASP.NET Cores DI system.
We wanted to depend on these new extension libraries instead of 3rd-party and custom solutions and this changes fundamental structures of the framework.
#### Self Modularization
While current ABP is already modular itself and consists of dozens of packages, we still wanted to split the functionalities to more fine grained nuget packages.
For example, the core Abp package contains many features like DDD classes, auditing, authorization, background jobs, event bus, json serialization, localization, multi-tenancy, threading, timing and so on We wanted to split all these functionality into their own packages and make them optional.
#### Dropping Support for Legacy Technologies
Yes, the new ABP framework will not support ASP.NET MVC 5.x, Entity Framework 6.x and other legacy technologies.
These legacy technologies are maintained by Microsoft but no new feature is being added. So, if you are still using these technologies, you can continue with the current ASP.NET Boilerplate framework. We will continue to maintain it, fix bugs and will add new features.
Dropping support for these legacy libraries will improve our development speed (since we currently duplicate our work for some features) and concentrate on the .Net Core & ASP.NET Core.
The new ABP framework will be based on .net standard. So, its still possible to use full .net framework or .net core with the new ABP framework.
### Goals
We have learnt much from the community and had experience of developing the current ASP.NET Boilerplate framework. New ABP framework has significant and exciting goals.
#### Application Modularity
The first goal is to provide a good infrastructure to develop application modules. We think a module as a set of application features with its own database, its own entities, services, APIs, UI pages, components and so on.
We will create a module market which will contain free & paid application modules. You will also be able to publish your own modules on the market. More information will be coming soon.
#### Microservices
We are designing the new ABP framework to be ready to develop microservices and communicate them to each other.
We are designing application modules so that they can be separately deployable as microservices or they can be embedded into a monolithic application.
We are creating a [specification / best practice documentation](https://github.com/abpframework/abp/blob/master/docs/Best-Practices/Index.md) for that.
#### Theming and UI Composition
The new ABP framework will provide a theming infrastructure based on the latest Twitter Bootstrap 4.x. We developed a basic theme that only uses the plain Bootstrap 4.x styling. Its free and open source. We are also developing premium & paid themes.
UI Composition is one of the main goals. For this purpose, theme system will provide menus, toolbars and other extensible areas to allow other modules to contribute.
#### ORM/Database Independence & MongoDB Integration
While current ASP.NET Boilerplate framework has implemented the repository pattern for ORM/Database independence, identity integration module (Abp.Zero* packages) has never worked well with ORMs other than EF.
With the new ABP framework, the ultimate goal is completely abstract underlying data store system and develop modules EF Core independent.
We embrace the MongoDB as a first-class citizen database and designing entities and repositories without any relational database or ORM assumption.
#### More Extensibility
New ABP framework provides more extensibility points and overriding capabilities for built-in services.
### Some Features
In this section, I will introduce some exciting new features of the new ABP framework.
#### Bootstrap Tag Helpers
We are creating a library to wrap twitter bootstrap 4.x elements/components into tag helpers...
#### Virtual File System
Virtual File System allows you to embed views, pages, components, javascript, css, json and other type of files into your module assembly / package(dll) and use your assembly in any application.Your virtual files behave just like physical files in the containing application with complete ASP.NET Core Integration.
Read more [about the Virtual File System](https://medium.com/volosoft/designing-modularity-on-asp-net-core-virtual-file-system-2dd2cc2078bd) and see [its documentation](https://github.com/abpframework/abp/blob/master/docs/Virtual-File-System.md).
#### Dynamic Bundling & Minification System
Dynamic bundling & minification system works on the virtual file system and allows modules to create, modify and contribute to bundles in a modular, dynamic and powerful way.
This code creates a new style bundle on the fly by including bootstrap(and its dependencies if there are) and two more css files.These files are bundled & minified on production environment, but will be added individually on the development environment.
See [the documentation](https://github.com/abpframework/abp/blob/master/docs/AspNetCore/Bundling-Minification.md) for more.
#### Distributed Event Bus
In current ABP, there is an IEventBus service to trigger and handle events inside the application.In addition to this local event bus, we are creating a distributed event bus abstraction (and RabbitMQ integration) to implement distributed messaging patterns.
#### Dynamic C# HTTP Client Proxies
ABP was already creating dynamic javascript proxies for all HTTP APIs.This feature does also exists in the new ABP framework.In addition, it now can create dynamic C# proxies for all HTTP APIs.
### Future Works
All the stuffs mentioned above are already in development.However, we havent started some concepts yet.
#### Single Page Applications
We designed the new framework SPAs in mind.However, we havent tried it with any SPA framework and we havent prepared a startup template for it yet.
### What About ASP.NET Boilerplate (Current Version) and ASP.NET Zero?
We have dedicated development & support teams actively working on the [ASP.NET Boilerplate](https://aspnetboilerplate.com/) and [ASP.NET Zero](https://aspnetzero.com/) projects. These projects have a big community and we are also getting contributions from the community.
We will continue to make enhancements, add new features and fix bugs for these projects for a long time.So, you can safely continue to use them.
### Is New ABP Production Ready?
No, not yet. Our first goal is to make fundamental features stable then incrementally complete other features.
We will frequently release new versions and every new version will probably have breaking changes.We will write breaking changes on the release notes.
We currently define it experimental.But we hope that this will not continue for a long time. We can not declare a date yet, follow our releases.
### Packages & Versioning
New ABP framework will start with v1.0 instead of following current ASP.NET Boilerplate's version to reflect the fact that its a rewrite.
We will frequently[release](https://github.com/abpframework/abp/releases) it. You can expect many breaking changes until v1.0. Starting with the v1.0, we will pay attention to not introduce breaking changes in 1.x releases.
Current ABPs package names start with[Abp](https://www.nuget.org/packages/Abp) prefix (like Abp.EntityFrameworkCore). New package names start with [Volo.Abp](https://www.nuget.org/packages/Volo.Abp.Core) prefix (like Volo.Abp.EntityFrameworkCore).
### Which One Should I Start With?
If you are creating a new project, we suggest to continue with the current ASP.NET Boilerplate framework since its very mature, feature rich and production ready.
If you are open to breaking changes and want to have experience on the new framework, you can start with the new ABP.We dont suggest it yet for projects with close deadlines and go to the production in a short term.
### Contribution
Just like the current ABP framework, the new framework is available for your contribution.
* You can send pull requests for code or documentation.
* You can write blog posts or tutorials about it.
* You can try it and share your experiences.
* You can create enhancement and feature requests.
* You can report bugs and other issues.
### Communication / Links
*** Official web site**: [abp.io](https://abp.io)
* **Github**: [github.com/abpframework](https://github.com/abpframework)
* **Twitter**: [@abpframework](https://twitter.com/abpframework)"
}
);
}
}
}

26
samples/MicroserviceDemo/microservices/BloggingService.Host/BloggingServiceHostModule.cs

@ -10,6 +10,7 @@ using Volo.Abp;
using Volo.Abp.Auditing;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.Autofac;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Volo.Abp.EventBus.RabbitMq;
@ -119,27 +120,16 @@ namespace BloggingService.Host
app.UseAuditing();
app.UseMvcWithDefaultRouteAndArea();
AsyncHelper.RunSync(() => SeedDataAsync(context.ServiceProvider));
}
public async Task SeedDataAsync(IServiceProvider serviceProvider)
{
using (var scope = serviceProvider.CreateScope())
//TODO: Problem on a clustered environment
AsyncHelper.RunSync(async () =>
{
var blogRepository = scope.ServiceProvider.GetRequiredService<IBlogRepository>();
var guidGenerator = scope.ServiceProvider.GetRequiredService<IGuidGenerator>();
if (await blogRepository.FindByShortNameAsync("abp") == null)
using (var scope = context.ServiceProvider.CreateScope())
{
await blogRepository.InsertAsync(
new Blog(
guidGenerator.Create(),
"ABP Blog",
"abp"
)
);
await scope.ServiceProvider
.GetRequiredService<IDataSeeder>()
.SeedAsync();
}
}
});
}
}
}

BIN
samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/6b32831845a8807aa8b839ed0f28182c.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

BIN
samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/90974f3f1edb4ab0a10cf9759fd5f9ae.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

BIN
samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/ec882345a403be325bc539ebda211e79.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 KiB

71
samples/MicroserviceDemo/microservices/ProductService.Host/Migrations/20190121115908_Initial.Designer.cs

@ -1,71 +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 ProductService.Host.EntityFrameworkCore;
namespace ProductService.Host.Migrations
{
[DbContext(typeof(ProductServiceMigrationDbContext))]
[Migration("20190121115908_Initial")]
partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.2.0-rtm-35687")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("ProductManagement.Product", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(32);
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256);
b.Property<float>("Price");
b.Property<int>("StockCount");
b.HasKey("Id");
b.HasIndex("Code");
b.HasIndex("Name");
b.ToTable("PmProducts");
});
#pragma warning restore 612, 618
}
}
}

23
samples/MicroserviceDemo/microservices/ProductService.Host/Migrations/20190307065413_Added_ImageName_To_Product.cs

@ -1,23 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace ProductService.Host.Migrations
{
public partial class Added_ImageName_To_Product : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ImageName",
table: "PmProducts",
maxLength: 128,
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ImageName",
table: "PmProducts");
}
}
}

4
samples/MicroserviceDemo/microservices/ProductService.Host/Migrations/20190307065413_Added_ImageName_To_Product.Designer.cs → samples/MicroserviceDemo/microservices/ProductService.Host/Migrations/20190408114353_Initial.Designer.cs

@ -10,8 +10,8 @@ using ProductService.Host.EntityFrameworkCore;
namespace ProductService.Host.Migrations
{
[DbContext(typeof(ProductServiceMigrationDbContext))]
[Migration("20190307065413_Added_ImageName_To_Product")]
partial class Added_ImageName_To_Product
[Migration("20190408114353_Initial")]
partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{

3
samples/MicroserviceDemo/microservices/ProductService.Host/Migrations/20190121115908_Initial.cs → samples/MicroserviceDemo/microservices/ProductService.Host/Migrations/20190408114353_Initial.cs

@ -21,7 +21,8 @@ namespace ProductService.Host.Migrations
Code = table.Column<string>(maxLength: 32, nullable: false),
Name = table.Column<string>(maxLength: 256, nullable: false),
Price = table.Column<float>(nullable: false),
StockCount = table.Column<int>(nullable: false)
StockCount = table.Column<int>(nullable: false),
ImageName = table.Column<string>(maxLength: 128, nullable: true)
},
constraints: table =>
{

110
samples/MicroserviceDemo/microservices/ProductService.Host/ProductServiceDataSeeder.cs

@ -0,0 +1,110 @@
using System;
using System.Threading.Tasks;
using ProductManagement;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
namespace ProductService.Host
{
public class ProductServiceDataSeeder : IDataSeedContributor, ITransientDependency
{
private readonly ProductManager _productManager;
private readonly IRepository<Product, Guid> _productRepository;
public ProductServiceDataSeeder(
IRepository<Product, Guid> productRepository,
ProductManager productManager)
{
_productRepository = productRepository;
_productManager = productManager;
}
[UnitOfWork]
public virtual async Task SeedAsync(DataSeedContext context)
{
await AddProductsAsync();
}
private async Task AddProductsAsync()
{
if (await _productRepository.GetCountAsync() > 0)
{
return;
}
await _productManager.CreateAsync(
"ABP04918",
"Lego Star Wars - 75059 Sandcrawler UCS",
999,
42,
"lego.jpg"
);
await _productManager.CreateAsync(
"ABP23849",
"Nikon AF-S 50mm f/1.8 G Lens",
1499,
56,
"nikon.jpg"
);
await _productManager.CreateAsync(
"ABP82731",
"Beats Solo3 Wireless On-Ear Headphone",
97,
20,
"beats.jpg"
);
await _productManager.CreateAsync(
"ABP12322",
"Rampage Sn-Rw2 Gamer Headphone",
654,
42,
"rampage.jpg"
);
await _productManager.CreateAsync(
"ABP00291",
"Asus Transformer Book T300CHI-FH011H",
1249,
3,
"asus.jpg"
);
await _productManager.CreateAsync(
"ABP02918",
"OKI C332DN Dublex + Network A4 Laser Printer",
215,
6,
"oki.jpg"
);
await _productManager.CreateAsync(
"ABP11121",
"Bluecat Rd810 Mini Led",
449,
13,
"bluecat.jpg"
);
await _productManager.CreateAsync(
"ABP44432",
"Sunny 55\" TV 4K Ultra HD Curved Smart Led TV",
2249,
1,
"sunny.jpg"
);
await _productManager.CreateAsync(
"ABP37182",
"Sony Playstation 4 Slim 500 GB (PAL)",
699,
120,
"playstation.jpg"
);
}
}
}

13
samples/MicroserviceDemo/microservices/ProductService.Host/ProductServiceHostModule.cs

@ -9,6 +9,7 @@ using Volo.Abp;
using Volo.Abp.Auditing;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.Autofac;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Volo.Abp.EventBus.RabbitMq;
@ -17,6 +18,7 @@ using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.Security.Claims;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.Threading;
namespace ProductService.Host
{
@ -101,6 +103,17 @@ namespace ProductService.Host
});
app.UseAuditing();
app.UseMvcWithDefaultRouteAndArea();
//TODO: Problem on a clustered environment
AsyncHelper.RunSync(async () =>
{
using (var scope = context.ServiceProvider.CreateScope())
{
await scope.ServiceProvider
.GetRequiredService<IDataSeeder>()
.SeedAsync();
}
});
}
}
}

Loading…
Cancel
Save