Developing Your Own ExchangeRateProvider for CurrencyField Type

In the previous entry showing how to develop custom Solr functionalities we are showing how to implement your own Solr filter. Today I’ll show you how to implement your own exchange rate provider, so we will implement the  ExchangeRateProvider for the CurrencyField type introduced in Solr 3.6.


In order to show how to implement your own provider for the CurrencyField type, I assume that our application which uses Solr is able to provide exchange rates in the proper form. So, I assume we have a library which provided implementation for the following interface:

package pl.solr;

import java.util.List;

public interface UpToDateCurrencyProvider {
  Map<String, List<Currency>> getExchangeRates();
  void refresh();
  void initialize();

And the Currency class looks like this:

package pl.solr;

public class Currency {
  private String from;
  private String to;
  private double rate;

  public Currency(String from, String to, double rate) {
    this.from = from; = to;
    this.rate = rate;

  public String getFrom() {
    return from;

  public String getTo() {
    return to;

  public double getRate() {
    return rate;

Similar to the previous development entry I’ll omit the details about IDE and jar building. We will focus on the most interesting stuff – the implementation of SolrPLCurrencyExchangeProvider.

SolrPLExchangeRateProvider Implementation

package pl.solr;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.solr.common.ResourceLoader;
import org.apache.solr.common.SolrException;
import org.apache.solr.schema.ExchangeRateProvider;

public class SolrPLCurrencyExchangeProvider implements ExchangeRateProvider {
  private UpToDateCurrencyProvider provider;

  public double getExchangeRate(String sourceCurrencyCode, String targetCurrencyCode) throws SolrException {
    if (sourceCurrencyCode == null || targetCurrencyCode == null) {
      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Cannot get exchange rate - source or target currency was null.");
    List<Currency> exchangesRates = provider.getExchangeRates().get(sourceCurrencyCode);
    if (exchangesRates == null) {
      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Cannot get exchange rate - source currency exchange rates not found");
    Currency exchange = null;
    for (Currency currency : exchangesRates) {
      if (currency.getTo().compareTo(targetCurrencyCode) == 0) {
        exchange = currency;
    if (exchange == null) {
      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Cannot get exchange rate - target currency exchange rates not found");
    return exchange.getRate();

  public void inform(ResourceLoader loader) throws SolrException {
    this.provider = new SolrPLUpToDateCurrencyProvider();

  public void init(Map<String, String> args) {

  public Set<String> listAvailableCurrencies() {
    return provider.getExchangeRates().keySet();

  public boolean reload() throws SolrException {
    return true;

Some Explanations

Some explanations regarding the above code:

  • Linia 11 – we create a class that implements ExchangeRateProvider interface from org.apache.solr.schema package.
  • Linia 12 – our service, which provides exchange rates.
  • Linia 15getExchangeRate method implementation which gets the data from the provided service and returns double value.
  • Linia 19 – get the data regarding the exchange rates. In the production environment we would like to cache this data from some period of time. We don’t do it in the example to simplify the code.
  • Linie 24 – 29 – loop in which we choose the correct Currency object.
  • Linie 30 – 32 – we throw an exception, when proper Currency object wasn’t found.
  • Linie 37 – 41 – we create an instance of our service in the inform method and we initialize it.
  • Linie 48 – 50 – method returning all the available exchange rates.
  • Linie 53 – 56 – method refreshing the provider.


After compilation and jar file preparation, we copy the jar file to a directory where Solr will see it. For example, we can create a lib directory in Solr home directory and then add the following entry to solrconfig.xml file:

<lib dir="../lib/" regex="*.jar" />

We also need to change the schema.xml file and add a type based on solr.CurrencyField, for example:

<fieldType class="solr.CurrencyField" name="currencyField" defaultCurrency="USD" providerClass="pl.solr.SolrPLExchangeRateProvider" />


The main problem with implementing your own ExchangeRateProvider is the data, not the actual implementation as you can see in the above example. I hope that this entry will help some of you and let you save some precious time 😉 Of course, you should remember that this is only an simplified example and we omit the exchange rates cache for example, which should be present in a code you want to use in the production system.

Leave a Reply

Your email address will not be published. Required fields are marked *