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

Disabling standard rate providers failed #170

Closed
dominik42 opened this issue Aug 24, 2017 · 30 comments
Closed

Disabling standard rate providers failed #170

dominik42 opened this issue Aug 24, 2017 · 30 comments

Comments

@dominik42
Copy link

dominik42 commented Aug 24, 2017

As mentioned at Stackoverflow an issues was filed as JAVAMONEY-131 regarding disabling of the standard rate provider like ECBCurrentRateProvider, ECBHistoric90RateProvider, IMFRateProvider etc. The JIRA page mentioned above isn't available any longer, at github I can't find any regarding issue and with version 1.1 this bug still exists. Here the content of my javamoney.properties

# Turn off loading of the default Moneta ExchangeRateProviders.
{1}load.ECBCurrentRateProvider.type=NEVER
{1}load.ECBHistoric90RateProvider.type=NEVER
{1}load.ECBHistoricRateProvider.type=NEVER
{1}load.IMFRateProvider.type=NEVER
{1}load.AbstractECBRateProvider=NEVER

But somehow the services are started

The exchange rate with resourceId ECBHistoric90RateProvider was started remotely
The exchange rate with resourceId IMFRateProvider was started remotely
The exchange rate with resourceId ECBCurrentRateProvider was started remotely
Loaded ECBCurrentRateProvider exchange rates for days:1
Loaded ECBHistoric90RateProvider exchange rates for days:63
Loaded ECBHistoricRateProvider exchange rates for days:4358

How can I disable all standard provider ?

@dominik42 dominik42 changed the title disabling standard rate providers failed Disabling standard rate providers failed Aug 24, 2017
@keilw keilw added the analysis label Aug 24, 2017
@dominik42
Copy link
Author

any news here ?

@atsticks
Copy link
Member

Not yet, will have a look at it asap. We should get out a maintenance release of the RI asap, so hopefully we can include this issues as well.

@keilw keilw added this to the 1.2 milestone Nov 25, 2017
@fprochazka
Copy link
Contributor

fprochazka commented Feb 6, 2018

