Giter Site home page Giter Site logo

unleash / unleash-client-java Goto Github PK

View Code? Open in Web Editor NEW
110.0 29.0 68.0 18.66 MB

Unleash client SDK for Java

Home Page: https://docs.getunleash.io

License: Apache License 2.0

Java 100.00%
toggles feature-toggles feature-flags java feature unleash-server java-client client-sdk activation-strategy feature-management

unleash-client-java's Introduction

What is Unleash?

Unleash is a powerful open source solution for feature management. It streamlines your development workflow, accelerates software delivery, and empowers teams to control how and when they roll out new features to end users. With Unleash, you can deploy code to production in smaller, more manageable releases at your own pace.

Feature flags in Unleash let you test your code with real production data, reducing the risk of negatively impacting your users' experience. It also enables your team to work on multiple features simultaneously without the need for separate feature branches.

Unleash is the most popular open source solution for feature flagging on GitHub. It supports 15 official client and server SDKs and over 15 community SDKs. You can even create your own SDK if you wish. Unleash is compatible with any language and framework.


Getting Started with Unleash

1. Setting Up Unleash

To get started with Unleash, you need git and docker installed on your machine.

Execute the following commands:

git clone [email protected]:Unleash/unleash.git
cd unleash
docker compose up -d

Then point your browser to localhost:4242 and log in using:

  • username: admin
  • password: unleash4all

If you'd rather run the source code in this repo directly via Node.js, see the step-by-step instructions to get up and running in the contributing guide.

2. Connect your SDK

Find your preferred SDK in our list of official SDKs and import it into your project. Follow the setup guides for your specific SDK.

If you use the docker compose file from the previous step, here's the configuration details you'll need to get going:

  • For front-end SDKs, use:
    • URL: http://localhost:4242/api/frontend/
    • clientKey: default:development.unleash-insecure-frontend-api-token
  • For server-side SDKs, use:
    • Unleash API URL: http://localhost:4242/api/
    • API token: default:development.unleash-insecure-api-token

If you use a different setup, your configuration details will most likely also be different.

Check a feature toggle

Checking the state of a feature toggle in your code is easy! The syntax will vary depending on your language, but all you need is a simple function call to check whether a toggle is available. Here's how it might look in Java:

if (unleash.isEnabled("AwesomeFeature")) {
  // do new, flashy thing
} else {
  // do old, boring stuff
}

Run Unleash on a service?

If you don't want to run Unleash locally, we also provide easy deployment setups for Heroku and Digital Ocean:

Deploy to Heroku Deploy to DigitalOcean

Configure and run Unleash anywhere

The above sections show you how to get up and running quickly and easily. When you're ready to start configuring and customizing Unleash for your own environment, check out the documentation for getting started with self-managed deployments, Unleash configuration options, or running Unleash locally via docker.


Online demo

Try out the Unleash online demo.

The Unleash online demo


Community and help — sharing is caring

We know that learning a new tool can be hard and time-consuming. We have a growing community that loves to help out. Please don't hesitate to reach out for help.

Join Unleash on Slack

💬 Join Unleash on Slack if you want ask open questions about Unleash, feature toggling or discuss these topics in general.

💻 Create a GitHub issue if you have found a bug or have ideas on how to improve Unleash.

📚 Visit the documentation for more in-depth descriptions, how-to guides, and more.

📖 Learn more about the principles of building and scaling feature flag solutions.


Contribute to Unleash

Unleash is the largest open source feature flag solution on GitHub. Building Unleash is a collaborative effort, and we owe a lot of gratitude to many smart and talented individuals. Building it together with the community ensures that we build a product that solves real problems for real people. We'd love to have your help too: Please feel free to open issues or provide pull requests.

Check out the CONTRIBUTING.md file for contribution guidelines and the Unleash developer guide for tips on environment setup, running the tests, and running Unleash from source.

Contributors

The Unleash contributors


Features our users love

