Skip to content

Commit

Permalink
Created Marketing read data model
Browse files Browse the repository at this point in the history
  • Loading branch information
ramon-tomas-c committed Jun 13, 2017
1 parent 4be61ab commit 9bf5670
Show file tree
Hide file tree
Showing 32 changed files with 430 additions and 39 deletions.
14 changes: 13 additions & 1 deletion docker-compose-windows.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,16 @@ services:
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
- EventBusConnection=rabbitmq
ports:
- "5109:80"
- "5109:80"

marketing.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word
- EventBusConnection=rabbitmq
- MongoConnectionString=mongodb://nosql.data
- MongoDatabase=MarketingDb
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
ports:
- "5110:80"
14 changes: 13 additions & 1 deletion docker-compose-windows.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,19 @@ services:
- BasketUrl=http://basket.api
ports:
- "5100:80"


marketing.api:
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word
- EventBusConnection=rabbitmq
- MongoConnectionString=mongodb://nosql.data
- MongoDatabase=MarketingDb
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
ports:
- "5110:80"

sql.data:
environment:
- SA_PASSWORD=Pass@word
Expand Down
14 changes: 13 additions & 1 deletion docker-compose-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,19 @@ services:
dockerfile: Dockerfile
depends_on:
- nosql.data

- rabbitmq

marketing.api:
image: eshop/marketing.api
build:
context: ./src/Services/Marketing/Marketing.API
dockerfile: Dockerfile
depends_on:
- sql.data
- nosql.data
- identity.api
- rabbitmq

sql.data:
image: microsoft/mssql-server-windows

Expand Down
3 changes: 3 additions & 0 deletions docker-compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ services:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word
- MongoConnectionString=mongodb://nosql.data
- MongoDatabase=MarketingDb
- EventBusConnection=rabbitmq
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
ports:
- "5110:80"
Expand Down
3 changes: 3 additions & 0 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ services:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word
- MongoConnectionString=mongodb://nosql.data
- MongoDatabase=MarketingDb
- EventBusConnection=rabbitmq
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
ports:
- "5110:80"
Expand Down
3 changes: 3 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ services:
dockerfile: Dockerfile
depends_on:
- sql.data
- nosql.data
- identity.api
- rabbitmq

webspa:
image: eshop/webspa
Expand Down Expand Up @@ -112,3 +114,4 @@ services:
dockerfile: Dockerfile
depends_on:
- nosql.data
- rabbitmq
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public LocationsController(ILocationsService locationsService, IIdentityService
}

//GET api/v1/[controller]/user/1
[Route("user/{userId:int}")]
[Route("user/{userId:guid}")]
[HttpGet]
public async Task<IActionResult> GetUserLocation(int userId)
public async Task<IActionResult> GetUserLocation(Guid userId)
{
var userLocation = await _locationsService.GetUserLocation(userId);
var userLocation = await _locationsService.GetUserLocation(userId.ToString());
return Ok(userLocation);
}