To understand the loading system, investigate DefaultLoaderService#registerData(org.javamoney.moneta.spi.LoadDataInformation)

  • the type is "update policy" which means when will the currency rates update (not wheter it loads something or not)
    • The NEVER means to load only local fallback - so you haven't disabled them, you've just forced the loader to never update the data.
    • LAZY does nothing (doesn't even load the local fallback), unless you request the data explicitly
    • SCHEDULED creates a "cron job" that updates regularly
    • ONSTARTUP loads once on startup asynchronously (in another thread)
  • the startRemote option synchronously (blocking the main thread) loads the remote urls
    • this is enabled on several resources by default
    • this is also where the The exchange rate with resourceId ... was started remotely comes from

I was able to achieve disabling them with this config

# Default conversion chain
{1}conversion.default-chain=IDENT,ECB

# Disable loading resources that are not used
{1}load.ECBHistoric90RateProvider.type=LAZY
{1}load.ECBHistoric90RateProvider.startRemote=false
{1}load.ECBHistoricRateProvider.type=LAZY
{1}load.ECBHistoricRateProvider.startRemote=false
{1}load.IMFRateProvider.type=LAZY
{1}load.IMFRateProvider.startRemote=false
{1}load.IMFHistoricRateProvider.type=LAZY
{1}load.IMFHistoricRateProvider.startRemote=false

@dominik42
Copy link
Author

Thanks for this hint. With it, I only see the following logs:
07:59:43.851 [] INFO vert.ECBAbstractRateProvider - Loaded ECBCurrentRateProvider exchange rates for days: 07:59:43.899 [] INFO vert.ECBAbstractRateProvider - Loaded ECBHistoric90RateProvider exchange rates for days:63 07:59:44.747 [] INFO vert.ECBAbstractRateProvider - Loaded ECBHistoricRateProvider exchange rates for days:4358

but no „… start remotely“ any more, fine !
But how can I disable the ‚loading‘ of those rate provider too ?

@fprochazka
Copy link
Contributor

I don't think you can - not easily.

@atsticks
Copy link
Member

Loading of the exchange rate providers is controlled by the service loader logic. The mentioned config AFAIK only is for controlling the loading logic, so loading cannot be switched of as of now.

@atsticks
Copy link
Member

With 1.2 the rate providers come in their own jars, so just avoid loding them, e.g. using Mven excludes, should work fine.

@wderose
Copy link

wderose commented Jun 22, 2019

@atsticks: Thank you for the suggestion to avoid loading unnecessary rate providers at build/assembly time using Maven/SBT.

The issue I face is even if I only use moneta-convert-imf or moneta-convert-ecb both jars contain historic rate providers that I would like to prevent from loading data into memory. My use case only calls for the current providers.

I've tried updating my javamoney.properties file as suggested in this thread but have not been able to prevent the historic providers from loading additional historic fx quotes.

Is there a way to specify the exact providers I'd like start/load in the 1.3 release?

# Default conversion chain
{1}conversion.default-chain=IDENT,IMF,ECB

# Disable loading resources that are not used
{1}load.ECBHistoric90RateProvider.type=LAZY
{1}load.ECBHistoric90RateProvider.startRemote=false

{1}load.ECBHistoricRateProvider.type=LAZY
{1}load.ECBHistoricRateProvider.startRemote=false

{1}load.IMFHistoricRateProvider.type=LAZY
{1}load.IMFHistoricRateProvider.startRemote=false

@thweiss
Copy link

thweiss commented May 11, 2020

I implemented my own ExchangeRateProvider and would like to use the other ones as a fallback in certain test environments of my application with poor data quality.
It would be nice to control this by means of staging the javamoney.properties.

@ayedo
Copy link

ayedo commented Sep 23, 2020

The way this is currently solved is confusing to me: as a user I feel like I have no control over what is happening. Like @wderose I would like to have a single provider with no historic data that loads data once a day. I could not figure out how to do that?

We are using the currency conversions in user web requests, and don't know how do deal with the 20s pauses when JavaMoney downloads some files.

@keilw
Copy link
Member

keilw commented Sep 23, 2020

At least @thweiss mentioned, he created his own, and I know, corporate users like Zalando also do, so it should work now, I don't think they build their own Moneta, just extending it.
Did you try the example @fprochazka gave? It worked for him as well, hence the ticket is closed.
I don't believe it needs to be reopened, but if some of you are happy to contribute to a special example under https://github.com/JavaMoney/javamoney-examples, please feel free to create a ticket, and participate in the example.

There's a conversion example in https://github.com/JavaMoney/javamoney-examples/blob/master/console/javamoney-console-java10/src/main/java/org/javamoney/examples/console/java10/convert/ConversionExample.java (also a Java 8 equivalent) but they only pick between IMF and ECB, not disable one of them or add a new provider.

@ayedo
Copy link

ayedo commented Sep 23, 2020

Thank for your reply. I've tried the solution provided by @fprochazka but it does not work for me. I still get the following in my log:

Loaded ECBHistoricRateProvider exchange rates for days:5562

This is my config:


# Default conversion chain
{1}conversion.default-chain=IDENT,ECB

# Disable loading resources that are not used
{1}load.ECBHistoric90RateProvider.type=LAZY
{1}load.ECBHistoric90RateProvider.startRemote=false
{1}load.ECBHistoricRateProvider.type=LAZY
{1}load.ECBHistoricRateProvider.startRemote=false
{1}load.IMFRateProvider.type=LAZY
{1}load.IMFRateProvider.startRemote=false
{1}load.IMFHistoricRateProvider.type=LAZY
{1}load.IMFHistoricRateProvider.startRemote=false

what am I doing wrong?

@keilw
Copy link
Member

keilw commented Sep 23, 2020

I hope @fprochazka could tell you a little more e.g. where he placed the file (on the classpath I would assume)
If he'd be too busy to respond, I may be able to look into it on Fri or over the weekend, because I have a few days with no client work during the day.

@keilw
Copy link
Member

keilw commented Sep 23, 2020

And feel free to create a ticket for the example because that could help others to understand how to use it.

@ayedo
Copy link

ayedo commented Sep 23, 2020

OK, thanks. No stress.

I can create a ticket, but I'm not sure for what. I don't think there is a bug, but I just can't figure out how to configure my use case.

Does anybody have the same use case as me?

I cannot have JavaMoney download resources while blocking one of our client request for 20 seconds. I want it to download what it needs on startup, and then regularly in an asynchronous fashion. I only need one provider for daily data.

@keilw
Copy link
Member

keilw commented Sep 23, 2020

Yes, e.g. @fprochazka or @dominik42, which is why I think it can't hurt to create a quick and easy example that shows how to do that. Companies like Zalando also did that earlier, so it should work but we had no time to fully document that case and it seems neither did Zalando, maybe they demonstrated it during a MeetUp, but I don't think it was documented in a publicly available space.

@fprochazka
Copy link
Contributor

Well... I've completely changed the strategy for loading exchanges rates, because loading it per-process and holding in memory became a problem for us.

I was forced to introduce several hacks to disable the default loading completely, introduced an abstract database provider, that is then extended for each exchange rate type and also made our own loader, that is executed periodically, that uses the parsing logic from moneta, but once the exchange rates are parsed, it then saves them to database, where the database provider can pick it up.

I was planning on introducing a propper solution for disabling the exchange rate providers and sending a PR, but never got to it, sorry.

@keilw
Copy link
Member

keilw commented Sep 23, 2020

If you still can, we appreciate, does it require a change and custom-build of Moneta right now? I cannot outrule Zalando also does because they are a large company, but the goal (especially for a follow-up JSR) would be to just configure it.

@fprochazka
Copy link
Contributor

I'd love to send a PR that would make this easier, but I can't promise I'll have time in the near future.

@keilw
Copy link
Member

keilw commented Sep 23, 2020

OK no worries, did it work with the mentioned file only or did you have to fork and patch parts of the RI?

@ghost
Copy link

ghost commented Nov 11, 2020

I have the same problem as @ayedo. I overrided javamoney.properties in my SpringBoot application and locally it looks nice. But, when I run it on server, javamoney/properties which is in resources folder is ignoring. I am using version 1.4.2 of javamoney. Any ideas? ;)