Flexibility and adaptability

Security and performance

  • Privacy by design (GDPR and Schrems II). End-user data never leaves your application.
  • Audit logs
  • Enforce OWASP's secure headers via the strict HTTPS-only mode
  • Flexible hosting options: host it on premise or in the cloud (any cloud)
  • Scale the Unleash Proxy independently of the Unleash server to support any number of front-end clients without overloading your Unleash instance

Looking for more features?

If you're looking for one of the following features, please take a look at our Pro and Enterprise plans:


Architecture

Read more in the system overview section of the Unleash documentation.


Unleash SDKs

To connect your application to Unleash you'll need to use a client SDK for your programming language.

Official server-side SDKs:

Official front-end SDKs:

The front-end SDKs connects via the Unleash Proxy in order to ensure privacy, scalability and security.

Community SDKs:

If none of the official SDKs fit your need, there's also a number of community-developed SDKs where you might find an implementation for your preferred language (such as Elixir, Dart, Clojure, and more).


Users of Unleash

Unleash is trusted by thousands of companies all over the world.

Proud Open-Source users: (send us a message if you want to add your logo here)

The Unleash logo encircled by logos for Finn.no, nav (the Norwegian Labour and Welfare Administration), Budgets, Otovo, and Amedia. The encircling logos are all connected to the Unleash logo.


Migration guides

Unleash has evolved significantly over the past few years, and we know how hard it can be to keep software up to date. If you're using the current major version, upgrading shouldn't be an issue. If you're on a previous major version, check out the Unleash migration guide!


Want to know more about Unleash?

Videos and podcasts

Articles and more

unleash-client-java's People

Contributors

ajvasey avatar andereld avatar andersos avatar andreas-unleash avatar annedroiid avatar blankg avatar checketts avatar chriswk avatar dennis-menge avatar dependabot[bot] avatar emilva avatar enrico2 avatar eurafa avatar gardleopard avatar gastonfournier avatar henrik242 avatar ivarconr avatar jan-berge-ommedal avatar jarib avatar joschi avatar martonskjevelandnav avatar michbeck100 avatar msayag avatar pedro-carneiro avatar praveenpg avatar scuilion avatar sighphyre avatar sjaanus avatar sveisvei avatar thomasheartman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unleash-client-java's Issues

feat: function for returning headers

This would allow for dynamic header setting, which is important to enable rotation of auth-tokens etc without restarting.

For reference, this feature is already implemented in the Node.js SDK, see Unleash/unleash-client-node#151

My thought was that it should be possible to register a function as part of the Unleash Configuration which would return a Map (name, value) of headers to add request sent to the unleash-server. If this function is set it should take precedence over customHttpHeaders already part of the UnleashConfig.java.

FeatureToggleRepository has set intialDelay to pooling interval

Now we have to wait a full polling interval before the client syncs feature toggle states with the server on start-up.

This can be significantly improved by just setting the initial delay to 0, forcing the client to perfom a server sync immediately.

getting error while using unleash client while running web app cygwin

2019-02-07 12:59:51.570  WARN 5092 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Could not refresh feature toggles
no.finn.unleash.UnleashException: Could not fetch toggles
        at no.finn.unleash.repository.HttpToggleFetcher.fetchToggles(HttpToggleFetcher.java:48)
        at no.finn.unleash.repository.FeatureToggleRepository.lambda$updateToggles$0(FeatureToggleRepository.java:43)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.ConnectException: Connection refused: connect
        at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
        at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.net.Socket.connect(Socket.java:589)
        at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
        at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
        at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
        at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
        at sun.net.www.http.HttpClient.New(HttpClient.java:339)
        at sun.net.www.http.HttpClient.New(HttpClient.java:357)
        at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220)
        at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156)
        at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
        at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984)
        at no.finn.unleash.repository.HttpToggleFetcher.fetchToggles(HttpToggleFetcher.java:37)
        ... 8 common frames omitted