Expand Down Expand Up @@ -54,6 +54,7 @@ public async Task<IActionResult> CreateOrUpdateUserLocation([FromBody]LocationRe
{
var userId = _identityService.GetUserIdentity();
var result = await _locationsService.AddOrUpdateUserLocation(userId, newLocReq);

return result ?
(IActionResult)Ok() :
(IActionResult)BadRequest();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public interface ILocationsRepository

Task<List<Locations>> GetLocationListAsync();

Task<UserLocation> GetUserLocationAsync(int userId);
Task<UserLocation> GetUserLocationAsync(string userId);

Task<List<Locations>> GetCurrentUserRegionsListAsync(LocationRequest currentPosition);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public async Task<Locations> GetAsync(string locationId)
.FirstOrDefaultAsync();
}

public async Task<UserLocation> GetUserLocationAsync(int userId)
public async Task<UserLocation> GetUserLocationAsync(string userId)
{
var filter = Builders<UserLocation>.Filter.Eq("UserId", userId);
return await _context.UserLocation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public interface ILocationsService
{
Task<Locations> GetLocation(string locationId);

Task<UserLocation> GetUserLocation(int id);
Task<UserLocation> GetUserLocation(string id);

Task<List<Locations>> GetAllLocation();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,26 @@
using System.Linq;
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Exceptions;
using System.Collections.Generic;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Locations.API.IntegrationEvents.Events;

public class LocationsService : ILocationsService
{
private ILocationsRepository _locationsRepository;
private readonly ILocationsRepository _locationsRepository;
private readonly IEventBus _eventBus;

public LocationsService(ILocationsRepository locationsRepository)
public LocationsService(ILocationsRepository locationsRepository, IEventBus eventBus)
{
_locationsRepository = locationsRepository ?? throw new ArgumentNullException(nameof(locationsRepository));
_eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
}

public async Task<Locations> GetLocation(string locationId)
{
return await _locationsRepository.GetAsync(locationId);
}

public async Task<UserLocation> GetUserLocation(int id)
public async Task<UserLocation> GetUserLocation(string id)
{
return await _locationsRepository.GetUserLocationAsync(id);
}
Expand All @@ -33,13 +37,8 @@ public async Task<List<Locations>> GetAllLocation()
return await _locationsRepository.GetLocationListAsync();
}

public async Task<bool> AddOrUpdateUserLocation(string id, LocationRequest currentPosition)
{
if (!int.TryParse(id, out int userId))
{
throw new ArgumentException("Not valid userId");
}

public async Task<bool> AddOrUpdateUserLocation(string userId, LocationRequest currentPosition)
{
// Get the list of ordered regions the user currently is within
var currentUserAreaLocationList = await _locationsRepository.GetCurrentUserRegionsListAsync(currentPosition);

Expand All @@ -57,7 +56,33 @@ public async Task<bool> AddOrUpdateUserLocation(string id, LocationRequest curre
userLocation.UpdateDate = DateTime.UtcNow;
await _locationsRepository.UpdateUserLocationAsync(userLocation);

// Publish integration event to update marketing read data model
// with the new locations updated
PublishNewUserLocationPositionIntegrationEvent(userId, currentUserAreaLocationList);

return true;
}

private void PublishNewUserLocationPositionIntegrationEvent(string userId, List<Locations> newLocations)
{
var newUserLocations = MapUserLocationDetails(newLocations);
var @event = new UserLocationUpdatedIntegrationEvent(userId, newUserLocations);
_eventBus.Publish(@event);
}

private List<UserLocationDetails> MapUserLocationDetails(List<Locations> newLocations)
{
var result = new List<UserLocationDetails>();
newLocations.ForEach(location => {
result.Add(new UserLocationDetails()
{
LocationId = location.Id,
Code = location.Code,
Description = location.Description
});
});

return result;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Microsoft.eShopOnContainers.Services.Locations.API.IntegrationEvents.Events
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
using System.Collections.Generic;

public class UserLocationUpdatedIntegrationEvent : IntegrationEvent
{
public string UserId { get; private set; }
public List<UserLocationDetails> LocationList { get; private set; }

public UserLocationUpdatedIntegrationEvent(string userId, List<UserLocationDetails> locationList)
{
UserId = userId;
LocationList = locationList;
}
}
}
5 changes: 5 additions & 0 deletions src/Services/Location/Locations.API/Locations.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.1.0" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="1.2.0" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
Expand Down Expand Up @@ -37,5 +38,9 @@
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/Services/Location/Locations.API/Model/UserLocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class UserLocation
[BsonIgnoreIfDefault]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public int UserId { get; set; } = 0;
public string UserId { get; set; }
[BsonRepresentation(BsonType.ObjectId)]
public string LocationId { get; set; }
public DateTime UpdateDate { get; set; }
Expand Down
14 changes: 14 additions & 0 deletions src/Services/Location/Locations.API/Model/UserLocationDetails.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Microsoft.eShopOnContainers.Services.Locations.API.Model
{
public class UserLocationDetails
{
public string LocationId { get; set; }
public string Code { get; set; }
public string Description { get; set; }
}
}
50 changes: 40 additions & 10 deletions src/Services/Location/Locations.API/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
using Microsoft.AspNetCore.Builder;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Http;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure;
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Filters;
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Repositories;
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using RabbitMQ.Client;
using System.Reflection;
using System;
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Services;
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Repositories;
using Microsoft.AspNetCore.Http;
using Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Filters;

namespace Microsoft.eShopOnContainers.Services.Locations.API
{
Expand All @@ -37,7 +41,7 @@ public Startup(IHostingEnvironment env)
}

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc(options =>
Expand All @@ -46,7 +50,21 @@ public void ConfigureServices(IServiceCollection services)
}).AddControllersAsServices();

services.Configure<LocationSettings>(Configuration);


services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
{
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();

var factory = new ConnectionFactory()
{
HostName = Configuration["EventBusConnection"]
};

return new DefaultRabbitMQPersistentConnection(factory, logger);
});

RegisterServiceBus(services);

// Add framework services.
services.AddSwaggerGen(options =>
{
Expand All @@ -72,7 +90,13 @@ public void ConfigureServices(IServiceCollection services)
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddTransient<IIdentityService, IdentityService>();
services.AddTransient<ILocationsService, LocationsService>();
services.AddTransient<ILocationsRepository, LocationsRepository>();
services.AddTransient<ILocationsRepository, LocationsRepository>();

//configure autofac
var container = new ContainerBuilder();
container.Populate(services);

return new AutofacServiceProvider(container.Build());
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand Down Expand Up @@ -109,5 +133,11 @@ protected virtual void ConfigureAuth(IApplicationBuilder app)
RequireHttpsMetadata = false
});
}

private void RegisterServiceBus(IServiceCollection services)
{
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
}
}
}
Loading

0 comments on commit 9bf5670

Please sign in to comment.