Skip to content

Commit

Permalink
Merge pull request #322 from elandau/3.x_dev
Browse files Browse the repository at this point in the history
Conditional bindings and major cleanup
  • Loading branch information
elandau committed Nov 24, 2015
2 parents e2ab8d6 + 0d0f315 commit a9d31ff
Show file tree
Hide file tree
Showing 138 changed files with 2,195 additions and 2,177 deletions.
51 changes: 27 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,37 +115,40 @@ public class HelloWorld {
```
----------
Conditional module loading
Conditional bindings
----------------------------------
Karyon supports conditional module loading to auto install Guice modules based on the application runtime environment. Conditionals can depend on property values, modules having been installed, bindings, etc. An example use case would be to set the appropriate bindings for running Eureka locally as opposed to running in the cloud without requiring the developer to know which specific bindings to override. For conditional bindings to work all the jars must be in the classpath and the modules made known to Karyonvia a ModuleListProvider (such as ClassPathModuleListProvider, ServiceLoaderModuleListProvider, etc...). By default karyon will include any modules under the 'com.netflix.karyon' package.
Applications and libraries frequently need different bindings based on the context in which the application is running.
Conditional bindings may be specified in a Guice module using @ProvidesConditionally. This features is syntactic sugar
instead of having to write a complex Provider, put conditional logic in a Guice module or write complex conditional code
when determining which Guice modules to install.
```java
Karyon.create()
.addModuleListProvider(ModuleListProvides.forPackage("org.example")
.addModules(new AbstractModule() {
@Override
protected void configure() {
}
@ProvidesConditionally(isDefault=true)
@ConditionalOnProfile("local")
protected Foo getFooWhenRunningLocally() {
return new FooForLocalDevelopment();
}
@ProvidesConditionally
@ConditionalOnEc2
protected Foo getFooWhenRunningInEc2() {
return new FooForEc2();
}
})
.start()
```
In addition to the conditionals built in to Karyon offers two key conditionals, ConditionalOnLocalDev and ConditionalOnEc2 that can be used to load specific modules (i.e. bindings) for local development and unit tests or when running in an EC2 environment.
For example,
```java
@ConditionalOnLocalDev
public class Module extends AbstractModule {
@Override
protected void configure() {
bind(Foo.class).to(FooLocalDevImpl.class);
}
}
@ConditionalOnEc2
public class Module extends AbstractModule {
@Override
protected void configure() {
bind(Foo.class).to(FooEc2Impl.class);
}
}
```
You can run in either configuration via setting the properties karyon.profiles=localDev or karyon.profiles=ec2
Note the following restrictions when using conditional bindings
* ALL bindings for the type must be conditional otherwise Guice will fail with duplicate bindings errors
* No more than 1 conditional may be true otherwise Guice will fail with duplicate bindings errors
* If no conditions are met the @ProvidesConditionally with isDefault=true will be used. Only one @ProvidesConditional may be default.
* If no conditions are met and no isDefault is set Guice will throw a ProvisionException
----------
Archaius Configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public Object invoke(InputStream stream, Map<String, String> queryParameters) th
if (stream.available() > 0 || !queryParameters.isEmpty()) {
throw new UnsupportedOperationException("Query parameters or request object not supported yet");
}
method.setAccessible(true);
return method.invoke(services.getService(serviceName));
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ protected void configure() {

@Override
public boolean equals(Object obj) {
return AdminModule.class.equals(obj.getClass());
return getClass().equals(obj.getClass());
}

@Override
public int hashCode() {
return AdminModule.class.hashCode();
return getClass().hashCode();
}

}
28 changes: 28 additions & 0 deletions karyon3-api/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2015 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

apply plugin: 'java'

dependencies {
compile 'javax.inject:javax.inject:1'
}

eclipse {
classpath {
downloadSources = true
downloadJavadoc = true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.netflix.karyon.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.inject.Qualifier;

/**
* Qualifier associated with String[] arguments passed to Karyon.start(args)
*/
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Qualifier
public @interface Arguments {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.netflix.karyon.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.inject.Qualifier;

/**
* Qualifier associated with Set{@literal <}String{@literal >} of active profiles
*/
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Qualifier
public @interface Profiles {

}
2 changes: 2 additions & 0 deletions karyon3-archaius2/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ dependencies {
compile group: "com.netflix.archaius", name: "archaius2-archaius1-bridge", version: "${archaius_version}", changing: true

testCompile project(':karyon3-junit')
testCompile "org.hamcrest:hamcrest-core:${hamcrest_version}"
testCompile "org.hamcrest:hamcrest-library:${hamcrest_version}"
}

eclipse {
Expand Down
Loading

0 comments on commit a9d31ff

Please sign in to comment.