Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mwitkow/java-flagz
Dynamic flag field library for JVM languages.
https://github.com/mwitkow/java-flagz
Last synced: 7 days ago
JSON representation
Dynamic flag field library for JVM languages.
- Host: GitHub
- URL: https://github.com/mwitkow/java-flagz
- Owner: mwitkow
- License: mit
- Created: 2016-05-07T18:31:25.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2020-11-28T11:25:23.000Z (almost 4 years ago)
- Last Synced: 2024-05-09T20:13:55.990Z (6 months ago)
- Language: Java
- Size: 81.1 KB
- Stars: 32
- Watchers: 4
- Forks: 5
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# FlagZ - modern flag library for Java/Scala
[![Travis Build](https://travis-ci.org/mwitkow/java-flagz.svg)](https://travis-ci.org/mwitkow/java-flagz)
[![MIT License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)A modern, annotation-based flags library for Java and Scala that's tailored for large codebases.
## Key features
* No more passing around config classes, and punching-through parameters.
* Like [args4j](http://args4j.kohsuke.org/) or [JCommander](http://jcommander.org/) uses `@FlagInfo` annotation-based mapping of flag names to class fields.
* *Unlike* [args4j](http://args4j.kohsuke.org/) or [JCommander](http://jcommander.org/) allows flags to be specified *anywhere* on the classpath.
* Support for simple types, e.g. `Boolean`, `Integer`, `String`, `Double`...
* Support for generic container types, e.g. `List`, `Map`, `Set`
* All flags are *thread-safe* and dynamically modifiable at runtime through:
- JMX MBeans - a standard Java mechanism for server debugging/tuning - see [`JmxSampleApp`](samples/src/main/java/org/flagz/samples/JmxSampleApp.java) example
- [etcd](https://coreos.com/etcd/docs/latest/getting-started-with-etcd.html) - a distributed key-value store, allowing for multiple servers to have their dynamic flags changed in sync - see [`EtcdSampleApp`](samples/src/main/java/org/flagz/samples/EtcdSampleApp.java)
* Compatibility with existing `System.properties`-based libraries through [`@FlagProperty`](flagz-java/src/main/java/org/flagz/FlagProperty.java) annotation that syncs a flag with a property name.
* `withValidator` - All flags can have a set of validators attached, that prevent bad values (e.g. out of range) from being set.
* `withNotifier` - All flags have callabacks that are triggered when flags are modified dynamically.
* Extensible - just extend [`FlagField`](flagz-java/src/main/java/org/flagz/FlagField.java) and define your own types, e.g. JSON flags, protobuf flags.
* Scala support
## Paint me a code picture
Let's say your project is more than just a simple CLI utility and consists of multiple packages.
You can define parameters that relate to given functionality *inside* the relevant package.
```java
package com.example.rpc.client
...public class MyRpcClientFactory {
@FlagInfo(name="rpc_client_max_threadpool_size", help="Max threadpool size for RPC client callbacks")
private static final Flag maxThreadPool = Flagz.valueOf(10);
@FlagInfo(name="rpc_client_default_timeout_s", help="Default timeout (seconds) for RPCs.")
private static final Flag defaultRpcTimeoutSec = Flagz.valueOf(1.5);
...
}
```All `@FlagInfo`-annotated fields on the classpath will automatically be discovered. Let's say that the server's main
looks like:```java
package com.example.superserver
...public class Main {
@FlagInfo(name="daemonize", altName="d", help="Whether to fork off the process,")
private static final Flag daemonize = Flagz.valueOf(false);@FlagInfo(name="bind_addr", help="Bind addresses to listen on")
private static final Flag> bindList = Flagz.valueOf(ImmutableList.of("0.0.0.0:80"));...
public static void main(String[] args) {
Flagz.parse(args);
...
for (bind in bindList.Get()) {
server.BindTo(bind);
}
if (daemonize.Get()) {
server.Fork()
}
...
}
...
}
```This means you can start the server as:
$ java com.example.superserver.Main --rpc_client_max_threadpool_size=15 -d
This will start the server in daemon mode, and change the the `maxThreadPool` field in `MyRpcClientFactory` without
the need for punching through massive configuration objects.## Installing
### Maven Packages
To use this flag library, include this in your `pom.xml`:
```xml
...
mwitkow-github-repo
https://raw.github.com/mwitkow/maven-repos/master
......
org.flagz
flagz
2.2
...```
### Development
Obviously git-clone this repo. Then install [bazel](https://www.bazel.io/versions/master/docs/install.html)>=0.3.2, which is a fantastic build system that this project uses.
Bazel takes care of downloading all other dependencies (Scala, etcd), the only system requirement is JDK>=8.0.To run all the tests:
```bash
bazel test //...
```#### Publishing (internal stuff)
The way that bazel `BUILD` files are laid out in this project is along the lines of old Maven packages. This means that each target
is a maven-deliverable.To build all of them using:
```
bazel build //flagz-java/src/main/java/org/flagz
bazel build //flagz-etcd/src/main/java/org/flagz
bazel build //flagz-scala/src/main/scala/org/flagz
```The command line will output you the relevant `.jar` file containing the distributable. **TODO(mwitkow)** Add a script for Maven publishing.
#### Sample Apps
The `samples/` directory contains two sample JVM apps that show case what's going on.
You can run the JMX example
```bash
bazel run -- //samples/src/main/java/org/flagz/samples:jmx
```or (with a running [etcd instance](https://github.com/coreos/etcd/releases)) the etcd demo:
```bash
bazel run -- //samples/src/main/java/org/flagz/samples:etcd --flagz_etcd_directory=/foo
```## Status
At Improbable we use `flagz-etcd` and `flagz-scala` to dynamically reconfigure our simulation runtime environment,
allowing our engineers to quickly iterate on tuning parameters and launch new functionality hidden behind flags.As such, the code is considered **production quality**.
## License and Copyright
`flagz` is released under the MIT License. See the [LICENSE](LICENSE) file for details.
The project was completely written by [@mwitkow](https://github.com/mwitkow)'s as a thread-safe and dynamic
version of [kennyyu/flags](https://github.com/kennyyu/flags), with only the public interfaces remaining from the old project.