When we run web application in cygwin , has windows OS , its creating incorrect windows path with wrong slash using java client SDK

its throwing while creating repo file with /cygwin/ C/x/ff.json , this slash will not work in cygwin

4XX errors does not log anything

The client should log if it gets 400 errors from the server.

  • How noisy should it be on this?
  • Should it mute after a few errors?
  • Should this option be configurable?

Java client never fetches from server

I'm having trouble getting the Java client setup and running. Everything looks fine from the logs when running a simple test.

UnleashConfig config = UnleashConfig.builder()
				.appName("test")
				.instanceId("localhost")
				.unleashAPI("http://localhost:4242/api/")
				.build();
Unleash client = new DefaultUnleash(config);
assertTrue(client.isEnabled("test-feature"));

I'm running client v3.1.2 and server locally v3.1.7. I'm able to connect to the server fine using curl and also while running the node client. Both return expected results. The only logs I can see are

09:56:04.579 [main] INFO  no.finn.unleash.repository.ToggleBackupHandlerFile - Unleash will try to load feature toggle states from temporary backup
09:56:04.579 [main] INFO  no.finn.unleash.repository.ToggleBackupHandlerFile - Unleash will try to load feature toggle states from temporary backup
09:56:04.590 [main] WARN  no.finn.unleash.repository.ToggleBackupHandlerFile -  Unleash could not find the backup-file '/var/folders/nd/1c9btckx64jdxkj94j7dy8400000gn/T//unleash-test-repo.json'. 
This is expected behavior the first time unleash runs in a new environment.
09:56:04.590 [main] WARN  no.finn.unleash.repository.ToggleBackupHandlerFile -  Unleash could not find the backup-file '/var/folders/nd/1c9btckx64jdxkj94j7dy8400000gn/T//unleash-test-repo.json'. 
This is expected behavior the first time unleash runs in a new environment.

When I add a backup file and specify it in the builder then the last 2 log messages disappear however the result is still wrong. When I add the expected feature flag to the backup file then the above test passes so it seems like it's only fetching from the 'local backup' without ever going out to the server.

From the node client I get the following log on the server: New client registered with appName=ben-node-client and instanceId=ben-macbookpro which I never get from the Java client.

Any help would be greatly appreciated! I really like this project and would love to get it running.
Thanks

Critical bug: empty of bogus backup file will crash the client at startup.

How to reproduce:

  1. Make sure /tmp/unleash-repo.json is empty or invalid json.
  2. Run the UnleashUsageTest found the the test directory.

It will crash the unleash with an constructor excpetion (se example)

Suggested solution:
Add an extra catch in ToggleBackupHandlerFile.java to make sure we also handle bogus backup-file.

java.lang.IllegalStateException: Could not extract toggles from json
    at no.finn.unleash.repository.JsonToggleParser.fromJson(JsonToggleParser.java:23)
    at no.finn.unleash.repository.ToggleBackupHandlerFile.read(ToggleBackupHandlerFile.java:29)
    at no.finn.unleash.repository.FeatureToggleRepository.<init>(FeatureToggleRepository.java:42)
    at no.finn.unleash.repository.FeatureToggleRepository.<init>(FeatureToggleRepository.java:35)
    at no.finn.unleash.DefaultUnleash.<init>(DefaultUnleash.java:22)
    at no.finn.unleash.example.UnleashUsageTest.wire(UnleashUsageTest.java:17)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)

Problem with userWithId strategy

I'm putting this here even thought it relates to the Finn client.
There was additional whitespace after an id in the parameter so it didn't match.
We should maybe remove whitespace from the parameters?
This might effect more than just the userWithId strategy.

skjermbilde 2015-03-05 kl 17 07 03

Extend the unleash interface with context-data

In the current version of Unleash strategies needs to get their context data via special provides which typically is implemented as some magic-data available at the current request. This works well in most java-based web-applications.