@keilw
Copy link
Member

keilw commented Nov 11, 2020

Could you tell us a little more about the server, is it a JavaEE/Jakarta EE server or Spring Framework running in a container?
I cannot say 100% sure, but there were a few issues Anatole got us into 1.4.x trying to do a "Tamaya Light" around properties, I assume it could be related to different class or module paths in an Enterprise container, but that is why we would like to know which containers are affected?

@ghost
Copy link

ghost commented Nov 11, 2020

It is simple SpringBoot (2.2.5) application with Tomcat inside. ;) Should I simply decrease version to 1.3.x?

@keilw
Copy link
Member

keilw commented Nov 11, 2020

As a test or comparison why not. We are preparing 1.4.3 before eventually in the next year there could even be a new JavaMoney spec, but that'll take a little time. Thanks for the observations.
I will not reopen it because I think there is a similar case reported by JBoss a while ago. They never came back to us if it was resolved, but potentially some issues with classloading in Tomcat and Wildfly/JBoss could have the same reason.

@brassier
Copy link

Is there any more insight on this issue? We also have a Spring Boot app (embedded tomcat) and overriding with the javamoney.properties seems to have no effect for us, similar to what's noted above.

@keilw
Copy link
Member

keilw commented Apr 26, 2021

No not that we know of, there are PRs like #347 but they are about different things. The issue was closed and so far @fprochazka did not get a chance to raise a PR for this one.

@brassier
Copy link

brassier commented Apr 26, 2021

Thanks @keilw. I actually confirmed that my spring boot javamoney.properties changes ARE getting picked up. I was being thrown off because the providers continue to be loaded even when disabling them in properties, as noted above.

What is the suggested way to adjust the rate providers that are leveraged if we want current but no historic providers? The javamoney.properties don't seem to actually turn anything off. If we want to stop using the historic providers, is there a way to do that either programmatically in app startup, or with properties updates?

@brassier
Copy link

In case this helps others, I'm using version 1.3 and was seemingly able to stop providers from loading using the NEVER type (as opposed to the LAZY type suggested above. My configuration is below:

{1}load.ECBHistoric90RateProvider.type=NEVER
{1}load.ECBHistoric90RateProvider.startRemote=false
{1}load.ECBHistoricRateProvider.type=NEVER
{1}load.ECBHistoricRateProvider.startRemote=false
{1}load.IMFHistoricRateProvider.type=NEVER
{1}load.IMFHistoricRateProvider.startRemote=false

Additionally, I wanted to load rates at startup AND with the default schedule. I was able to throw something like below into my app startup which fetches rates. Lastly, someone above noted waiting for 20 seconds for rates. Below will help that by pushing it to startup. The root cause of that might be due to this.

            Collection<LoaderService> loaders = Bootstrap.getServices(LoaderService.class);
            for (LoaderService loader : loaders) {
                Set<String> resources = loader.getResourceIds();
                for (String resource : resources) {
                    UpdatePolicy policy = loader.getUpdatePolicy(resource);
                    if (policy != UpdatePolicy.NEVER) {
                        logger.info("Loading Resource: " + resource);
                        loader.loadData(resource);
                    }
                }
            }

@basarito
Copy link

basarito commented Mar 1, 2023

Is there any update on this?

My use case is that I want to disable loading of providers in some tests because it significantly slows down our pipelines.. at the moment it seems impossible to do, but looking at the source code it should be simple enough to do with an additional property in javamoney.properties?

In org.javamoney.moneta.spi.loader.LoaderConfigurator#load method we can just check for a property like load.ECBHistoricRateProvider.enabled=true and skip loading if false?

Like it was mentioned in comments above, setting load.ECBHistoricRateProvider.type=NEVER does nothing because it refers to updating, not loading.

@keilw
Copy link
Member

keilw commented Mar 1, 2023

The only way you can fully disable IMF or ECB is by patching Moneta and disabling the modules you don't like in moneta/pom.xml and moneta-convert/pom.xml.
This is done temporarily in the 1.4.3 snapshot, to separate ECB problems (like #374) from those with IMF (like #353) but in theory if you're willing to build your own Moneta, you could also use that to disable one or both default provicers.
At the moment I'm afraid, there is no other method.
We may revisit that with a 1.5 release or a whole new Money JSR assuming that finds enough support in the JCP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants