i have a few different aspects in my application and i want them to be able to communicate. is it possible to somehow access one from another or the only way is to have some static field serving as a 'message board'?
i'm talking about aspectj, NOT spring aop. also i'm using the .aj files so i'm not limited by the annotation-only syntax
Edit:
To provide sample use case and the code i'm thinking about: Let's say i want to have different aspects guarding my banking app against frauds. And i want them to communicate sometimes to decide together how to react on new types of timeseries and together change the fraud detection policy:
public aspect MyAspect1 {
private MyState myState = ...
pointcut myPointcut(): ...
before(): myPointcut {
MyAspect2 other = ... // how to get the reference to another similar aspect?
}
}
Related
I would like to use placeholders in a feature file, like this:
Feature: Talk to two servers
Scenario: Forward data from Server A to Server B
Given MongoDb collection "${db1}/foo" contains the following record:
"""
{"key": "value"}
"""
When I send GET "${server1}/data"
When I forward the respone to PUT "${server2}/data"
Then MongoDB collection "${db2}/bar" MUST contain the following record:
"""
{"key": "value"}
"""
The values of ${server1} etc. would depend on the environment in which the test is to be executed (dev, uat, stage, or prod). Therefore, Scenario Outlines are not applicable in this situation.
Is there any standard way of doing this? Ideally there would be something which maintains a Map<String, String> that can be filled in a #Before or so, and runs automatically between Cucumber and the Step Definition so that inside the step definitions no code is needed.
Given the following step definitions
public class MyStepdefs {
#When("^I send GET "(.*)"$)
public void performGET(final String url) {
// …
}
}
And an appropriate setup, when performGET() is called, the placeholder ${server1} in String uri should already be replaced with a lookup of a value in a Map.
Is there a standard way or feature of Cucumber-Java of doing this? I do not mind if this involves dependency injection. If dependency injection is involved, I would prefer Spring, as Spring is already in use for other reasons in my use case.
The simple answer is that you can't.
The solution to your problem is to remove the incidental details from your scenario all together and access specific server information in the step defintions.
The server and database obviously belong together so lets describe them as a single entity, a service.
The details about the rest calls doesn't really help to convey what you're
actually doing. Features don't describe implementation details, they describe behavior.
Testing if records have been inserted into the database is another bad practice and again doesn't describe behavior. You should be able to replace that by an other API call that fetches the data or some other process that proves the other server has received the information. If there are no such means to extract the data available you should create them. If they can't be created you can wonder if the information even needs to be stored (your service would then appear to have the same properties as a black hole :) ).
I would resolve this all by rewriting the story such that:
Feature: Talk to two services
Scenario: Forward foobar data from Service A to Service B
Given "Service A" has key-value information
When I forward the foobar data from "Service A" to "Service B"
Then "Service B" has received the key-value information
Now that we have two entities Service A and Service B you can create a ServiceInformationService to look up information about Service A and B. You can inject this ServiceInformationService into your step definitions.
So when ever you need some information about Service A, you do
Service a = serviceInformationService.lookup("A");
String apiHost = a.getApiHost():
String dbHost = a.getDatabaseHOst():
In the implementation of the Service you look up the property for that service System.getProperty(serviceName + "_" + apiHostKey) and you make sure that your CI sets A_APIHOST and A_DBHOST, B_APIHOST, B_DBHOST, ect.
You can put the name of the collections in a property file that you look up in a similar way as you'd look up the system properties. Though I would avoid direct interaction with the DB if possible.
The feature you are looking for is supported in gherkin with qaf. It supports to use properties defined in properties file using ${prop.key}. In addition it offers strong resource configuration features to work with different environments. It also supports web-services
I am trying to create a generic Logger which would be a small standalone code. Different applications can use this Logger for logging.
Let's say, there are two different codebases- CB1 and CB2.
CB1 needs to capture all public methods of all classes under package- CB1/a/b/c
CB2 needs to capture all public methods of all classes under package- CB2/d/e/f
Now, what I have done till now is as below-
A new codebase, say LogUtility which has an Aspect GenericLogger-
public class GenericLogger {
public Object aroundLog(ProceedingJoinPoint jp) {
//logging code goes here
}
}
in some_context.xml-
<aop:config>
<aop:aspect id="loggerAspect" ref="myLogger">
<aop:pointcut id="sample" expression="${logger.pointcutExpr}" />
<aop:around method="aroundLog" pointcut-ref="sample" />
</aop:aspect>
</aop:config>
If CB1 needs to use this LogUtility, CB1 will add LogUtility to its pom/ivy dependency and provide the value of ${logger.pointcutExpr} via a property file at application startup time.
So, it works fine this way for CB1, CB2,...
The only disadvantage of this approach that I think is the long list in the properties file which has the single key i.e.logger.pointcutExpr
Good thing is, whenever any codebase needs to change it can just add a new pointcut in its own properties file. So a single Aspect can serve multiple codebases.
Earlier, I was trying to do something like this,
#Aspect
#Component
public class GenericLogger {
#Around(<can't make this dynamic>)
public object aroundLog(ProceedingJoinPoint jp) {
//logging code goes here
}
}
The problem with the above is that values passed to any annotation must be final, so can't go with this approach.
I was wondering if there is anything that can be done to achieve this on the fly.
1. Any way in which different codebases can provide the value of the key logger.pointcutExpr without explicitly creating a properties file.
2. Or is it possible to register pointcut with an Aspect on the fly?
I've been googling a lot on this and I'm finding basic AOP tutorials everywhere. I think to do something like this I need to dig deeper in AspectJ along with Spring AOP. I found below links-
https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-choosing
how to apply spring aop for legacy code by taking pointcut as input from user
https://eclipse.org/aspectj/doc/next/devguide/ltw-configuration.html
I have basic knowledge of AspectJ, what I'm looking for could be silly.
You can make what is in the Around method dynamic (sort of) by using a static final expression.
But I would suggest something else.
You can definitely do this sort of thing in AspectJ, it's just that you will need to firstly think of the Aspect as describing what expression will execute for the super set of all your cases. Then within the aspect define the behaviour you are wanting to achieve. So for instance you can use Object target = joinPoint.getTarget(); to get the target (class which was executing the method), and then use String canonicalName = taget.getCanonicalName() which will include the package in the name, and then you can do stuff like:
if(getCanonicalName.contains("some/package") {
System.out.println("You can do better than this if statement");
}
And make whatever if statements you need to differentiate between the various packages which are contained in the canonical name. That way you can have greater control over what happens for each package.
Similar question was posted here Clean code - how to design this class?
I still don't find an answer though, I'm confused!
I read the book "clean code" too.He is saying in some part you shouldn't mix data structure/Object, whether data structure with no behaviour or an object with behaviour.
In my application we have Data tranfer objects which carry data from external services .These DTO have just data accessors and mutators. So I was considering them as Data structure type.
However Robert Martin is saying in his book that client.isMarried() is better than isMarried(client) I found this logical as isMarried function use attributes only from client class.. it is cleaner.
In many areas in my application we need some behaviour on a certain DTOs I'm confused where to put this behaviour.
We have made Utils classes that has business logic like
ClientUtils {
boolean isMarried(Client client) { ...}
String getCompleteName(Client client) { ...}
}
Should this go to the service layer ? even if these methods does not manipulate any thing else other than the input object It does not interact with another layer (DAL, services .. )
Since you can't change the Client class due to the external library constraint, I wouldn't extend it. I suggest making a ClientInfo wrapper class that "has a" Client member instead.
class ClientInfo {
private Client myClient;
public ClientInfo(Client c) {
myClient = c;
}
public boolean isMarried() { ...}
public String getCompleteName() { ...}
}
If you ask me, then Utils class just means you have a random static method lingering somewhere which contains actual business logic. Why not keep DTOs as DTOs, and create a ClientManager class that has isMarried method?
The ClientInfo approach that wraps the external object is another option, possibly driven by Domain Driven Security.
I have a (web-)application that needs special configurations and/or extensions based on the customer using the application. I call these additions "plugins" and they are auto discovered by classpath scanning when the application starts. For extensions that is incredibly easy. Let's say I want to have a plugin which adds an API that prints "hello world" when the URL /myplugin/greet is called: I just create a #Controller annotated class with the according #RequestMapping, put this in a myplugin.jar, copy that on the classpath and that's it.
Problems come up when I want to change some defaults and especially if I want to do this multiple times. Let's say my core application has a config like this:
#Configuration
public class CoreConfiguration {
#Bean
public Set<String> availableModules() {
return Collections.singleton("core");
}
}
Now I have two plugins that don't know about each other (but they do know the CoreConfig), but they both want to add themselves to the list of available modules. How would I do that? If I only had a single plugin that wants to override the module list I could override the existing bean from CoreConfiguration, but with two plugins that becomes a problem. What I imagine is something like this:
#Configuration
public class FirstPluginConfiguration {
#Bean
public Set<String> availableModules(Set<String> availableModules) {
Set<String> extendedSet = new HashSet<>(availableModules);
extendedSet.add("FirstPlugin");
return extendedSet;
}
}
Of course a SecondPluginConfiguration would look nearly exactly like this, except that the Set is not extended by "FirstPlugin", but by "SecondPlugin". I tested it to check what would happen and spring will just never call the First/SecondPluginConfiguration "availableModules" methods but it does not show an error either.
Now of course in this case this could easily be solved by using a mutable Set in the CoreConfiguration and then autowiring and extending the set in the other configurations, but for example I also want to be able to add method interceptors to some beans. So for example I might have an interface CrashLogger which has a logCrash(Throwable t) method and in CoreConfiguration a ToFileCrashLogger is created that writes stack traces to files as the name suggests. Now a plugin could say that he also wants to get notified about crashes, for example the plugin wants to ADDITIONALLY send the stacktrace to someone by email. For that matter that plugin could wrap the CrashLogger configured by the CoreConfiguration and fire BOTH. A second plugin could wrap the wrapper again and do something totally different with the stacktrace and still call both of the other CrashLoggers.
The later does sound somewhat like AOP and if I'd just let ALL my beans be proxied (I did not test that) I could autowire them into my plugin configurations, cast them to org.springframework.aop.framework.Advised and then add advices that manipulate behaviour. However it does seem like a huge overkill to generate proxies for each and everyone of my beans just so that that plugin can potentially add one or two advices one one or two beans.
I have written some code which I thought was quite well-designed, but then I started writing unit tests for it and stopped being so sure.
It turned out that in order to write some reasonable unit tests, I need to change some of my variables access modifiers from private to default, i.e. expose them (only within a package, but still...).
Here is some rough overview of my code in question. There is supposed to be some sort of address validation framework, that enables address validation by different means, e.g. validate them by some external webservice or by data in DB, or by any other source. So I have a notion of Module, which is just this: a separate way to validate addresses. I have an interface:
interface Module {
public void init(InitParams params);
public ValidationResponse validate(Address address);
}
There is some sort of factory, that based on a request or session state chooses a proper module:
class ModuleFactory {
Module selectModule(HttpRequest request) {
Module module = chooseModule(request);// analyze request and choose a module
module.init(createInitParams(request)); // init module
return module;
}
}
And then, I have written a Module that uses some external webservice for validation, and implemented it like that:
WebServiceModule {
private WebServiceFacade webservice;
public void init(InitParams params) {
webservice = new WebServiceFacade(createParamsForFacade(params));
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
So basically I have this WebServiceFacade which is a wrapper over external web service, and my module calls this facade, processes its response and returns some framework-standard response.
I want to test if WebServiceModule processes reponses from external web service correctly. Obviously, I can't call real web service in unit tests, so I'm mocking it. But then again, in order for the module to use my mocked web service, the field webservice must be accessible from the outside. It breaks my design and I wonder if there is anything I could do about it. Obviously, the facade cannot be passed in init parameters, because ModuleFactory does not and should not know that it is needed.
I have read that dependency injection might be the answer to such problems, but I can't see how? I have not used any DI frameworks before, like Guice, so I don't know if it could be easily used in this situation. But maybe it could?
Or maybe I should just change my design?
Or screw it and make this unfortunate field package private (but leaving a sad comment like // default visibility to allow testing (oh well...) doesn't feel right)?
Bah! While I was writing this, it occurred to me, that I could create a WebServiceProcessor which takes a WebServiceFacade as a constructor argument and then test just the WebServiceProcessor. This would be one of the solutions to my problem. What do you think about it? I have one problem with that, because then my WebServiceModule would be sort of useless, just delegating all its work to another components, I would say: one layer of abstraction too far.
Yes, your design is wrong. You should do dependency injection instead of new ... inside your class (which is also called "hardcoded dependency"). Inability to easily write a test is a perfect indicator of a wrong design (read about "Listen to your tests" paradigm in Growing Object-Oriented Software Guided by Tests).
BTW, using reflection or dependency breaking framework like PowerMock is a very bad practice in this case and should be your last resort.
I agree with what yegor256 said and would like to suggest that the reason why you ended up in this situation is that you have assigned multiple responsibilities to your modules: creation and validation. This goes against the Single responsibility principle and effectively limits your ability to test creation separately from validation.
Consider constraining the responsibility of your "modules" to creation alone. When they only have this responsibility, the naming can be improved as well:
interface ValidatorFactory {
public Validator createValidator(InitParams params);
}
The validation interface becomes separate:
interface Validator {
public ValidationResponse validate(Address address);
}
You can then start by implementing the factory:
class WebServiceValidatorFactory implements ValidatorFactory {
public Validator createValidator(InitParams params) {
return new WebServiceValidator(new ProdWebServiceFacade(createParamsForFacade(params)));
}
}
This factory code becomes hard to unit-test, since it is explicitly referencing prod code, so keep this impl very concise. Put any logic (like createParamsForFacade) on the side, so that you can test it separately.
The web service validator itself only gets the responsibility of validation, and takes in the façade as a dependency, following the Inversion of Control (IoC) principle:
class WebServiceValidator implements Validator {
private final WebServiceFacade facade;
public WebServiceValidator(WebServiceFacade facade) {
this.facade = facade;
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
Since WebServiceValidator is not controlling the creation of its dependencies anymore, testing becomes a breeze:
#Test
public void aTest() {
WebServiceValidator validator = new WebServiceValidator(new MockWebServiceFacade());
...
}
This way you have effectively inverted the control of the creation of the dependencies: Inversion of Control (IoC)!
Oh, and by the way, write your tests first. This way you will naturally gravitate towards a testable solution, which is usually also the best design. I think that this is due to the fact that testing requires modularity, and modularity is coincidentally the hallmark of good design.