Binding instances during Caliper benchmarks - java

I've recently been tasked with benchmarking some features of our API, and I've been using Caliper to do so. It seems fairly straightforward and is actually quite powerful, I've been following the tutorials here:
How to use caliper
Tutorial from the creator
I'm working with Guice in our current app, so when I try to run the benchmark, I make sure to inject the services I need
Provided below is my code. I've tried setting the variables with their own #injected annotation, I've tried initiating them directly (although there's too many dependencies to deal with, and I'd have to initiate them as well). #Parms annotation won't work because I need to have a string type to iterate through (the parms only takes strings, there's documentation of what to do if it's another type, but it needs a .toString type method)
package com.~~~.~~~.api.benchmark;
import com.~~~.ds.mongo.orm.user.User;
import com.~~~.~~~.api.exceptions.auth.AccessDeniedException;
import com.~~~.~~~.api.service.authorization.UserService;
import com.~~~.~~~.api.service.campaign.CampaignMetadataService;
import com.google.caliper.BeforeExperiment;
import com.google.caliper.Benchmark;
import com.google.caliper.Param;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
public class CampaignBenchmark {
// === SERVICE INJECTIONS
#Inject
private CampaignMetadataService campaignMetadataService;
#Inject
private UserService userService;
// =============================================
// === BENCHMARK PARMS
#Param({
"7ca8c319",
"49191829"
})
String userId;
#Param({
"485",
"500"
})
String hashAdvertiserId;
// =============================================
// === TESTING PARMS
private User user;
// =============================================
// === SETUP
#Inject
public CampaignBenchmark(){
Injector injector = Guice.createInjector();
this.userService = injector.getInstance(UserService.class);
this.campaignMetadataService = injector.getInstance(CampaignMetadataService.class);
}
#BeforeExperiment
void setUp(){
this.user = userService.getUserByHashedId(userId);
}
// =============================================
// === BENCHMARKS
#Benchmark
int fetchAllCampaign(int reps) throws AccessDeniedException {
VideoIqUser user = this.user;
String hashAdvertiserId = this.hashAdvertiserId;
int dummy = 0;
for(int i=0 ; i<reps ; i++){
dummy |= campaignMetadataService.fetchAllCampaigns(user, hashAdvertiserId).size();
}
return dummy;
}
}
When we try to run it with
mvn exec:java -Dexec.mainClass="com.google.caliper.runner.CaliperMain" -Dexec.args="com.~~~.~~~.api.benchmark.CampaignBenchmark"
We get the following
WARNING: All illegal access operations will be denied in a future release
Experiment selection:
Benchmark Methods: [fetchAllCampaign]
Instruments: [allocation, runtime]
User parameters: {hashAdvertiserId=[485, 500], userId=[7ca8c319, 49191829]}
Virtual machines: [default]
Selection type: Full cartesian product
This selection yields 16 experiments.
Could not create an instance of the benchmark class following reasons:
1) Explicit bindings are required and com.~~~.~~~.api.service.campaign.CampaignMetadataService is not explicitly bound.
2) Explicit bindings are required and com.~~~.~~~.api.service.authorization.UserService is not explicitly bound.
The question is: at what point should I be doing injections, and how do I go about that? Should I have a wrapper class setup?
Quick Update
I forgot to mention that is part of a DropWizard (0.7.1) application. We use resources and inject them into the environment
Ex:
environment.jersey().register(injector.getInstance(CampaignManagementResource.class));
These resources contain the services needed to run them, and they are included as #Inject, though we never actually specify a binding anywhere else.
#Inject
private CampaignMetadataService apiCampaignMetadataService;
Is there something I should adjust for DropWizard, or should I just mock up the services?

Think of Guice as nothing but a Hashtable. Working with Guice has these parts:
creating the hashtable
putting things into it
getting things out of it
Your code creates the hashtable and queries it, but never puts anything in it:
public CampaignBenchmark() {
// Creating the hashtable
Injector injector = Guice.createInjector();
// Retrieving from the hashtable
this.userService = injector.getInstance(UserService.class);
this.campaignMetadataService = injector.getInstance(CampaignMetadataService.class);
}
The Guice hashtable is populated in Module classes. Undoubtedly, you have a CampaignModule or AdvertisingModule lying around somewhere. It probably looks like this:
public class CampaignModule extends AbstractModule {
#Override protected void configure() {
bind(CampaignMetadataService.class).to(CampaignMetadataServiceImplementation.class);
}
What that does is put a <CampaignMetadataService, CampaignMetadataServiceImplementation> entry into the Guice hashtable. Going forward, whoever asks for an instance of CampaignMetadataService receives an instance of CampaignMetadataServiceImplementation.
So in your code, you need to let Guice know about this module:
public CampaignBenchmark() {
// Creating the hashtable and letting modules populate it
Injector injector = Guice.createInjector(new CampaignModule(), new UserModule());
// Retrieving from the hashtable
this.userService = injector.getInstance(UserService.class);
this.campaignMetadataService = injector.getInstance(CampaignMetadataService.class);
}
Everything else you do is fine. Side note: #Inject annotations on your constructor and fields don't do anything, since you never ask Guice to supply you with instances of CampaignBenchmark. These can just be deleted.

