Play 2.6 - Java - Transaction managment - playframework-2.6

I try to migrate a Play1 application in Play2 (version 2.6.15 at the moment).
With Play1, transactions were automatically managed when a request arrived. So I didn’t have to worry about consistency of my database updates. Database updates were done all over the service layer.
I have to keep that logic in Play2 and I’m not sure how to do that. I saw some threads with Scala but the answers don't help me. So I'll take my chances :)
To understand how it works, I worked on a snippet with 2 twos models : Person and Address. I want to save a person and the list of their addresses and rollback in case an error occurs on one of the requests.
To start my migration, I was inspired by play-java-jpa-example : I created some repositories that contain all access to database, based on JPAApi and executed on DatabaseExecutionContext
public class PersonRepository implements IPersonRepository {
private final JPAApi jpaApi;
private final DatabaseExecutionContext executionContext;
#Inject
public PersonRepository(JPAApi jpaApi, DatabaseExecutionContext executionContext) {
this.jpaApi = jpaApi;
this.executionContext = executionContext;
}
...
#Override
public CompletionStage<Person> add(Person person) {
return supplyAsync(() -> jpaApi.withTransaction(em -> {
em.persist(person);
return person;
}), executionContext);
}
}
public class AddressRepository implements IAddressRepository {
...
#Override
public CompletionStage<Address> add(Address address) {
return supplyAsync(() -> jpaApi.withTransaction(em -> {
em.persist(address);
return address;
}), executionContext);
}
}
I have a service to save Address
public class AddressService implements IAddressService {
....
#Override
public CompletionStage<Address> add(Address address) {
//do some stuff here
return addressRepository.add(address);
}
}
And a service to save a Person, with
public class PersonService implements IPersonService {
...
#Override
public CompletionStage<Person> add(Person person, List<Address> address) {
return add(person).thenApplyAsync(p -> {
for (Address a : address) {
a.person=p;
addressServiceAsync.add(a);
}
return p;
}, ec.current());
}
}
With this implementation of add(Person person, List address), if saving the second address fails, the person and the first address will have been persisted in the database which is not good enough for me.
I tried to remove transaction management in repositories and put it in my PersonService.add function. By passing the entity manager to the functions of my services and repositories it works (I only tested with synchronous calls). Something like that :
public class PersonService implements IPersonService {
#Override
public CompletionStage<Person> add(Person person, List<Address> address) {
return supplyAsync(() -> jpaApi.withTransaction(em -> {
Person person1 = personRepository.insert(em, person);
for (Address a : address) {
a.person = person1;
addressService.add(em, a);
}
return person1;
})).exceptionally(throwable -> {
Logger.error("pan", throwable);
return null;
});
}
}
I don’t like the approach (giving em to all functions) and wonder about asynchronous calls.
What is planned in Play to handle this kind of rollback problem with JPAApi and DatabaseExecutionContext ?
I didn’t see any explicit thread evoking this point, maybe I missed something. What would be the best practice to solve this problem?
Thanks for your help.

Related

Dependency injection of IActorStateManager in Azure Service Fabric stateful actor

