I am currently working on a project to manage the reservation system.
There is a new requirement, which is to be able to keep track of all booking status changes.
I hope this does not affect the existing logic and exists as an independent module.
At first I thought of AOP, but there are some problems.
This request should record how what data was changed by what action.
I thought that I could extract the different data by applying AOP to the save method of the repository.
However, this is not possible because there are many different actions that update data.
For example, for reservation, the update by using the save method in the repository, but this method is used in various actions such as check in, check out and etc..
Therefore, the difference in data can be obtained, but it is not possible to tell which action the data was updated.
#Service
public class BookingService {
#Autowired
private BookingRepository bookingRepository;
public Booking create(Booking booking) {
return bookingRepository.save(booking);
}
public void update(Booking booking) {
Booking oldBooking = bookingRepository.findById(booking.getId()).orElseThrow(() -> new RuntimeException("Entity not found"));
oldBooking.update(booking);
bookingRepository.save(oldBooking);
}
public void checkIn(long id) {
Booking booking = bookingRepository.findById(id).orElseThrow(() -> new RuntimeException("Entity not found"));
booking.setStatus(Booking.Status.CheckIn);
bookingRepository.save(booking);
}
}
And since I use AOP, I don't want the parameters or result values of the existing logic to fit in a certain form.
While contemplating how to solve this, how about using the method used by Mockito.
In Mockito, We can know when a method is executed within a method.
Wouldn't it be possible to create a method like this, for example?
#Aspect
public class BookingHistory {
#Autowired
private BookingRepository bookingRepository;
#Around("execution(* *Service.update(..))")
public void update(ProceedingJoinPoint proceedingJoinPoint) {
long id = getBookingId(proceedingJoinPoint);
Booking origin = getBooking(id);
final DiffData diffData;
when(bookingRepository::save).thenReturn(result -> diffData = diff(origin, result));
saveHistory("UPDATE", "Booking", diffData);
}
}
But I have no idea how to implement "when", "thenReturn" etc in Mockito.
Could I get some hints to implement Mockito?
And if not this way, is there any other good way?
Mockito is a testing framework and should only be used for unit testing. If you want to keep track of which method changes the data using Spring's AOP, you can use custom annotations. With custom annotations, you can just pass the value which identifies the action and do whatever you want to it, e.g.: log it, publish it to MQ for analytics, etc. Try the following article on creating custom annotations and this on how to get the method's caller information.
Related
Our application calls many external API's which take a session token of the current user as input. So what we currently do is in a controller, get the session token for the user and pass it into a service which in turn might call another service or some API client. To give an idea, we end up with something like this (example is .NET but something similar is I think possible in Java)
public IActionResult DoSomething(string something)
{
this.someService.DoSomethingForUser(this.HttpContext.SessionToken, something);
return View();
}
And then we have
public class SomeService
{
private readonly IApiClient apiClient;
public SomeService(IApiClient apiClient)
{
this.apiClient = apiClient;
}
public void DoSomethingForUser(string sessionToken, something)
{
this.apiClient.DoSomethingForUser(sessionToken, something);
}
}
It can also happen that in SomeService another service is injected which in turn calls the IApiClient instead of SomeService calling IApiClient directly, basically adding another "layer".
We had a discussion with the team if it isn't better to instead of passing the session token, inject it using DI so you get something like this:
public IActionResult DoSomething(string something)
{
this.someService.DoSomethingForUser(something);
return View();
}
And then we have
public class SomeService
{
private readonly IUserService userService;
private readonly IApiClient apiClient;
public SomeService(IUserService userService, IApiClient apiClient)
{
this.userService = userService;
this.apiClient = apiClient;
}
public void DoSomethingForUser(string something)
{
this.apiClient.DoSomethingForUser(userService.SessionToken, something);
}
}
The IUserService would have an IHttpContextAccessor injected:
public class UserService : IUserService
{
private readonly IHttpContextAccessor httpContextAccessor;
public UserService(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
public string SessionToken => httpContextAccessor.HttpContext.SessionToken;
}
The benefits of this pattern are I think pretty clear. Especially with many services, it keeps the code "cleaner" and you end up with less boilerplate code to pass a token around.
Still, I don't like it. To me the downsides of this pattern are more important than its benefit:
I like that passing the token in the methods is concise. It is clear that the service needs some sort of authentication token for it to function. I'm not sure if you can call it a side effect but the fact that a session token is magically injected three layers deep is impossible to tell just by reading the code
Unit testing is a bit more tedious if you have to Mock the IUserService
You run into problems when calling this in another thread, e.g. calling SomeService from another thread. Although these problems can be mitigated by injecting another concrete type of IUserService which gets the token from some place else, it feels like a chore.
To me it strongly feels like an anti pattern but apart from the arguments above it is mostly a feeling. There was a lot of discussion and not everybody was convinced that it was a bad idea. Therefor, my question is, is it an anti pattern or is it perfectly valid? What are some strong arguments for and against it, hopefully so there can be not much debate that this pattern is indeed, either perfectly valid or something to avoid.
I would say the main point is to enable your desired separation of concerns. I think it is a good question if expressed in those terms. As Kit says, different people may prefer different solutions.
REQUEST SCOPED OBJECTS
These occur quite naturally in APIs. Consider the following example, where a UI calls an Orders API, then the Orders API forwards the JWT to an upstream Billing API. A unique Request ID is also sent, in case the flow experiences a temporary problem. If the flow is retried, the Request ID can be used by APIs to prevent data duplication. Yet business logic should not need to know about either the Request ID or the JWT.
BUSINESS LOGIC CLASS DESIGN
I would start by designing my logic classes with my desired inputs, then work out the DI later. In my example the OrderService class might use claims to get the user identity and also for authorization. But I would not want it to know about HTTP level concerns:
public class OrderService
{
private readonly IBillingApiClient billingClient;
public OrderService(IBillingApiClient billingClient, ClaimsPrincipal user)
{
this.billingClient = billingClient;
}
public async void CreateOrder(OrderInput data)
{
this.Authorize();
var order = this.CreateOrder(data);
await this.billingClient.CreateInvoice(order);
}
}
DI SETUP
To enable my preferred business logic, I would write a little DI plumbing, so that I could inject request scoped dependencies in my preferred way. First, when the app starts, I would create a small middleware class. This will run early in the HTTP request pipeline:
private void ConfigureApiMiddleware(IApplicationBuilder api)
{
api.UseMiddleware<ClientContextMiddleware>();
}
In the middleware class I would then create a ClientContext object from runtime data. The OrderService class will run later, after next() is called:
public class ClientContextMiddleware
{
public async Task Invoke(HttpContext context)
{
var jwt = readJwt(context.Request);
var requestId = readRequestId(context.Request);
var holder = context.RequestServices.GetService<ClientContextHolder>();
holder.ClientContext = new ClientContext(jwt, requestIO);
await this.next(context);
}
}
In my DI composition at application startup I would express that the API client should be created when it is first referenced. In the HTTP request pipeline, the OrderService request scoped object will be constructed after the middleware has run. The below lambda will then be invoked:
private void RegisterDependencies(IServiceCollection services)
{
this.services.AddScoped<IApiClient>(
ctx =>
{
var holder = ctx.GetService<ClientContextHolder>();
return new ApiClient(holder.context);
});
this.services.AddScoped<ClientContextHolder>();
}
The holder object is just due to a technology limitation. The MS stack does not allow you to create new request scoped injectable objects at runtime, so you have to update an existing one. In a previous .NET tech stack, the concept of child container per request was made available to developers, so the holder object was not needed.
ASYNC AWAIT
Request scoped objects are stored against the HTTP request object, which is the correct behaviour when using async await. The current thread ID may switch, eg from 4 to 6 after the call to the Billing API.
If the OrderService class has a transient scope, it could get recreated when the flow resumes on thread 6. If this is the case, then resolution will continue to work.
SUMMARY
Designing inputs first, then writing some support code if needed is a good approach I think, and it is also useful to know the DI techniques. Personally I think natural request scoped objects that need to be created at runtime should be usable in DI. Some people may prefer a different approach though.
See in dotnet the area that I am an expert is not an anti standard on the contrary it is the model that many adopt but it is not a model that I would follow for the following reasons
it is not clear where is the token for those who read and use it being an anti clean code
you load important information in a place that is frequently accessed by the framework in the case of .netCore
your classes will reference a large property carrying a lot of unnecessary information when you could have created a more clean model that costs less memory and allocation time, I'm saying this because the HttpAcessor carries all the information relevant to your request
As I would take care of readability (clean code) and improve my performance
I would make a middleware or filter in my flow mvc where I would do the authentication part and create a class like:
public class TokenAuthenciationValues
{
public string TokenClient { get; set; }
public string TokenValue { get; set; }
}
Of course my method is an example but in my middleware I would implement it by loading its token values after calling the necessary apis (of course this model needs an interface and it needs to be configured as .AddScoped() in the case of .net)
That way I would use it in my methods only instantiating my ITokenAuthenciationValues in the constructor and I would have clear and clean information loaded in memory during the entire request
If it is necessary in the middle of the request to change the token any class can access it and change its value
I would have less memory allocated unused in my classes since the IHttpAcessor contract the ITokenAuthenciationValues only has relevant information
Hope this helps
I read "Clean Code" book ((c) Robert C. Martin) and try to use SRP(single responsibility principle). And I have some questions about it. I have some service in my application, and I do not know how can I refactor it so it matched the right approach. For example, I have service:
public interface SendRequestToThirdPartySystemService {
void sendRequest();
}
What does it do if you look at the class name? - send a request to the third party system. But I have this implementation:
#Slf4j
#Service
public class SendRequestToThirdPartySystemServiceImpl implements SendRequestToThirdPartySystemService {
#Value("${topic.name}")
private String topicName;
private final EventBus eventBus;
private final ThirdPartyClient thirdPartyClient;
private final CryptoService cryptoService;
private final Marshaller marshaller;
public SendRequestToThirdPartySystemServiceImpl(EventBus eventBus, ThirdPartyClient thirdPartyClient, CryptoService cryptoService, Marshaller marshaller) {
this.eventBus = eventBus;
this.thirdPartyClient = thirdPartyClient;
this.cryptoService = cryptoService;
this.marshaller = marshaller;
}
#Override
public void sendRequest() {
try {
ThirdPartyRequest thirdPartyRequest = createThirdPartyRequest();
Signature signature = signRequest(thirdPartyRequest);
thirdPartyRequest.setSignature(signature);
ThirdPartyResponse response = thirdPartyClient.getResponse(thirdPartyRequest);
byte[] serialize = SerializationUtils.serialize(response);
eventBus.sendToQueue(topicName, serialize);
} catch (Exception e) {
log.error("Send request was filed with exception: {}", e.getMessage());
}
}
private ThirdPartyRequest createThirdPartyRequest() {
...
return thirdPartyRequest;
}
private Signature signRequest(ThirdPartyRequest thirdPartyRequest) {
byte[] elementForSignBytes = marshaller.marshal(thirdPartyRequest);
Element element = cryptoService.signElement(elementForSignBytes);
Signature signature = new Signature(element);
return signature;
}
What does it do actually? - create a request -> sign this request -> send this request -> to send the response to Queue
This service inject 4 another services: eventBus, thirdPartyClient, cryptoSevice and marshaller. And in sendRequest method calls each this service.
If I want to create a unit test for this service, I need mock 4 services. I think it's too much.
Can somebody indicate how can this service be changed?
Change the class name and leave as is?
Split into several classes?
Something else?
The SRP is a tricky one.
Let's ask two questions:
What is a responsibility?
What are the different types of responsibilities?
One important thing about responsibilities is that they have a Scope and you can define them in different levels of Granularity. and are hierarchical in nature.
Everything in your application can have a responsibility.
Let's start with Modules. Each module has responsibilities an can adhere to the SRP.
Then this Module can be made of Layers. Each Layer has a responsibility and can adhere to the SRP.
Each Layer is made of different Objects, Functions etc. Each Object and/or Function has responsibilities and can adhere to the SRP.
Each Object has Methods. Each Method can adhere to the SRP. Objects can contain other objects and so on.
Each Function or Method in an Object is made of statements and can be broken down to more Functions/Methods. Each statement can have responsibilities too.
Let's give an example. Let's say we have a Billing module. If this module is implemented in a single huge class, does this module adhere to the SRP?
From the point of view of the system, the module does indeed adhere to the SRP. The fact that it's a mess doesn't affect this fact.
From the point of view of the module, the class that represents this module doesn't adhere to the SRP as it will do a lot of other things, like communicate with DB, send Emails, do business logic etc.
Let's take a look at the different types of responsibilities.
When something should be done
How it should be dome
Let's take an example.
public class UserService_v1 {
public class SomeOperation(Guid userID) {
var user = getUserByID(userID);
// do something with the user
}
public User GetUserByID(Guid userID) {
var query = "SELECT * FROM USERS WHERE ID = {userID}";
var dbResult = db.ExecuteQuery(query);
return CreateUserFromDBResult(dbResult);
}
public User CreateUserFromDBResult(DbResult result) {
// parse and return User
}
}
public class UserService_v2 {
public void SomeOperation(Guid userID) {
var user = UserRepository.getByID(userID);
// do something with the user
}
}
Let's take a look at these two implementations.
UserService_v1 and UserService_v2 do exactly the same thing but different ways. From the point of view of the System, these services adhere to the SRP as they contain operations related to Users.
Now let's take a look at what they actually do to complete their work.
UserService_v1 does these things:
Builds a SQL query string.
Calls the db to execute the query
Takes the specific DbResult and creates a User from it.
Does the operation on the User
UserService_v2 does these things:
1. Requests from the repository the User by ID
2. Does the operation on the User
UserService_v1 contains:
How specific query is build
How the specific DbResult is mapped to a User
When this query need to be called (in the begging of the operation in this case)
UserService_v1 contains:
When a User should be retrieved from the DB
UserRepository contains:
How specific query is build
How the specific DbResult is mapped to a User
What we do here is to move the responsibility of How from the Service to the Repository. This way each class has one reason to change. If how changes, we change the Repository. If when changes, we change the Service.
This way we create objects that collaborate with each other to do specific work, by dividing responsibilities. The tricky parts is: what responsibilities we divide?
If we have a UserService and OrderService we don't divide when and how here. We divide what so we can have one service per Entity in our system.
It's natural for there services to need other objects to do their work. We can of course add all of the responsibilities of what, when and how to a single object but that just makes to the messy, unreadable and hard to change.
In this regard the SRP helps us to achieve cleaner code by having more smaller parts that collaborate with and use each other.
Let's take a look at your specific case.
If you can move the responsibility of how the ClientRequest is created and signed by moving it to the ThirdPartyClient, your SendRequestToThirdPartySystemService will only tell when this request should be sent. This will remove Marshaller, and CryptoService as dependencies from your SendRequestToThirdPartySystemService.
Also you have SerializationUtils that you probably rename to Serializer to capture the intent better as Utils is something that we stick to objects that we just don't know how to name and contains a lot of logic (and probably multiple responsibilities).
This will reduce the number of dependencies and your tests will have less things to mock.
Here's a version of the sendRequest method with less responsibilities.
#Override
public void sendRequest() {
try {
// params are not clear as you don't show them to your code
ThirdPartyResponse response = thirdPartyClient.sendRequest(param1, param2);
byte[] serializedMessage = SerializationUtils.serialize(response);
eventBus.sendToQueue(topicName, serialize);
} catch (Exception e) {
log.error("Send request was filed with exception: {}", e.getMessage());
}
}
From your code I'm not sure if you can also move the responsibility of serialization and deserialization to the EventBus, but if you can do that, it will remove Seriazaliation from your service also. This will make the EventBus responsible for how it serialized and stores the things inside it making it more cohesive. Other objects that collaborate with it will just tell it to send and object to the queue not caring how this objects get's there.
I have a lot of DAO classes I need to test on a Spring project.
I am already using DBUnit to mock my database, however I use the #Before annotation to create objects and compare them after tests on create/update/delete operations.
#DatabaseSetup(value = { "/db_data/dao/common.xml", "/db_data/dao/myDAOCommonTest.xml" })
#DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader.class)
public class MyDAOImplTest extends AbstractDaoTU {
#Autowired
private MyDAO myDAO;
private Set<ClassNeeded> objectsNeeded = new HashSet<>();
private ClassOne classOne;
private ClassTwo classTwo;
private ClassThree classThree;
#Override
public void setUp() throws Exception {
super.setUp();
this.objectsNeeded.add(somethingComingFromTheMotherClass);
this.classOne = new ClassOne();
this.classOne.setIdClassOne(1L)
this.classOne.setObjectsNeeded(this.objectsNeeded);
// ... Many other sets
this.classTwo = new ClassTwo();
this.classTwo.setIdClassTwo(1L);
this.classTwo.setClassOne(this.classOne);
// ... Many other sets
// ... Other sets follow for a lot of other objects
}
#Test
public void testOne {
// ...
}
// ... Other tests follow
}
I am using an ORM (Hibernate in this case), and most objects are inter-dependent. My dao functions mostly need complete objects to be called, so I must create the objects before testing.
My questions are the following :
Is there a better approach to unit test DAOs ?
What tools do you know to make this easier/faster to write ? (I am using maven for packaging)
Thanks for your help !
DB Unit complicates the maintenance of the tests as it increases the number of places that need updates when something changes. Additionally it separates the data preparation from the tests too much so it's hard to find which of the data relates to which tests.
Ideally each test prepares data for itself. This removes global state and keeps related things together.
To prepare the data just create entities and save them in the very same test. You can use randomization and transaction rollbacks to isolate the tests. Here is an example from one of my projects:
#Test public void returnsExperimentAsItWasSaved() {
Experiment original = Experiment.random();
experimentRepository.save(original);
flushToDbAndClearCache();
Experiment fromDb = experimentRepository.findOne(original.getExperimentId());
assertReflectionEquals(original, fromDb);
}
Note, that the very same DAO class is used to prepare the data.
The best way is to develop your tests as you would develop your code: refactor to minimize duplication, extract reusable services, etc.
So, you'll probably create some TestCaseFactory that chains up a whole set of objects and saves them using your actual DAO's. Then, you can call them from an #Before as you did. If you need a lot of different sets of objects, you can create different methods or a parameter object etc.
And do a cleanup of all test data in an #After.
i am atg beginner
I have to add few processes to payment pipeline(paymentpipeline.xml) as I have to do some integration stuff. Please let me know how to add processes to payment pipeline and how to invoke them ?
Also, i am not able to find paymentpipeline.xml in my project. Do i need to create it or do changes in commercepipeline.xml? Thanks
You can find paymentpipeline.xml in %DYNAMO_HOME%\..\DCS\src\config\atg\commerce\payment
To create a new process you need to implement PipelineProcessor.
import atg.nucleus.logging.ApplicationLoggingImpl;
import atg.service.pipeline.PipelineProcessor;
public class MyProcessor extends ApplicationLoggingImpl implements PipelineProcessor
{
public int[] getRetCodes()
{
return new int{1,2};
}
public int runProcess(final Object pParam, final PipelineResult pResult) throws Exception
{
// do what ever you wish to do here
//1 is transaction status
return 1;
}
}
This creates a class that will be called when the pipeline chain is called. Next thing required is you need to create a properties file to create a component. It may typically look like this.
$class=/demo/atg/order/processor/MyProcessor
$scope=global
Modify PipelinePayment.xml and add a new pipelinechain. To invoke an individual processor in chain call PipelineManager.runProcess and pass chained of the created processor.
<pipelinechain name=" lastExistingchain" transaction="TX_REQUIRED" headlink="sampleDemoLink">
<pipelinelink name="sampleDemoLink" transaction="TX_REQUIRED">
<processor jndi="demo/atg/order/processor/MyProcessor"/>
</pipelinelink>
</pipelinechain>
Depending on your requirement you may have to add this pipeline link in an existing pipelinechain insttead of creating a new chain.
I am working on a project where I am using MyBatis annotations as persistence framework. Therefore, I have to create an interface for the 'mapper' and compose the mapper in the service like :
class XYZServiceImpl{
public XYZMapper getXYZMapper(){
return SessionUtil.getSqlSession().getMapper(XYZMapper.class)
}
}
Now while unit testing the service with Mockito, I am trying to inject a mock for the mapper. But since I am injecting mock in an instance of XYZService, how can mock a method of the service itself, in this case getXYZMapper() is what I am trying to stub. Although I have got a solution of creating the instance XYZMapper in the service and not call on demand like the above code does something like :
Class XYZServiceImpl{
XYZMapper mapper;
public void useXYZMapper(){
mapper = SessionUtil.getSqlSession().getMapper(XYZMapper.class);
}
}
But that would bring a lot of code changes (ofcourse I can refactor) but is there a way to achieve without having to make code changes?
Also what would be a 'purist' way to have a mapper instance in the class is it the method 1 that is better than method 2 in terms of performance?
EDIT : Here XYZMapper is an interface. Something like :
public interface XYZMapper{
#Select("SELECT * FROM someclass WHERE id = #{id}")
public SomeClass getSomeClass(int id);
}
EDIT : I am facing a similar situation but with a variance that I have a service that I do want to test like XYZServiceImpl. Now it has a method getXYZDetails() which has a lot of business logic handled within the service. Now if getXYZDetails looks like the following :
public XYZDetails getXYZDetails(int id){
XYZDetails details = new XYZDetails();
details.set1Details(fetchSet1Details(id));
//Perform some business logic
details.set2Details(fetchSet2Details(id));
if(details.set2Details() != null){
for(int i = 0; i < details.set2Details().size(); i++){
flushTheseDetails(i);
}
}
.
.
}
Kindly notice that fetchSet1Details(), fetchSet2Details(), flushTheseDetails are public service, public and private service respectively.
I want to know of a method that can mock/stub these methods while testing getXYZDetails() thus enabling me to
There are several options you can use.
Inject dependency
This works only for simple methods like getXYZMapper when method only returns external dependency of you object. This may require to create new XYZServiceImpl instances if for example mapper is bound to connection which is opened per request.
Encapsulate method behavior in object
Another way to achieve similar result is to use a factory or service locator
like this:
public class XYZServiceImpl {
public XYZServiceImpl(XYZMapperFactory mapperFactory) {
this.mapperFactory = mapperFactory;
}
public XYZMapper getXYZMapper() {
return mapperFactory.getMapper();
}
}
This will allow you easily substitute factory in test with implementation which returns mock mapper.
The similar approach can be used for other methods fetchSet1Details, fetchSet2Details, flushTheseDetails that is moving them to other class or classes. If the method contains complex (and may be loosely related) logic it is a good candidate to be moved in separate class. Think about what these methods do. Usually you can move some essential and unrelated part of them to other class or classes and this makes mocking them much easier.
Subclass
This is not recommended but in legacy code sometimes is very helpful as a temporary solution.
In your test subclass you class under test and override methods you need:
#Test
public void someTest() {
XYZServiceImpl sut = new XYZServiceImpl() {
public XYZMapper getXYZMapper() {
return mapperMock;
}
public Whatever fetchSet1Details() {
return whateverYouNeedInTest;
}
}
sut.invokeMethodUnderTest();
}
The only thing you may need to do is to change access modifier of private method to package-private or protected so you can override them.
Spying
This method in also discouraged but you can use mockito spies:
XYZServiceImpl realService = new XYZServiceImpl();
XYZServiceImpl spy = Mockito.spy(realService);
when(spy.fetchSet1Details()).thenReturn(whaeveryouneed);
when(spy.getXYZMapper()).thenReturn(mockMapper);
spy.methodUnderTest();
I would suggest the "purist" way of doing this is to accept an XYZMapper instance in your constructor and store it in a local field.
In production use, you can pass an e.g. SQLXYZMapper, which will interact with your database. In test use, you can pass in a mocked object that you can verify interactions with.