However doing toggles in a standalone web-application this becomes much harder as you typically do not have a user bound to the current request. In this scenario you will typically have the context-data available runtime, at the same location you want to verify if a toggle should be on or of.

It would thus be beneficial if the client also could inject context data at runtime. The unleash API would then be overloaded with a new method, the the user can inject the required context-data.

unleash.isEnabled("app.someToggle", UnleashConext.of("k1", "v1", "k2", "v2"));

Unleash will then in turn inject the context-data to the strategy which would be extended to:

public interface Strategy {
    String getName();

    boolean isEnabled(Map<String, String> parameters);

    boolean isEnabled(Map<String, String> parameters, UnleashConext context);
}

(* if we move the client to java8 we could also provide a default implementation of the new method to avoid breaking the API)

This is also the approach used for the unleash-client-node.

MetricsBucket is not thread safe (NullpointerException)

We sometimes get this exception:

java.lang.NullPointerException: null
    at no.finn.unleash.metric.MetricsBucket.registerCount(MetricsBucket.java:19)
    at no.finn.unleash.metric.UnleashMetricServiceImpl.count(UnleashMetricServiceImpl.java:43)
    at no.finn.unleash.DefaultUnleash.count(DefaultUnleash.java:138)
    at no.finn.unleash.DefaultUnleash.isEnabled(DefaultUnleash.java:85)

The issue seems to be that MetricsBucket is not thread safe. Changing the code to use a ConcurrentHashMap (using ConcurrentHashMap.computeIfAbsent in MetricsBucket.getOrCreate) would likely fix the problem

Setup release pipeline

Our current release unleash-java-client:0.1-alpha, i did manually on my computer. We should automate the release (with a manual trigger).

Need to decide if we'll setup Travis to do the release build, or maybe FINN.no's internal build system. The release process needs credientials for sonatype repo and a password to unluck a pgp key for signing the artifact. Is it possible have these credentials secured and used by Travis?

Change strategy interface

There have been one request to change the strategy interface and have unleash also inject which feature toggle is being checked now.

The reasoning behind it is to easier support gradual rollout in a such way that one can use the hashcode of the user in combination with the feature toggle. This will allow gradual rollout to be consistent within an toggle (eg. same users will fall within 1% and 5%) but not across different feature toggles. I see no reason to hide this information from the strategy-implementation, and most strategies can just ignore this extra parameter.

The new interface will the be:

public interface Strategy {
    String getName();

    boolean isEnabled(String toggleName, Map<String, String> parameters);
}

This will however be a breaking change, but most of our users have not yet started implementing their own strategies.

The same behavior can be achieved by having an extra config parameter in the strategy-parameters, but is more burdensome to the user.

Any thoughts?

Synchronous call to pull toggles when instantiating the unleash client

Right now it looks like when the unleash client is instantiated a background thread is setup to query the toggles from the server. I am running into an issue where a call to getFeatureToggleNames() is returning an empty list because the call is made too soon after the instantiation of the client and no backup file existed.

Can the instantiation make an synchronous call to update first and then setup the background thread?

Error-msg on first load on new node

If the tmp-backup-file is missing unleash-client fgenerates this warning:

[ WARN] 13:11:09 Unable to locate backup file:'/tmp/unleash-repo.json' []
java.io.FileNotFoundException: /tmp/unleash-repo.json (No such file or directory)
    at java.io.FileInputStream.open(Native Method) ~[?:1.8.0_05]
    at java.io.FileInputStream.<init>(FileInputStream.java:131) ~[?:1.8.0_05]
    at java.io.FileInputStream.<init>(FileInputStream.java:87) ~[?:1.8.0_05]
    at java.io.FileReader.<init>(FileReader.java:58) ~[?:1.8.0_05]
    at no.finn.unleash.repository.BackupFileHandler.read(BackupFileHandler.java:24) [unleash-client-java-1.0-SNAPSHOT.jar:?]
    at no.finn.unleash.repository.FeatureToggleRepository.<init>(FeatureToggleRepository.java:43) [unleash-client-java-1.0-SNAPSHOT.jar:?]
    at no.finn.unleash.repository.FeatureToggleRepository.<init>(FeatureToggleRepository.java:36) [unleash-client-java-1.0-SNAPSHOT.jar:?]
    at no.finn.unleash.DefaultUnleash.<init>(DefaultUnleash.java:20) [unleash-client-java-1.0-SNAPSHOT.jar:?]
    at no.finntech.talent.web.config.ApplicationConfig.unleash(ApplicationConfig.java:103) [classes/:?]
    at no.finntech.talent.web.config.ApplicationConfig$$EnhancerBySpringCGLIB$$c9f14094.CGLIB$unleash$6(<generated>) [spring-core-4.0.2.RELEASE.jar:?]
    at no.finntech.talent.web.config.ApplicationConfig$$EnhancerBySpringCGLIB$$c9f14094$$FastClassBySpringCGLIB$$5e09d657.invoke(<generated>) [spring-core-4.0.2.RELEASE.jar:?]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) [spring-core-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312) [spring-context-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at no.finntech.talent.web.config.ApplicationConfig$$EnhancerBySpringCGLIB$$c9f14094.unleash(<generated>) [spring-core-4.0.2.RELEASE.jar:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_05]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_05]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0_05]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:580) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1014) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:957) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700) [spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760) [spring-context-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) [spring-context-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:658) [spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:530) [spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:484) [spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136) [spring-webmvc-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    at javax.servlet.GenericServlet.init(GenericServlet.java:244) [javax.servlet-api-3.1.0.jar:3.1.0]
    at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:561) [jetty-servlet-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:351) [jetty-servlet-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:840) [jetty-servlet-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:300) [jetty-servlet-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1347) [jetty-webapp-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:745) [jetty-server-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:492) [jetty-webapp-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69) [jetty-util-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:117) [jetty-util-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.server.Server.start(Server.java:355) [jetty-server-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:99) [jetty-util-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60) [jetty-server-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.server.Server.doStart(Server.java:324) [jetty-server-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69) [jetty-util-9.1.2.v20140210.jar:9.1.2.v20140210]
    at no.finntech.talent.web.LocalJettyServer.start(LocalJettyServer.java:64) [test-classes/:?]
    at no.finntech.talent.web.LocalJettyServer.main(LocalJettyServer.java:28) [test-classes/:?]

Strategy for strategies

Unleash has gotten some pull requests to the Finn client and it is good that people want to use the service. I just want to raise a concern.

Right now this version has the following strategies:

  • DefaultStrategy
  • UnknownStrategy

Finn client has the following strategies:

  • ActiveForUserWithIdStrategy
  • BetaUserStrategy
  • ByHostNameStrategy
  • GradualRolloutRandomStrategy
  • RemoteAddrStrategy

Should we not move more of the strategies from the Finn client over to the open source one?

I also suggest that we add a markdown file that describes the strategies with example use cases.

ClientRegistration Event - Suggestions

Small change suggestion.
You may want to change getInterval() to getSendMetricInterval() as this could easily be confused with the fetchTogglesInterval value from the UnleashConfig if the source code isn't examined.

Also, I noticed that the ClientRegistration is pulling a several values from the UnleashConfig. Would it make more sense to instead just store the entire UnleashConfig as an event variable instead of the few selected fields? That way, someone implementing the clientRegistered() method of the UnleashSubscriber can pick/choose which fields are relevant for them to log.

Evaluate Testframework

JUnit is old and boring. Unit testing can be more fun with modern framework such as Spock.

I vote for switching to Spock.

What is your favorite test framework in java?

Proxy support that recognizes -Dhttp.proxy* settings

Hello everyone,

I am currently playing around with the unleash java client. It works really well, I only struggled a little bit with the proxy configuration.

As you use HttpUrlConnection as http client, basic auth proxy settings are not recognized, i.e.:

  • http.proxyUser
  • http.proxyPassword

Therefore, it is necessary to implement a custom java.net.Authenticator. What do you think of providing such an implementation within the library itself? If so, I would try to create a PR for that.

Thank you in advance!

Error fetching toggles from Unleash API (StatusCode: 304)

I have an Unleash server v3.2.1 and java client v3.2.0 on a SpringBoot 2 backend API.

Seems to work well and use the updated value on the backend API but in the console I have this warrning/error every second:

2019-02-18 15:26:20.592  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:21.865  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:22.745  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:23.789  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:23.842  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:24.375  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:25.008  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:26.282  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:26.990  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:27.315  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:27.992  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:28.161  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:29.079  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:29.201  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:30.279  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)
2019-02-18 15:26:30.593  WARN 7514 --- [sh-api-executor] n.f.u.r.FeatureToggleRepository          : Error fetching toggles from Unleash API (StatusCode: 304)

...

Create a unleash-mock-implementation to facilitate unit-testing

To allow users of the unleash-client to perform awesome unit-testing in their own application we must implement a simple UnleashMock client with a simple API.

I'm thinking of something like:

UnleashMock unleash = new UnleashMock();

//enable all feature toggles
unleash.enableAll()

//disable all feature toggles
unleash.disableAll()

//enable specific feature toggle(s)
unleash.enable("featureName")
unleash.enable("featureName", "toggle2", "...")

//disable specific feature toggle(s)
unleash.disable("featureName", "toggle2", "...")

Unable to detect failures in HttpToggleFetcher

The current API of Unleash/HttpToggleFetcher makes it difficult to detect if HttpToggleFetcher is actually able to fetch toggles or if it experiences for example network failures, authentication/authorization failures or simply 404s because because somebody shut down or moved the unleash server.

It would be nice if applications are able to observe such problems through the API.

java client -fail gracefully

copied from Unleash/unleash#15

The client should not stop the application from starting or working if unleash-server is unavailable or acting up.

Enforce defaults for every feature toggle used by the application.

Can we make the API more explicit?

The way unleash is implemented now it is not really intuitive for the developer. Instantiating the unleash-client will also set up a background thread used to poll toggles and send metrics back to unleash. We see from time to time this ending up with memory leakage because the developer creates a new unleash instance per request handler.

Can we make the API more explicit by having dedicated methods for starting and stopping unleash?

  • unleash.startPolling()
  • unleash.destroy()

What should happen if the user has not stated unleash yet? Should we then just throw a runtime exception? Or always return false?

Support for expecific feature change subscriber

Context
Currently I have a system that need some heavy software pieces in the case of a feature is enable. You can image that when the feature is disable I don´t need for example connection to database or Kafka or whatever. Then I am creating a reactive system that create this pieces when the feature turn on and destroy it when turn off.

In order to do that I create a subscriber like this:

@Bean
fun unleash(): Unleash {
    val config = UnleashConfig.builder()
        .appName(application)
        .instanceId(getEnv("HOSTNAME"))
        .unleashAPI(url)
        .subscriber(object : UnleashSubscriber {

            override fun togglesFetched(toggleResponse: FeatureToggleResponse) {
                if (toggleResponse.status == CHANGED) {
                    //create heavy pieces
                }
            }
        })
        .build()
    return DefaultUnleash(config)
}

My problem
My first workaround was try to check the values that interest me form 'togglesFetched' via the
'toggleResponse: FeatureToggleResponse' paramether. The problem is that this class is internal class we can not access to anything.

My seconds workaround is to check the feature value via “isEnabled” or “getVariant”. I need the ‘Unleash’ object (aka the client) inside the subcriber, but I am creating the client.
Can you see the clicle?

Temporal solution
After a talk with @ivarconr we agree follow this approach: We could create your subscriber outside and provide the Unleash instance via a setter.

class MyUnleashSubscriber implements UnleashSubscriber {
    Unleash instance;
    
    public void setInstance(Unleash unleash) {
        instance = unleash;
    }

    @Override
    public void togglesFetched(FeatureToggleResponse toggleResponse) {
        if(toggleResponse.getStatus() == CHANGED) {
            if(instance != null) {
                instance.isEnabled("Demo");
            }
        }
       }
    }

    MyUnleashSubscriber subscriber = new MyUnleashSubscriber();

        UnleashConfig unleashConfig = new UnleashConfig.Builder()
                .appName("java-test")
                .instanceId("instance y")
                .unleashAPI("https://unleash.herokuapp.com/api/")
                .subscriber(subscriber)
                        .build())
                .build();

        Unleash unleash = new DefaultUnleash(unleashConfig);
        subscriber.setInstance(unleash);