For an Azure Service Fabric stateful service it is possible to inject the IReliableStateManager as follows:
ServiceRuntime.RegisterServiceAsync("MyServiceType", context =>
{
IReliableStateManager stateManager = new ReliableStateManager(context);
return new MyService(stateManager);
}
And this way you can mock IStateManager in unit tests for MyService.
The same doesn't seem possible for a stateful actor. IActorStateManager only has an internal implementation: Microsoft.ServiceFabric.Actors.Runtime.ActorStateManager. So how do I unit test a stateful actor?
At some point in my actor methods a call is made to IActorStateManager but since I can't inject this dependency, unit tests seem impossible.
Is there some way to work around this or is there another solution?
No, IActorStateManager isn't injectable today, but we're working on making it so. For now (without using reflection) you'll have to wrap your state operations in something that you can inject, and have that call into the state manager, which you can then mock for unit testing.
I usually write actor business logic in separate class that have constructor with IStateManager parameter and implement my actor interface. Actor is just wrapper around actor implementation class and I test actorImpl class instead of actor. Look at the code:
public interface IMyActor01 : IActor
{
Task<int> GetCountAsync();
Task SetCountAsync(int count);
}
public class MyActor01Impl : IMyActor01
{
private readonly IActorStateManager StateManager;
public MyActor01Impl(IActorStateManager stateManager)
{
this.StateManager = stateManager;
this.StateManager.TryAddStateAsync("count", 0);
}
public Task<int> GetCountAsync()
{
return this.StateManager.GetStateAsync<int>("count");
}
public Task SetCountAsync(int count)
{
return this.StateManager.AddOrUpdateStateAsync("count", count, (key, value) => count > value ? count : value);
}
}
[StatePersistence(StatePersistence.Persisted)]
internal class MyActor01 : Actor, IMyActor01
{
private MyActor01Impl Impl;
protected override Task OnActivateAsync()
{
ActorEventSource.Current.ActorMessage(this, "Actor activated.");
this.Impl = new MyActor01Impl(this.StateManager);
return Task.FromResult(true);
}
Task<int> IMyActor01.GetCountAsync()
{
return this.Impl.GetCountAsync();
}
Task IMyActor01.SetCountAsync(int count)
{
return this.Impl.SetCountAsync(count);
}
}
[TestFixture]
public class TestFixture01
{
[Test]
public void Test01()
{
//ARRANGE
var dictionary = new Dictionary<string, object>();
var impl = new MyActor01Impl(new StubStateManager(dictionary));
//ACT
impl.SetCountAsync(12).Wait();
//ASSERT
Assert.AreEquals(12, impl.GetCountAsync().Result);
//or
Assert.AreEquals(12, (int)dictionary["count"]);
}
}
I can share StubStateManager implementation if you want.

How can I get Ninject to inject a specific SerialPort instance into a specific instance of another class?

[This is for a Windows 10 IoT UWP app on a Raspberry Pi 2]:
Concretely, I'm trying to create two serial ports and link each one to a device driver for device that has a serial connection (I have two identical devices and a serial port to talk to each). I have a class (call it DeviceDriver) that implements an IDeviceDriver interface for this type of device. My hardware configuration also includes an external chip that has multiple serial ports. I have a class SerialPort for those and they implement an ISerialPort interface.
I need two instances of DeviceDriver as I have two devices, and two instances of SerialPort - one for each device. I can get Ninject to make one serialport and pass the ISerialPort object to the DeviceDriver constructor. Where I am stuck is that I want two DeviceDriver objects; one that gets linked to a SerialPort (COM1) and the other gets linked to a separate SerialPort (COM2). Examples for Ninject show you can bind multiple different classes to one instance (a Shuriken and Sword can both be bound to IWeapon), but I don't see how to bind a COM1 serialport and a COM2 serialport to ISerialPort - it gives me a compilation error. So how do I create two instances of the same SerialPort class (with different constructor arguments to say one is COM1 and the other is COM2, I know how to specify constructor arguments already) and then tell Ninject which SerialPort to pass to two instances of a DeviceDriver class, where one needs COM1 and one needs COM2?
My DeviceDriver basically looks like this:
public class DeviceDriver :IDeviceDriver
{
ISerialPort m_localPort;
public DeviceDriver(ISerialPort port)
{
m_localPort = port;
}
// Other stuff
// ...
}
Anybody have any thoughts how I can do this? The following link is the only thing I've found, but they are talking about Unity and XML configuration files and it seems overly complex for what I'm trying to do.
Initialising configurable objects with dependency injection container
Thanks!
Let's say we've got the following implementation:
public class SerialPortAddress
{
public SerialPortAddress(string address)
{
this.Address = address;
}
public string Address { get; }
}
public interface ISerialPort
{
SerialPortAddress Address { get; }
}
public class SerialPort : ISerialPort
{
public SerialPort(SerialPortAddress address)
{
this.Address = address;
}
public SerialPortAddress Address { get; }
}
public interface IDeviceDriver
{
ISerialPort SerialPort { get; }
}
public class DeviceDriver : IDeviceDriver
{
public DeviceDriver(ISerialPort serialPort)
{
SerialPort = serialPort;
}
public ISerialPort SerialPort { get; }
}
Multi-Injection
We can then create the bindings as follows and retrieve a list of IDeviceDrivers with their serial ports as follows:
public class Test
{
[Fact]
public void Bla()
{
var com1 = new SerialPortAddress("COM1");
var com2 = new SerialPortAddress("COM2");
var kernel = new StandardKernel();
kernel.Bind<ISerialPort>().To<SerialPort>();
kernel.Bind<IDeviceDriver>().To<DeviceDriver>()
.WithParameter(new TypeMatchingConstructorArgument(
typeof(SerialPortAddress),
(ctx, target) => com1, true));
kernel.Bind<IDeviceDriver>().To<DeviceDriver>()
.WithParameter(new TypeMatchingConstructorArgument(
typeof(SerialPortAddress),
(ctx, target) => com2, true));
var deviceDrivers = kernel.Get<List<IDeviceDriver>>();
deviceDrivers.Should().HaveCount(2)
.And.Contain(x => x.SerialPort.Address == com1)
.And.Contain(x => x.SerialPort.Address == com2);
}
}
Also see Multi Injection
Named Bindings
Alternatively, if you need to know which IDeviceDrivers is which, you can also use named bindings:
[Fact]
public void NamedBindings()
{
const string DeviceDriver1 = "DeviceDriver1";
const string DeviceDriver2 = "DeviceDriver2";
var com1 = new SerialPortAddress("COM1");
var com2 = new SerialPortAddress("COM2");
var kernel = new StandardKernel();
kernel.Bind<ISerialPort>().To<SerialPort>();
kernel.Bind<IDeviceDriver>().To<DeviceDriver>()
.Named(DeviceDriver1)
.WithParameter(new TypeMatchingConstructorArgument(
typeof(SerialPortAddress),
(ctx, target) => com1, true));
kernel.Bind<IDeviceDriver>().To<DeviceDriver>()
.Named(DeviceDriver2)
.WithParameter(new TypeMatchingConstructorArgument(
typeof(SerialPortAddress),
(ctx, target) => com2, true));
kernel.Get<IDeviceDriver>(DeviceDriver1).SerialPort.Address.Should().Be(com1);
kernel.Get<IDeviceDriver>(DeviceDriver2).SerialPort.Address.Should().Be(com2);
}
Factory
Finally, you could also create the components by factory, which requires a factory interface to begin with:
public interface IDeviceDriverFactory
{
IDeviceDriver Create(SerialPortAddress address);
}
using Ninject.Extensions.Factory we can now do the following:
[Fact]
public void Factory()
{
var com1 = new SerialPortAddress("COM1");
var com2 = new SerialPortAddress("COM2");
var kernel = new StandardKernel();
kernel.Bind<ISerialPort>().To<SerialPort>();
kernel.Bind<IDeviceDriver>().To<DeviceDriver>();
kernel.Bind<IDeviceDriverFactory>()
.ToFactory(() => new TypeMatchingArgumentInheritanceInstanceProvider());
var factory = kernel.Get<IDeviceDriverFactory>();
factory.Create(com1).SerialPort.Address.Should().Be(com1);
factory.Create(com2).SerialPort.Address.Should().Be(com2);
}
EDIT: Ninject.Extension.Factory may not run on the raspberry pi.
If that's the case you might need to implement the factory yourself:
public class DeviceDriverFactory : IDeviceDriverFactory
{
private readonly IResolutionRoot resolutionRoot;
public DeviceDriverFactory(IResolutionRoot resolutionRoot)
{
this.resolutionRoot = resolutionRoot;
}
public IDeviceDriver Create(SerialPortAddress address)
{
var serialPortAddressParameter = new TypeMatchingConstructorArgument(
typeof(SerialPortAddress),
(ctx, t) => address)
this.resolutionRoot.Get<IDeviceDriver>(serialPortAddressParameter);
}
}
Bind<IDeviceDriverFactory>().To<DeviceDriverFactory>();
I'm not familiar Ninject or Unity, but Castle Windsor has a lifestyle called Pooled, which will create up to a specified number of instances and then return those instances to the pool of instances after they've been released. When using this lifestyle, Windsor will create as many objects as are requested up to the limit specified, and then either recycle the instance (if you've derived from IRecyclable and implemented the Recycle() method) or dispose of it normally.
You can have your components created using a simple factory method that provides the correct constructor arguments, and then when they are returned to the pool they will be correctly configured.
EDIT:
If you're set on using Ninject, then I would solve this problem by injecting an ISerialPortFactory into the constructor of DeviceDriver and using that to create your ISerialPort objects. Since your DeviceDriver class doesn't care which ISerialPort it's using, the factory can be used to manage the instances that you need.
Your factory would look something like this:
public interface ISerialPortFactory
{
ISerialPort CreateNext();
}
public class SerialPortFactory : ISerialPortFactory
{
public ISerialPort CreateNext()
{
var serialPortConfiguration = GetNextConfiguration();
return new SerialPort(serialPortConfiguration);
}
private GetNextConfiguration()
{
// you could manage some kind of internal registry of COMx configurations here
}
}
And your client DeviceDriver class would look like this:
public class DeviceDriver : IDeviceDriver
{
public DeviceDriver(ISerialPortFactory factory)
{
m_localPort = factory.CreateNext();
}
}
The abstract factory method is sort of a heavy-handed way of getting what you want, but it's a surefire way to get exactly what you need since you have complete control over it. Its main use case is to resolve dependencies where you don't necessarily know the exact implementation you want until runtime.

Bind registered name to component instance in structuremap

I am about to switch from Windsor to Structuremap for an existing project with ~100 registered components (mostly singletons).
All components inherit from a common base class that provides logging and health tracking and for this reason, contains a "Name" property used to identify component instances.
With Windsor, it was possible to set the component's Name property to the name that was used to register the component in the IOC container (We used a Facility for this).
My question: Is something like this possible with Structuremap?
(I dream of a call to c.For<IFoo>.Use<Bar>.Named("Doe") that magically results in instanceOfBar.Name = "Doe" somewhere.)
Here is what I tried:
using System;
using StructureMap;
using StructureMap.Interceptors;
using System.Diagnostics;
namespace ConsoleApplication1
{
interface IServiceA { }
interface IServiceB { }
class Base
{
public string Name { get; set; }
}
class ComponentA : Base, IServiceA { }
class ComponentB : Base, IServiceB
{
public ComponentB(IServiceA serviceA)
{
this.ServiceA = serviceA;
}
public IServiceA ServiceA { get; private set; }
}
class SetNameInterceptor : TypeInterceptor
{
public bool MatchesType(Type type) { return true; }
public object Process(object target, IContext context)
{
// *** Any other way? This does not work...
string name = context.BuildStack.Current != null ? context.BuildStack.Current.Name : context.RequestedName;
((Base)target).Name = name;
return target;
}
}
class Program
{
static void Main(string[] args)
{
Container container = new Container(c =>
{
c.RegisterInterceptor(new SetNameInterceptor());
c.For<IServiceA>().Use<ComponentA>().Named("A");
c.For<IServiceB>().Use<ComponentB>().Named("B");
});
var b = container.GetInstance<IServiceB>();
// both Fail:
Debug.Assert(((ComponentB)b).Name == "B");
Debug.Assert(((ComponentA)((ComponentB)b).ServiceA).Name == "A");
}
}
}
The above obviously does not work, I tried several variations but had no luck. The registered name of the target object does not seem to be consistently reachable via IContext.
My second best approach would be to define a new "NamedComponent(...)" extension method that resolves to Named(name).WithProperty(x => x.Name).EqualTo(name), but I wonder if this can be avoided to keep component registration as "structuremap-like" as possible?
Am I missing something?
I've never used WithProperty before but if it works the way I'd expect it should do the trick for you.
I think I would favor using EnrichWith though. Something like:
c.For<IFoo>().Use<Foo>().Named(name).EnrichWith(f => f.Name = name);
EnrichWith is a bit more explicit about what it's doing IMO, and lets you call any code on your instance before returning it to the caller. I like that this lets you do a straightforward assignment as well.
There is also a more complex handler you can use with EnrichWith that gives access to the context of the request - this would allow you to do something like this:
c.For<IFoo>().Use<Foo>().Named(name)
.EnrichWith((c, i) => {
i.Name = c.RequestedName;
return i;
});
This may be overkill for your situation but the contextual awareness can be pretty useful.

How to use methods in ObjectContext class, if I use IObjectSet<T> for unit test?

I am using EF4 with POCO and trying to make it testable architecture.
So I create IObjectContext interface as follow :
public interface IObjectContext
{
IObjectSet<Employee> Employees { get; }
IObjectSet<Team> Teams { get; }
void Commit();
}
Then I changed type of properties to IObjectSet in my real ObjectContext class as follow :
public partial class HRManagementEntities : ObjectContext, IUnitOfWork
{
// skip some codes here...........
public IObjectSet<Employee> Employees
{
get { return _employees ?? (_employees = CreateObjectSet<Employee>("Employees"));
}
private IObjectSet<Employee> _employees;
public IObjectSet<Team> Teams
{
get { return _teams ?? (_teams = CreateObjectSet<Team>("Teams")); }
}
private IObjectSet<Team> _teams;
public void Commit()
{
SaveChanges();
}
}
In my service layer, consume EF like this :
public class Service
{
private IObjectContext ctx;
public HRService(IObjectContext ctx)
{
this.ctx = ctx;
}
public List<Team> GetAllTeams()
{
return ctx.Teams.ToList();
}
}
Here is my problem, How to call methods in ObjectContext for example, ApplyCurrentValues(), ExecuteStoreCommand(), and so on... ?
Do I need to implement those methods in the IObjectContext to use?
EDIT
As RPM's advice, I created following extension method for ApplyCurrentValues() method, another methods could be extended in same way.
public static T UpdateModel<T>(this IObjectSet<T> iObjectSet, T currentEntity) where T : class
{
ObjectSet<T> objectSet = iObjectSet as ObjectSet<T>;
if (objectSet == null || currentEntity == null)
throw new ArgumentNullException();
return objectSet.ApplyCurrentValues(currentEntity);
}
You need to create extension methods for the methods you need, and cast the IObjectSet to ObjectSet.
For instance, if you need to do .Include (eager loading), use this extension method:
public static IQueryable<TSource> Include<TSource>(this IQueryable<TSource> source, string path)
{
var objectQuery = source as ObjectQuery<TSource>;
if (objectQuery != null)
{
objectQuery.Include(path);
}
return source;
}
You could probably do the same thing for IObjectContext, but not sure why you are even mocking this out. You should not expose the OC to outside the repository, only the repository should know about the OC.
In your example, your service is calling ctx.Teams on the entities/repository.
IMO your service should be calling ctx.Find, which would be strongly-typed (via generics) to the Teams object context. (IRepository)
A common trap is to over-mock things. Don't mock everything just for the sake of it, mock the functionality which you require for unit testing.
If you want to abstract out the Object Context then use the Unit of Work pattern.

How do I handle classes with static methods with Ninject?

How do I handle classes with static methods with Ninject?
That is, in C# one can not have static methods in an interface, and Ninject works on the basis of using interfaces?
My use case is a class that I would like it to have a static method to create an
unpopulated instance of itself.
EDIT 1
Just to add an example in the TopologyImp class, in the GetRootNodes() method, how would I create some iNode classes to return? Would I construct these with normal code practice or would I somehow use Ninject? But if I use the container to create then haven't I given this library knowledge of the IOC then?
public interface ITopology
{
List<INode> GetRootNodes();
}
public class TopologyImp : ITopology
{
public List<INode> GetRootNodes()
{
List<INode> result = new List<INode>();
// Need code here to create some instances, but how to without knowledge of the container?
// e.g. want to create a few INode instances and add them to the list and then return the list
}
}
public interface INode
{
// Parameters
long Id { get; set; }
string Name { get; set; }
}
class NodeImp : INode
{
public long Id
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public string Name
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
// Just background to highlight the fact I'm using Ninject fine to inject ITopology
public partial class Form1 : Form
{
private ITopology _top;
public Form1()
{
IKernel kernal = new StandardKernel(new TopologyModule());
_top = kernal.Get<ITopology>();
InitializeComponent();
}
}
If you're building a singleton or something of that nature and trying to inject dependencies, typically you instead write your code as a normal class, without trying to put in lots of (probably incorrect) code managing the singleton and instead register the object InSingletonScope (v2 - you didnt mention your Ninject version). Each time you do that, you have one less class that doesnt surface its dependencies.
If you're feeling especially bloody-minded and are certain that you want to go against that general flow, the main tools Ninject gives you is Kernel.Inject, which one can use after you (or someone else) has newd up an instance to inject the dependencies. But then to locate one's Kernelm you're typically going to be using a Service Locator, which is likely to cause as much of a mess as it is likely to solve.
EDIT: Thanks for following up - I see what you're after. Here's a hacky way to approximate the autofac automatic factory mechanism :-
/// <summary>
/// Ugly example of a not-very-automatic factory in Ninject
/// </summary>
class AutomaticFactoriesInNinject
{
class Node
{
}
class NodeFactory
{
public NodeFactory( Func<Node> createNode )
{
_createNode = createNode;
}
Func<Node> _createNode;
public Node GenerateTree()
{
return _createNode();
}
}
internal class Module : NinjectModule
{
public override void Load()
{
Bind<Func<Node>>().ToMethod( context => () => Kernel.Get<Node>() );
}
}
[Fact]
public void CanGenerate()
{
var kernel = new StandardKernel( new Module() );
var result = kernel.Get<NodeFactory>().GenerateTree();
Assert.IsType<Node>( result );
}
}
The ToMethod stuff is a specific application of the ToProvider pattern -- here's how you'd do the same thing via that route:-
...
class NodeProvider : IProvider
{
public Type Type
{
get { return typeof(Node); }
}
public object Create( IContext context )
{
return context.Kernel.Get<Node>();
}
}
internal class Module : NinjectModule
{
public override void Load()
{
Bind<Func<Node>>().ToProvider<NodeProvider>();
}
}
...
I have not thought this through though and am not recommending this as A Good Idea - there may be far better ways of structuring something like this. #Mark Seemann? :P
I believe Unity and MEF also support things in this direction (keywords: automatic factory, Func)
EDIT 2: Shorter syntax if you're willing to use container-specific attributes and drop to property injection (even if Ninject allows you to override the specific attributes, I much prefer constructor injection):
class NodeFactory
{
[Inject]
public Func<Node> NodeFactory { private get; set; }
public Node GenerateTree()
{
return NodeFactory();
}
}
EDIT 3: You also need to be aware of this Ninject Module by #Remo Gloor which is slated to be in the 2.4 release
EDIT 4: Also overlapping, but not directly relevant is the fact that in Ninject, you can request an IKernel in your ctor/properties and have that injected (but that doesn't work directly in a static method).

Resources