Related

Sharing state between step definitions in Cucumber

I have 4 step definition classes and a set of domain object classes.
My first step definition class looks like this:
public class ClaimProcessSteps {
Claim claim;
public ClaimProcessSteps(Claim w){
this.claim = w;
}
#Given("^a claim submitted with different enrolled phone's model$")
public void aClaimSubmittedFromCLIENTSChannelWithDifferentEnrolledPhoneSModel() throws Throwable {
claim = ObjMotherClaim.aClaimWithAssetIVH();
}
}
My Claim class looks like this:
public class Claim {
private String claimType;
private String clientName;
private Customer caller;
private List<Hold> holds;
public Claim() {}
public Claim(String claimType, String clientName, Customer caller) {
this.claimType = claimType;
this.clientName = clientName;
this.caller = caller;
}
public String getClaimType() {
return claimType;
}
My second step definition class looks like:
public class CaseLookupSteps {
Claim claim;
public CaseLookupSteps(Claim w){
this.claim = w;
}
#When("^I access case via (right|left) search$")
public void iAccessCaseInCompassViaRightSearch(String searchVia) throws Throwable {
System.out.println(claim.getClaimType());
}
I've already imported the picocontainter dependency in my POM.XML and I am getting the following error.
3 satisfiable constructors is too many for 'class java.lang.String'. Constructor List:[(Buffer), (Builder), ()]
None of my step definition classes constructors receive primitives as arguments. Does anyone have any clue as to why I am still getting that error? Could it be my business object constructor that does expect a String in its constructor?
Thanks in advance for any help.
Picocontainer looks over not only your step definition classes to resolve dependencies. It also looks over all classes that your steps definitions depend on.
In this case, it's trying to resolve the dependencies for your non-default Claim constructor.
public Claim(String claimType, String clientName, Customer caller) {
...
}
According to this issue there's no way to solve this other than keeping only default constructors in all your dependencies.
Assuming your scenario looks like this:
Given some sort of claim
When I lookup this claim
Then I see this claim
Currently your test is missing the setup step of the claim.
So rather then directly sharing the claim object between steps you should create a ClaimService class with only the default constructor. You can inject this service into your step definitions.
Once you have injected the service, you can use it in the step definition of Given some sort of claim to callclaimService.createSomeSortOfClaim() to create a claim. This claim can be created in memory, in a mock db, actual db, or other persistence medium.
In When I lookup this claim you then use claimService.getClaim() to return that claim so you can use its type to search for it.
Doing it this way you'll avoid the difficulty of trying to make the DI container figure out how it should create the claim under test.

How to configure providers with custom parameters?

My class depends on some services which needs to take few parameters and then make network call, currently I am passing those parameters and then creating those services via a factory injected into my class. I need to inject those services as a dependency instead, I know that I can create providers for them but in most of the examples I see that the providers are often bound to the fixed values like serveraddres etc. but I need to give then values during run time.
Below is my example code:
public SomeClass {
private final SomeFactory someFactory;
#Inject
SomeClass(SomeFactory factory) {
someFactory = factory;
}
public Foo getFoo(String fooId) {
FooService fooService = someFactory.getFooService(fooId);
return fooService.getFoo();
}
}
What I need to do is:
public SomeClass {
private final FooService fooService;
#Inject
SomeClass(FooService fooService) {
this.fooService = fooService;
}
public Foo getFoo(String fooId) {
return fooService.getFoo();
}
}
Update 1
Making the use case more clear:
#Provides
#RequestScoped
public SomeService provideSomeService(Dep1 dep1, String code) throws IOException {
return new SomeService.Builder()
.withApplicationName("Foo")
.setCode(code)
.build();
}
Here, code can be null by default and when needed I can give some value in it.
Can I somehow pass arguments to the provider before its created?
If you have a binding for your value (here, code is a String without a binding annotation), then your Update 1 is exactly what the code would look like.
In practice, there are a few differences:
Constants like int and String values are generally annotated with a binding annotation, either #Named or a custom annotation.
If you need to inject a value into an object graph after Guice initialization, but have a deep enough object graph that dependency injection is still a good idea, you can create a child injector. This way you can make a #Named("code") String accessible within one action or object, but not across your entire Guice application.
If your value for code is dynamic enough that it can't be provided through Guice as a key of its own, then you'll have to pass it in using a factory of some sort. For a Builder-based object, I'd say that your SomeFactory implementation is the best that I would come up with in your case.
If you don't need to use a Builder, and can let Guice create the object based on your fields or constructor parameters, you can code-generate a Factory.
Guice can generate a factory for you through FactoryModuleBuilder, in a feature known as "assisted injection".
Google's other tool, AutoFactory, will code-generate a factory implementation that works in both Guice and Dagger. (It's bundled as "Auto", which includes a model object generator called AutoValue that also generates annotation implementations.)
I put a small demonstration of a child injector and assisted injection in my other SO answer here.
The best approach here is to parameterize the module and pass the parameter through to a provider that you create at runtime:
public class MyModule extends AbstractModule {
private final String code;
public MyModule(String code) {
this.code = code;
}
#Override public void configure() {
Provider<Dep1> depProvider = getProvider(Dep1.class);
bind(SomeService.class)
.toProvider(() -> new SomeService.Builder()
.withApplicationName("Foo")
.withDep(depProvider.get())
.setCode(code)
.build())
.in(RequestScoped.class);
}
}