Obviously this work but I think that we can improve the support of that situation by the client allowing add subscriber dynamically after the creation or exposing the features values in the subscriber (in a external format of course)

client metrics

copied from Unleash/unleash#21

jarib:
There's currently no way of tracking what toggles are being used across applications. The simplest I can think of is to add easy statsd/graphite reporting in the client.

Perhaps look at Yammer Metrics. From reading the Kafka docs it sounds pretty nice:

Kafka uses Yammer Metrics for metrics reporting in both the server and the client. This can be configured to report stats using pluggable stats reporters to hook up to your monitoring system.

hennings:
Codahale Metrics (successor to Yammer metrics) is a nice library for timing
histograms, counters and gauges. There are several publishers you can plug
in to send the data to graphite, a servlet etc.

Henning
On 21 Oct 2014 15:33, "Jari Bakken" [email protected] wrote:

There's currently no way of tracking what toggles are being used across
applications. The simplest I can think of is to add easy statsd/graphite
reporting to the client.

Perhaps look at Yammer Metrics
https://dropwizard.github.io/metrics/3.1.0/. From reading the Kafka
docs it sounds pretty nice:

Kafka uses Yammer Metrics for metrics reporting in both the server and the
client. This can be configured to report stats using pluggable stats
reporters to hook up to your monitoring system.


