Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inject properties #287

Closed
Krasnyanskiy opened this issue Dec 19, 2015 · 12 comments

Comments

@Krasnyanskiy
Copy link

commented Dec 19, 2015

If you're using Spring Framework you can inject a value to any of the components in this way:

@Value("${mongodb.url:127.0.0.1}")
private String mongodbUrl;

It would be great to have the similar property injection in Finatra.

class SomeController @Inject("prop_file#some.key}")(value: String) 
extends Controller {...}
@mosesn

This comment has been minimized.

Copy link
Contributor

commented Dec 19, 2015

@Krasnyanskiy finatra already supports injection via Guice, so is this proposal to do it via spring instead?

@Krasnyanskiy

This comment has been minimized.

Copy link
Author

commented Dec 19, 2015

Hmm... I've tried to inject the value via Guice:

class AssetsController @Inject()(@Named("foo") path: String) extends Controller {...}

In my application.conf file I have the next prop: foo = "Barmaley". But I got this error:

com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for java.lang.String annotated with @com.google.inject.name.Named(value=foo) was bound.
  while locating java.lang.String annotated with @com.google.inject.name.Named(value=foo)
    for parameter 0 at test.finatra.playground.web.controller.AssetsController.<init>(AssetsController.scala:15)
  while locating test.finatra.playground.web.controller.AssetsController

1 error
    at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1004)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1009)
    at com.twitter.inject.Injector.instance(Injector.scala:12)
    at com.twitter.finatra.http.routing.HttpRouter.add(HttpRouter.scala:89)

What did I miss?

@scosenza

This comment has been minimized.

Copy link
Contributor

commented Dec 20, 2015

Use @Flag("flagname")
See http://twitter.github.io/finatra/user-guide/getting-started/#flags

-Steve

On Saturday, December 19, 2015, Sasha notifications@github.com wrote:

Hmm... I've tried to inject the value via Guice:

class AssetsController @Inject()(@nAmed("foo") path: String) extends Controller {...}

In my application.conf file I have the next prop: foo = "Barmaley". But I
got this error:

com.google.inject.ConfigurationException: Guice configuration errors:

  1. No implementation for java.lang.String annotated with @com.google.inject.name.Named(value=foo) was bound.
    while locating java.lang.String annotated with @com.google.inject.name.Named(value=foo)
    for parameter 0 at test.finatra.playground.web.controller.AssetsController.(AssetsController.scala:15)
    while locating test.finatra.playground.web.controller.AssetsController

1 error
at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1004)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1009)
at com.twitter.inject.Injector.instance(Injector.scala:12)
at com.twitter.finatra.http.routing.HttpRouter.add(HttpRouter.scala:89)

What did I miss?


Reply to this email directly or view it on GitHub
#287 (comment).

-Steve

Sent from Gmail Mobile

@Krasnyanskiy

This comment has been minimized.

Copy link
Author

commented Dec 20, 2015

Still get this error:

com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for java.lang.String annotated with @com.twitter.finatra.annotations.Flag(value=foo) was bound.
@scosenza

This comment has been minimized.

Copy link
Contributor

commented Dec 20, 2015

Hi Sasha,

The flag must be defined inside a TwitterModule to use the @Flag
functionality. We'll update the docs to make this more clear.

-Steve

On Sunday, December 20, 2015, Sasha notifications@github.com wrote:

Still get this error:

com.google.inject.ConfigurationException: Guice configuration errors:

  1. No implementation for java.lang.String annotated with @com.twitter.finatra.annotations.Flag(value=foo) was bound.


Reply to this email directly or view it on GitHub
#287 (comment).

-Steve

Sent from Gmail Mobile

@Krasnyanskiy

This comment has been minimized.

Copy link
Author

commented Dec 20, 2015

Thanks.

@fayimora

This comment has been minimized.

Copy link
Contributor

commented Dec 21, 2015

@Krasnyanskiy have a look at the twitter-clone example, specifically the FirebaseModule to see how to handle flags.

@Krasnyanskiy

This comment has been minimized.

Copy link
Author

commented Dec 21, 2015

I added a module:

object PropertyProviderModule extends TwitterModule {
  val _flag = flag("foo", "", "foo")
}

Then I added the module to

override val modules = Seq(PropertyProviderModule)

And now I can use it in my controller (it works fine)

class AssetsController @Inject()(
  @Flag("foo") path: String
) extends Controller {...}

But only if I specify a program argument

-foo "Test"

This is not exactly what I'm looking for. Originally I was trying to get the property value from application.conf and inject it to the controller.

@fayimora

This comment has been minimized.

Copy link
Contributor

commented Dec 21, 2015

Typesafe's config is not explicitly supported in finatra, AFAIK. However, there is a way to do this(there are a few conversations about this on the google group).

  • Add these two dependencies to your build:
"com.github.racc" % "typesafeconfig-guice" % "0.0.2",
"com.typesafe" % "config" % "1.3.0",
import com.github.racc.tscg.TypesafeConfigModule
import com.twitter.inject.{Logging, TwitterModule}
import com.typesafe.config.ConfigFactory

object ConfigModule extends TwitterModule with Logging {
  override def configure() = {
    info("Loading Config file")
    val config = ConfigFactory.load()
    info(s"App Name from Config: ${config.getString("app.name")}")
    install(TypesafeConfigModule.fromConfig(config))
  }
}
  • Add the new module to your list of modules in the server.
override val modules = Seq(ConfigModule)
  • Pass in the config file using JVM arguments like this:
-Dconfig.file=path/to/config/application.conf
  • Inject values form the config
class MyService @Inject()(@TypesafeConfig("db.url") dbUrl: String)  {
  // ......
}
  • Profit!
@Krasnyanskiy

This comment has been minimized.

Copy link
Author

commented Dec 21, 2015

Yahoo! It woks.
@fayimora Thanks for the hint 👍

@fayimora

This comment has been minimized.

Copy link
Contributor

commented Dec 21, 2015

No worries @kramasamy , glad I could help!

@fayimora

This comment has been minimized.

Copy link
Contributor

commented Jun 4, 2016

@Krasnyanskiy did you by any chance build a fat jar with this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
4 participants
You can’t perform that action at this time.