Multiple implementations to a service using Guice using providers

I need a suggestion for how to code for multiple implementations for a service using Google-guice. Below is the example
TestService testService =new TestServiceImplOne();
TestService testService =new TestServiceImplTwo();
As Guice doesn't allow binding a type to more than one implementations as the below code results in error
binderObject.bind(SomeType.class).to(ImplemenationOne.class);
binderObject.bind(SomeType.class).to(ImplemenationTwo.class);
we can solve this with named annotations as below
binder.bind(Player.class).annotatedWith(Names.named("Good")).to(GoodPlayer.class);
binder.bind(Player.class).annotatedWith(Names.named("Bad")).to(BadPlayer.class);
#Named("Good") Player goodPlayer = (Player)injector.getInstance(Player.class);
#Named("Bad") Player badPlayer = (Player)injector.getInstance(Player.class);
But the application which iam working is something like this. We are binding all the modules in the init() method and creating the injector modules:
//separate method to bind
protected void configure() {
bind(new TypeLiteral<List<Service>>() {}).toInstance(serviceSets);
}
//separate method to inject
Injector i = Guice.createInjector(modules);
But with the above process I can just bind one implementation class to the interface (service class)
Could you please provide me a way to do this with providers. I would like to do something like this below
class TestServiceProvider extends Provider{
// some code where it returns the instance of impl class needed. In my case TestServiceImplOne and TestServiceImplTwo and provider returns the corresponding instance of service class
}
and bind service class with provider class. Something like this
bind(TestService.class).toProvider(TestServiceProvider.class);
I would appreciate if someone suggests a good example using providers or some other way that I can inject whatever implementation I want in the client.
Note: I am using webservices and I am not sure how I can inject different implementations when a webservice is called to a service class.
First of all thanks very much for responding . Coming straight to the point
Iam working on webservices . Heres's the Flow
// GET URI
GET http://www.google.com:8182/indi/provide/organizations/{ou}
OrganizationsResource -------->OrganizationService------>OrganizationServiceImpl
Iam binding OrganizationService with OrganizationServiceImpl and injecting the OrganizationService in OrganizationsResource
#Inject
public void setOrganizationService(OrganizationService orgService) {
this.orgService= orgService;
}
Its fine till here but i have two implementations for OrganizationService ------>OrgDeatilsServiceImpl which does some other job
Now i want to bind both OrganizationServiceImpl and OrgDeatilsServiceImpl to OrganizationService
Confusions:
1) What procedure i have to use in Guice to bind two implementaions?
2) How exactly i can code in OrganizationsResource to dynamically decide which implementation to call.
I would appreciate if you give a sample example for the above requirement.
As Vladimir noted, you can use binding annotations with Providers...
// in YourModule.configure():
bind(TestService.class)
.annotatedWith(Names.named("foo")
.toProvider(TestServiceProvider.class);
...and generic types using TypeLiterals...
bind(new TypeLiteral<List<Service>>() {})
.annotatedWith(Names.named("bar")
.toInstance(serviceSets);
...as long as you ask for an annotated instance using getInstance(Key<T>)...
List<Service> servicesOne = injector.getInstance(
new Key<List<Service>>(Names.named("bar")) {});
// or
List<Service> servicesTwo = injector.getInstance(
Key.get(new TypeLiteral<List<Service>>() {}, Names.named("bar"));
...or, preferably, keep them as fields and let Guice do the injecting, because Guice can't inject local variables. Remember that Guice can only inject classes that it creates, or that you request specifically.
class MyInjectorCreator {
#Inject #Named("foo") Provider<TestService> fooServiceProvider;
#Inject #Named("bar") List<Service> barServices;
// Guice will also wrap/unwrap Providers automatically.
#Inject #Named("foo") TestService fooService;
#Inject #Named("bar") Provider<List<Service>> barServicesProvider;
public void createInjector() {
Injector injector = Guice.createInjector(getListOfModules());
injector.injectMembers(this);
}
}
Now, that answers the question as you phrased it in the title. That said, it sounds like you actually want to choose between implementations at runtime, which is a slightly different but easy-to-solve problem:
class TestServiceProvider extends Provider<TestService> {
// Injection is allowed here!
#Inject ApplicationSettings settings;
#Inject Provider<TestServiceImplOne> oneProvider;
#Inject Provider<TestServiceImplTwo> twoProvider;
#Override public TestService get() {
if (settings.isInTestMode()) {
return new TestTestServiceImplImpl(); // without injection!
} else if (settings.useNewService()) {
return twoProvider.get(); // with injection!
} else {
return oneProvider.get(); // also with injection!
}
}
}
But I should warn you that if you know at injector creation time which service to use, you should probably just bind it correctly then for the sake of code cleanliness and ease of readability:
// in YourModule.configure():
if (settings.isInTestMode()) {
bind(TestService.class).toInstance(new TestTestServiceImplImpl());
} else if (settings.useNewService()) {
bind(TestService.class).to(TestServiceImplTwo.class);
} else {
bind(TestService.class).to(TestServiceImplOne.class);
}

How should I unit-test a long function?

If i have a long method of code which gathers data from 2 or 3 difference sources and returns a result. How can I refactor it so that it is more unit-testable? This method is a webservice and I want to make one call from client code to gather all the data.
I can refactor some portions out into smaller methods which will be more testable. But the current method will still be calling those 5 methods and will remain less testable. Assuming Java as programming language, is there a pattern for making such code testable?
This is a very common testing problem, and the most common solution I come across for this is to separate the sourcing of data from the code which uses the data using dependency injection. This not only supports good testing, but is generally a good strategy when working with external data sources (good segregation of responsibilities, isolates the integration point, promotes code reuse being some reasons for this).
The changes you need to make go something like:
For each data source, create an interface to define how data from that source is accessed, and then factor out the code which returns the data into a separate class which implements this.
Dependency inject the data source into the class containing your 'long' function.
For unit testing, inject a mock implementation of each data source.
Here is some code examples showing what this would look like - note that this code is merely illustrative of the pattern, you will need some more sensible names for things. It would be worth studying this pattern and learning more about dependency injection & mocking - two of the most powerful weapons in the unit testers armory.
Data Sources
public interface DataSourceOne {
public Data getData();
}
public class DataSourceOneImpl implements DataSourceOne {
public Data getData() {
...
return data;
}
}
public interface DataSourceTwo {
public Data getData();
}
public class DataSourceTwoImpl implements DataSourceTwo {
public Data getData() {
...
return data;
}
}
Class with Long Method
public class ClassWithLongMethod {
private DataSourceOne dataSourceOne;
private DataSourceTwo dataSourceTwo;
public ClassWithLongMethod(DataSourceOne dataSourceOne,
DataSourceTwo dataSourceTwo) {
this.dataSourceOne = dataSourceOne;
this.dataSourceTwo = dataSourceTwo;
}
public Result longMethod() {
someData = dataSourceOne.getData();
someMoreData = dataSourceTwo.getData();
...
return result;
}
}
Unit Test
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class ClassWithLongMethodTest {
#Test
public void testLongMethod() {
// Create mocked data sources which return the data required by your test
DataSourceOne dataSourceOne = mock(DataSourceOne.class);
when(dataSourceOne.getData()).thenReturn(...);
DataSourceTwo dataSourceTwo = mock(DataSourceTwo.class);
when(dataSourceTwo.getData()).thenReturn(...);
// Create the object under test using the mocked data sources
ClassWithLongMethod sut = new ClassWithLongMethod(dataSourceOne,
dataSourceTwo);
// Now you can unit test the long method in isolation from it's dependencies
Result result = sut.longMethod();
// Assertions on result
...
}
}
Please forgive (and correct) any syntactic mistakes, I don't write much java these days.
The test for the "big" method will look like integration test where the smaller methods can be mocked.
If you can separate the "big" method into five isolated methods, then the "big" method could be further partitioned into semantically-/contextually-meaningful groups of the isolated methods.
Then you can mock the larger groupings of isolated methods for the "big" method.

Guice: is it possible to inject modules?

I have a Module that requires some Depedency. Is there a way Modules themselves can be injected? I realize this is a bit of a chicken and egg situation...
Example:
public class MyModule implements Module {
private final Dependency d_;
#Inject public MyModule(Dependency d) {
d_ = d;
}
public void configure(Binder b) { }
#Provides Something provideSomething() {
// this requires d_
}
}
I suppose in this case the solution would be to turn the #Provides method into a full-fledged Provider<Something> class. This is clearly a simplified example; the code I'm dealing with has many such #Provides methods so cutting them each into individual Provider<...> classes and introducing a module to configure them adds a fair amount of clutter - and I thought Guice was all about reducing boilerplate clutter?
Perhaps it's a reflection of my relative noobyness to Guice but I've come across a fair few cases where I've been tempted to do the above. I must be missing something...
#Provides methods can take dependencies as parameters just like parameters to an #Inject annotated constructor or method:
#Provides Something provideSomething(Dependency d) {
return new Something(d); // or whatever
}
This is documented here, though perhaps it could be made to stand out more.
Using a provider or #Provides methods are great if you need a dependency to manually construct an object. However, what if you need something to help you decide how to configure the bindings themselves? It turns out you can use Guice to create (and configure) your module.
Here is a (contrived) example. First, the module we want to configure:
/**
* Creates a binding for a Set<String> which represents the food in a pantry.
*/
public class PantryModule extends AbstractModule {
private final boolean addCheese;
#Inject
public ConditionalModule(#Named("addCheese") boolean addCheese) {
this.addCheese = addCheese;
}
#Override
protected void configure() {
Multibinder<String> pantryBinder = Multibinder
.newSetBinder(binder(), String.class);
pantryBinder.addBinding().toInstance("milk");
if (addCheese) {
pantryBinder.addBinding().toInstance("cheese");
}
pantryBinder.addBinding().toInstance("bread");
}
}
The PantryModule expects a boolean value to be injected to decide whether or not it should include cheese in the pantry.
Next, we'll use Guice to configure the module:
// Here we use an anonymous class as the "configuring" module. In real life, you would
// probably use a standalone module.
Injector injector = Guice.createInjector(new AbstractModule() {
#Override
protected void configure() {
// No cheese please!
bindConstant().annotatedWith(Names.named("addCheese")).to(false);
bind(PantryModule.class);
}
});
Module configuredConditionalModule = injector.getInstance(PantryModule.class);
Now that we have a configured module, we'll update our injector to use it...
//...continued from last snippet...
injector = injector.createChildInjector(configuredConditionalModule);
And finally we'll get the set of strings that represent our pantry:
//...continued from last snippet...
Set<String> pantry = injector.getInstance(new Key<Set<String>>() {});
for (String food : pantry) {
System.out.println(food);
}
If you put all the pieces together in a main method and run it, you'll get the following output:
milk
bread
If you change the binding to the "addCheese" boolean to true, you'll get:
milk
cheese
bread
This technique is cool, but probably only useful when you have control over the Injector instance and only when the module requires complex dependencies. Nonethless, I found a real need for this on a real project at work. If I did, then someone else might too.
The question is already well answered, but I just wanted to add a variation to Colin's example:
class MyModule extends AbstractModule {
public void configure() {
bind(Something.class).toProvider(new Provider<Something>() {
#Inject Dependency d;
Something get() { return d.buildSomething(); }
}
}
}
The #Provides method approach is clearer than what I have above for this simple case, but I've found that instantiating an actual Provider can be useful in some situations too. Something I stole from the mailing list; wouldn't have occurred to me on my own ;)
What is the problem with initializing the module just by calling new MyModule(d) or by creating a Provider<Something> that has an injected Injector? Those would appear to be the standard ways of handling this sort of problem. As has been mentioned, you can also use #Provides methods with arguments.
If the dependency is optional then you can create the module and then call a setter to initialize the value if needed (e.g., com.google.inject.persist.jpa.JpaPersistModule does this with properties, while using new JpaPersistModule(String) to load the correct configuration).
Otherwise I suppose it might be possible to do so (and then call createChildInjector(Modules... modules)), but I'd almost always prefer one of the other approaches to that one.

Categories

Resources