Reply to this email directly or view it on GitHub
Unleash/unleash#21.

Local backup json file is not getting updated

Local backup json file is not getting updated when disabled labels in UI, disable /enable the lables in admin GUI , is not reflected in unleash client in multiple AWS ec2 instance, it only picks up the first time settings

Metric Bucket + Client Features Flag list

I noticed no.finn.unleash.metric.MetricsBucket is a non-public class, is that intentional? I was hoping to retrieve the MetricBucket via the UnleashSubscriber.clientMetrics() event to capture a Set of the feature flags the client is checking for. This could be a quick way to identify feature flags that exist (and are being called) in the client, that may not exist on the server yet. Unless there is a better alternative way for the client to know what feature flags exist within the client code base. I know from the Unleash server side, for a given application, I can get a list of Feature flags that have been triggered on the client, but are not defined on the server. I'm trying to do a similar thing, just from the client side.

Improve error messages

When connecting to the unleash-server over http instead of https and the client only receives 301 it will only log 301 and not the new location header. This can make it hard for the use to understand why the client cannot connect to the server.

Publish events

The client should provide a way for users to subscribe on interesting events. Preferably without introducing third party dependencies.

Examples:

  • ready - Unleash client has fetched initial state from unleash-server is able to serve request
  • update - Unleash client got updated toggle configuration from server.
  • error - Unleash client failed fetching data from unleash-server (might want to set some retry limit?).

Plugin Api to registrer custom strategies

It would have been nice with the a possibility to add strategies at runtime. E.g. adding the following addStrategy method:

interface Unlesh{
boolean isEnabled(String toggleName);
boolean isEnabled(String toggleName, boolean defaultSetting);
addStrategy(Strategy strategy);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.