mirror of https://github.com/apache/lucene.git
SOLR-3255: OpenExchangeRates.Org Exchange Rate Provider and improved ExchangeRateProvider interface
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1307063 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ea611beacc
commit
e3374c9c9b
|
@ -581,6 +581,8 @@ New Features
|
|||
* SOLR-2202: Currency FieldType, whith support for currencies and exchange rates
|
||||
(Greg Fodor & Andrew Morrison via janhoy, rmuir, Uwe Schindler)
|
||||
|
||||
* SOLR-3255: OpenExchangeRates.Org Exchange Rate Provider for CurrencyField (janhoy)
|
||||
|
||||
* SOLR-3026: eDismax: Locking down which fields can be explicitly queried (user fields aka uf)
|
||||
(janhoy, hossmann, Tomás Fernández Löbbe)
|
||||
|
||||
|
|
|
@ -47,11 +47,11 @@ import javax.xml.xpath.XPathExpressionException;
|
|||
import javax.xml.xpath.XPathFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Currency;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Field type for support of monetary values.
|
||||
|
@ -62,7 +62,7 @@ public class CurrencyField extends FieldType implements SchemaAware, ResourceLoa
|
|||
protected static final String PARAM_DEFAULT_CURRENCY = "defaultCurrency";
|
||||
protected static final String PARAM_RATE_PROVIDER_CLASS = "providerClass";
|
||||
protected static final Object PARAM_PRECISION_STEP = "precisionStep";
|
||||
protected static final String DEFAULT_RATE_PROVIDER_CLASS = "org.apache.solr.schema.FileExchangeRateProvider";
|
||||
protected static final String DEFAULT_RATE_PROVIDER_CLASS = "solr.FileExchangeRateProvider";
|
||||
protected static final String DEFAULT_DEFAULT_CURRENCY = "USD";
|
||||
protected static final String DEFAULT_PRECISION_STEP = "0";
|
||||
protected static final String FIELD_SUFFIX_AMOUNT_RAW = "_amount_raw";
|
||||
|
@ -117,8 +117,7 @@ public class CurrencyField extends FieldType implements SchemaAware, ResourceLoa
|
|||
args.remove(PARAM_PRECISION_STEP);
|
||||
|
||||
try {
|
||||
// TODO: Are we using correct classloader?
|
||||
Class<?> c = Class.forName(exchangeRateProviderClass);
|
||||
Class<?> c = schema.getResourceLoader().findClass(exchangeRateProviderClass);
|
||||
Object clazz = c.newInstance();
|
||||
if (clazz instanceof ExchangeRateProvider) {
|
||||
provider = (ExchangeRateProvider) clazz;
|
||||
|
@ -512,14 +511,15 @@ class FileExchangeRateProvider implements ExchangeRateProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String[] listAvailableCurrencies() {
|
||||
List<String> pairs = new ArrayList<String>();
|
||||
public Set<String> listAvailableCurrencies() {
|
||||
Set<String> currencies = new HashSet<String>();
|
||||
for(String from : rates.keySet()) {
|
||||
currencies.add(from);
|
||||
for(String to : rates.get(from).keySet()) {
|
||||
pairs.add(from+","+to);
|
||||
currencies.add(to);
|
||||
}
|
||||
}
|
||||
return pairs.toArray(new String[1]);
|
||||
return currencies;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,6 +17,7 @@ package org.apache.solr.schema;
|
|||
*/
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.solr.common.ResourceLoader;
|
||||
import org.apache.solr.common.SolrException;
|
||||
|
@ -35,11 +36,10 @@ public interface ExchangeRateProvider {
|
|||
public double getExchangeRate(String sourceCurrencyCode, String targetCurrencyCode) throws SolrException;
|
||||
|
||||
/**
|
||||
* List all configured currency code pairs
|
||||
* @return a string array of <a href="http://en.wikipedia.org/wiki/ISO_4217">ISO 4217</a> currency codes on the format
|
||||
* ["SRC,DST", "SRC,DST"...]
|
||||
* List all configured currency codes which are valid as source/target for this Provider
|
||||
* @return a Set of <a href="http://en.wikipedia.org/wiki/ISO_4217">ISO 4217</a> currency code strings
|
||||
*/
|
||||
public String[] listAvailableCurrencies();
|
||||
public Set<String> listAvailableCurrencies();
|
||||
|
||||
/**
|
||||
* Ask the currency provider to explicitly reload/refresh its configuration.
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
package org.apache.solr.schema;
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.noggit.JSONParser;
|
||||
import org.apache.solr.common.ResourceLoader;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.SolrException.ErrorCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Exchange Rates Provider for {@link CurrencyField} implementing the freely available
|
||||
* exchange rates from openexchangerates.org
|
||||
* <p/>
|
||||
* <b>Disclaimer:</b> This data is collected from various providers and provided free of charge
|
||||
* for informational purposes only, with no guarantee whatsoever of accuracy, validity,
|
||||
* availability or fitness for any purpose; use at your own risk. Other than that - have
|
||||
* fun, and please share/watch/fork if you think data like this should be free!
|
||||
*/
|
||||
public class OpenExchangeRatesOrgProvider implements ExchangeRateProvider {
|
||||
public static Logger log = LoggerFactory.getLogger(OpenExchangeRatesOrgProvider.class);
|
||||
protected static final String PARAM_RATES_FILE_LOCATION = "ratesFileLocation";
|
||||
protected static final String PARAM_REFRESH_INTERVAL = "refreshInterval";
|
||||
protected static final String DEFAULT_RATES_FILE_LOCATION = "http://openexchangerates.org/latest.json";
|
||||
protected static final String DEFAULT_REFRESH_INTERVAL = "1440";
|
||||
|
||||
protected String ratesFileLocation;
|
||||
protected int refreshInterval;
|
||||
protected ResourceLoader resourceLoader;
|
||||
|
||||
protected OpenExchangeRates rates;
|
||||
|
||||
/**
|
||||
* Returns the currently known exchange rate between two currencies. The rates are fetched from
|
||||
* the freely available OpenExchangeRates.org JSON, hourly updated. All rates are symmetrical with
|
||||
* base currency being USD by default.
|
||||
*
|
||||
* @param sourceCurrencyCode The source currency being converted from.
|
||||
* @param targetCurrencyCode The target currency being converted to.
|
||||
* @return The exchange rate.
|
||||
* @throws an exception if the requested currency pair cannot be found
|
||||
*/
|
||||
public double getExchangeRate(String sourceCurrencyCode, String targetCurrencyCode) {
|
||||
if (rates == null) {
|
||||
throw new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE, "Rates not initialized.");
|
||||
}
|
||||
|
||||
if (sourceCurrencyCode == null || targetCurrencyCode == null) {
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Cannot get exchange rate; currency was null.");
|
||||
}
|
||||
|
||||
if (rates.getTimestamp() + refreshInterval*60*1000 > System.currentTimeMillis()) {
|
||||
log.debug("Refresh interval has expired. Refreshing exchange rates.");
|
||||
reload();
|
||||
}
|
||||
|
||||
Double source = (Double) rates.getRates().get(sourceCurrencyCode);
|
||||
Double target = (Double) rates.getRates().get(targetCurrencyCode);
|
||||
|
||||
if (source == null || target == null) {
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
|
||||
"No available conversion rate from " + sourceCurrencyCode + " to " + targetCurrencyCode + ". "
|
||||
+ "Available rates are "+listAvailableCurrencies());
|
||||
}
|
||||
|
||||
return target / source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
OpenExchangeRatesOrgProvider that = (OpenExchangeRatesOrgProvider) o;
|
||||
|
||||
return !(rates != null ? !rates.equals(that.rates) : that.rates != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return rates != null ? rates.hashCode() : 0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "["+this.getClass().getName()+" : " + rates.getRates().size() + " rates.]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> listAvailableCurrencies() {
|
||||
if (rates == null)
|
||||
throw new SolrException(ErrorCode.SERVER_ERROR, "Rates not initialized");
|
||||
return rates.getRates().keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reload() throws SolrException {
|
||||
InputStream ratesJsonStream = null;
|
||||
try {
|
||||
log.info("Reloading exchange rates from "+ratesFileLocation);
|
||||
try {
|
||||
ratesJsonStream = (new URL(ratesFileLocation)).openStream();
|
||||
} catch (Exception e) {
|
||||
ratesJsonStream = resourceLoader.openResource(ratesFileLocation);
|
||||
}
|
||||
|
||||
rates = new OpenExchangeRates(ratesJsonStream);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
throw new SolrException(ErrorCode.SERVER_ERROR, "Error reloading exchange rates", e);
|
||||
} finally {
|
||||
if (ratesJsonStream != null) try {
|
||||
ratesJsonStream.close();
|
||||
} catch (IOException e) {
|
||||
throw new SolrException(ErrorCode.SERVER_ERROR, "Error closing stream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Map<String,String> params) throws SolrException {
|
||||
try {
|
||||
ratesFileLocation = getParam(params.get(PARAM_RATES_FILE_LOCATION), DEFAULT_RATES_FILE_LOCATION);
|
||||
refreshInterval = Integer.parseInt(getParam(params.get(PARAM_REFRESH_INTERVAL), DEFAULT_REFRESH_INTERVAL));
|
||||
// Force a refresh interval of minimum one hour, since the API does not offer better resolution
|
||||
if (refreshInterval < 60) {
|
||||
refreshInterval = 60;
|
||||
log.warn("Specified refreshInterval was too small. Setting to 60 minutes which is the update rate of openexchangerates.org");
|
||||
}
|
||||
log.info("Initialized with rates="+ratesFileLocation+", refreshInterval="+refreshInterval+".");
|
||||
} catch (Exception e) {
|
||||
throw new SolrException(ErrorCode.BAD_REQUEST, "Error initializing", e);
|
||||
} finally {
|
||||
// Removing config params custom to us
|
||||
params.remove(PARAM_RATES_FILE_LOCATION);
|
||||
params.remove(PARAM_REFRESH_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inform(ResourceLoader loader) throws SolrException {
|
||||
resourceLoader = loader;
|
||||
reload();
|
||||
}
|
||||
|
||||
private String getParam(String param, String defaultParam) {
|
||||
return param == null ? defaultParam : param;
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple class encapsulating the JSON data from openexchangerates.org
|
||||
*/
|
||||
class OpenExchangeRates {
|
||||
private Map<String, Double> rates;
|
||||
private String baseCurrency;
|
||||
private long timestamp;
|
||||
private String disclaimer;
|
||||
private String license;
|
||||
private JSONParser parser;
|
||||
|
||||
public OpenExchangeRates(InputStream ratesStream) throws IOException {
|
||||
parser = new JSONParser(new InputStreamReader(ratesStream));
|
||||
rates = new HashMap<String, Double>();
|
||||
|
||||
int ev;
|
||||
do {
|
||||
ev = parser.nextEvent();
|
||||
switch( ev ) {
|
||||
case JSONParser.STRING:
|
||||
if( parser.wasKey() ) {
|
||||
String key = parser.getString();
|
||||
if(key.equals("disclaimer")) {
|
||||
parser.nextEvent();
|
||||
disclaimer = parser.getString();
|
||||
} else if(key.equals("license")) {
|
||||
parser.nextEvent();
|
||||
license = parser.getString();
|
||||
} else if(key.equals("timestamp")) {
|
||||
parser.nextEvent();
|
||||
timestamp = parser.getLong();
|
||||
} else if(key.equals("base")) {
|
||||
parser.nextEvent();
|
||||
baseCurrency = parser.getString();
|
||||
} else if(key.equals("rates")) {
|
||||
ev = parser.nextEvent();
|
||||
assert(ev == JSONParser.OBJECT_START);
|
||||
ev = parser.nextEvent();
|
||||
while (ev != JSONParser.OBJECT_END) {
|
||||
String curr = parser.getString();
|
||||
ev = parser.nextEvent();
|
||||
Double rate = parser.getDouble();
|
||||
rates.put(curr, rate);
|
||||
ev = parser.nextEvent();
|
||||
}
|
||||
} else {
|
||||
log.warn("Unknown key "+key);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
log.warn("Expected key, got "+JSONParser.getEventString(ev));
|
||||
break;
|
||||
}
|
||||
|
||||
case JSONParser.OBJECT_END:
|
||||
case JSONParser.OBJECT_START:
|
||||
break;
|
||||
|
||||
default:
|
||||
log.info("Noggit UNKNOWN_EVENT_ID:"+JSONParser.getEventString(ev));
|
||||
break;
|
||||
}
|
||||
} while( ev != JSONParser.EOF);
|
||||
}
|
||||
|
||||
public Map<String, Double> getRates() {
|
||||
return rates;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public String getDisclaimer() {
|
||||
return disclaimer;
|
||||
}
|
||||
|
||||
public String getBaseCurrency() {
|
||||
return baseCurrency;
|
||||
}
|
||||
|
||||
public String getLicense() {
|
||||
return license;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
{
|
||||
"disclaimer": "This data is collected from various providers and provided free of charge for informational purposes only, with no guarantee whatsoever of accuracy, validity, availability or fitness for any purpose; use at your own risk. Other than that - have fun, and please share/watch/fork if you think data like this should be free!",
|
||||
"license": "Data collected from various providers with public-facing APIs; copyright may apply; not for resale; no warranties given.",
|
||||
"timestamp": 1332070464,
|
||||
"base": "USD",
|
||||
"rates": {
|
||||
"AED": 3.6732,
|
||||
"AFN": 48.299999,
|
||||
"ALL": 105.919998,
|
||||
"AMD": 388.890015,
|
||||
"ANG": 1.79,
|
||||
"AOA": 94.769997,
|
||||
"ARS": 4.35,
|
||||
"AUD": 0.943931,
|
||||
"AWG": 1.7899,
|
||||
"AZN": 0.7863,
|
||||
"BAM": 1.48775,
|
||||
"BBD": 2,
|
||||
"BDT": 82,
|
||||
"BGN": 1.4962,
|
||||
"BHD": 0.37703,
|
||||
"BIF": 1304.170044,
|
||||
"BMD": 1,
|
||||
"BND": 1.2575,
|
||||
"BOB": 6.91,
|
||||
"BRL": 1.8003,
|
||||
"BSD": 1,
|
||||
"BTN": 50.185001,
|
||||
"BWP": 7.2307,
|
||||
"BYR": 8150,
|
||||
"BZD": 1.9135,
|
||||
"CAD": 0.9921,
|
||||
"CDF": 917.276917,
|
||||
"CHF": 0.9164,
|
||||
"CLF": 0.02146,
|
||||
"CLP": 482.75,
|
||||
"CNY": 6.3239,
|
||||
"COP": 1760,
|
||||
"CRC": 507.600006,
|
||||
"CUP": 1,
|
||||
"CVE": 84.190002,
|
||||
"CZK": 18.606001,
|
||||
"DJF": 179.490005,
|
||||
"DKK": 5.64424,
|
||||
"DOP": 39.025002,
|
||||
"DZD": 74.544998,
|
||||
"EGP": 6.0385,
|
||||
"ETB": 17.720449,
|
||||
"EUR": 0.758956,
|
||||
"FJD": 1.7734,
|
||||
"FKP": 0.6316,
|
||||
"GBP": 0.631373,
|
||||
"GEL": 1.6469,
|
||||
"GHS": 1.7455,
|
||||
"GIP": 0.63165,
|
||||
"GMD": 31.5,
|
||||
"GNF": 7100,
|
||||
"GTQ": 7.6975,
|
||||
"GYD": 203.699997,
|
||||
"HKD": 7.76306,
|
||||
"HNL": 19.055,
|
||||
"HRK": 5.7333,
|
||||
"HTG": 41,
|
||||
"HUF": 219.850006,
|
||||
"IDR": 9118,
|
||||
"IEP": 0.5978,
|
||||
"ILS": 3.7542,
|
||||
"INR": 50.165001,
|
||||
"IQD": 1165.5,
|
||||
"IRR": 12308,
|
||||
"ISK": 127.440002,
|
||||
"JMD": 86.699997,
|
||||
"JOD": 0.7095,
|
||||
"JPY": 83.445,
|
||||
"KES": 83.18,
|
||||
"KGS": 46.699402,
|
||||
"KHR": 4010.300049,
|
||||
"KMF": 373.424255,
|
||||
"KPW": 900,
|
||||
"KRW": 1125.849976,
|
||||
"KWD": 0.27925,
|
||||
"KZT": 147.690002,
|
||||
"LAK": 7993.799805,
|
||||
"LBP": 1504,
|
||||
"LKR": 125.224998,
|
||||
"LRD": 73.459999,
|
||||
"LSL": 7.5768,
|
||||
"LTL": 2.6219,
|
||||
"LVL": 0.5291,
|
||||
"LYD": 1.2572,
|
||||
"MAD": 8.4611,
|
||||
"MDL": 11.89,
|
||||
"MGA": 2155,
|
||||
"MKD": 46.705002,
|
||||
"MMK": 6.51,
|
||||
"MNT": 1322.5,
|
||||
"MOP": 7.9958,
|
||||
"MRO": 293,
|
||||
"MUR": 29.110001,
|
||||
"MVR": 15.36,
|
||||
"MWK": 165.206207,
|
||||
"MXN": 12.6745,
|
||||
"MYR": 3.0575,
|
||||
"MZN": 27.200001,
|
||||
"NAD": 7.58,
|
||||
"NGN": 157.600006,
|
||||
"NIO": 23.215,
|
||||
"NOK": 5.73163,
|
||||
"NPR": 80.620003,
|
||||
"NZD": 1.212269,
|
||||
"OMR": 0.38485,
|
||||
"PAB": 1,
|
||||
"PEN": 2.674,
|
||||
"PGK": 2.0627,
|
||||
"PHP": 43.02,
|
||||
"PKR": 90.800003,
|
||||
"PLN": 3.1285,
|
||||
"PYG": 4245,
|
||||
"QAR": 3.6415,
|
||||
"RON": 3.3256,
|
||||
"RSD": 84.100502,
|
||||
"RUB": 29.2342,
|
||||
"RWF": 606.717468,
|
||||
"SAR": 3.7505,
|
||||
"SBD": 7.075973,
|
||||
"SCR": 14.0447,
|
||||
"SDG": 2.6765,
|
||||
"SEK": 6.74525,
|
||||
"SGD": 1.258,
|
||||
"SHP": 0.63165,
|
||||
"SLL": 4364.5,
|
||||
"SOS": 1629,
|
||||
"SRD": 3.2875,
|
||||
"STD": 18650,
|
||||
"SVC": 8.7475,
|
||||
"SYP": 57.450001,
|
||||
"SZL": 7.5752,
|
||||
"THB": 30.700001,
|
||||
"TJS": 4.7588,
|
||||
"TMT": 2.85,
|
||||
"TND": 1.5178,
|
||||
"TOP": 1.693601,
|
||||
"TRY": 1.796,
|
||||
"TTD": 6.40015,
|
||||
"TWD": 29.532,
|
||||
"TZS": 1595,
|
||||
"UAH": 8.029,
|
||||
"UGX": 2481.699951,
|
||||
"USD": 1,
|
||||
"UYU": 19.469999,
|
||||
"UZS": 1835.75,
|
||||
"VEF": 4.295,
|
||||
"VND": 20820,
|
||||
"VUV": 90.199997,
|
||||
"WST": 2.247475,
|
||||
"XAF": 497.898987,
|
||||
"XCD": 2.7,
|
||||
"XDR": 0.652794,
|
||||
"XOF": 498.399994,
|
||||
"XPF": 90.639999,
|
||||
"YER": 216.005005,
|
||||
"ZAR": 7.5688,
|
||||
"ZMK": 5271.5,
|
||||
"ZWD": 378.700012,
|
||||
"ZWL": 322.355011
|
||||
}
|
||||
}
|
|
@ -396,7 +396,10 @@
|
|||
|
||||
<!-- Currency type -->
|
||||
<fieldType name="currency" class="solr.CurrencyField" currencyConfig="currency.xml"/>
|
||||
<fieldType name="mock_currency" class="solr.CurrencyField" providerClass="org.apache.solr.schema.MockExchangeRateProvider" foo="bar" />
|
||||
<fieldType name="mock_currency" class="solr.CurrencyField" providerClass="solr.MockExchangeRateProvider" foo="bar" />
|
||||
<fieldType name="openexchangeratesorg_currency" class="solr.CurrencyField"
|
||||
providerClass="solr.OpenExchangeRatesOrgProvider"
|
||||
ratesFileLocation="open-exchange-rates.json" />
|
||||
|
||||
<!-- some per-field similarity examples -->
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ public abstract class AbstractZkTestCase extends SolrTestCaseJ4 {
|
|||
putConfig(zkClient, "stopwords.txt");
|
||||
putConfig(zkClient, "protwords.txt");
|
||||
putConfig(zkClient, "currency.xml");
|
||||
putConfig(zkClient, "open-exchange-rates.json");
|
||||
putConfig(zkClient, "mapping-ISOLatin1Accent.txt");
|
||||
putConfig(zkClient, "old_synonyms.txt");
|
||||
putConfig(zkClient, "synonyms.txt");
|
||||
|
|
|
@ -23,8 +23,8 @@ import org.junit.BeforeClass;
|
|||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Tests currency field type.
|
||||
|
@ -86,12 +86,26 @@ public class CurrencyFieldTest extends SolrTestCaseJ4 {
|
|||
|
||||
// A few tests on the provider directly
|
||||
ExchangeRateProvider p = ((CurrencyField) tmp).getProvider();
|
||||
String[] available = p.listAvailableCurrencies();
|
||||
assert(available.length == 5);
|
||||
Set<String> availableCurrencies = p.listAvailableCurrencies();
|
||||
assert(availableCurrencies.size() == 4);
|
||||
assert(p.reload() == true);
|
||||
assert(p.getExchangeRate("USD", "EUR") == 2.5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMockExchangeRateProvider() throws Exception {
|
||||
SolrCore core = h.getCore();
|
||||
IndexSchema schema = core.getSchema();
|
||||
SchemaField amount = schema.getField("mock_amount");
|
||||
|
||||
// A few tests on the provider directly
|
||||
ExchangeRateProvider p = ((CurrencyField)amount.getType()).getProvider();
|
||||
Set<String> availableCurrencies = p.listAvailableCurrencies();
|
||||
assert(availableCurrencies.size() == 3);
|
||||
assert(p.reload() == true);
|
||||
assert(p.getExchangeRate("USD", "EUR") == 0.8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCurrencyRangeSearch() throws Exception {
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
|
@ -197,7 +211,7 @@ public class CurrencyFieldTest extends SolrTestCaseJ4 {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testMockExchangeRateProvider() throws Exception {
|
||||
public void testMockFieldType() throws Exception {
|
||||
assertU(adoc("id", "1", "mock_amount", "1.00,USD"));
|
||||
assertU(adoc("id", "2", "mock_amount", "1.00,EUR"));
|
||||
assertU(adoc("id", "3", "mock_amount", "1.00,NOK"));
|
||||
|
|
|
@ -17,7 +17,9 @@ package org.apache.solr.schema;
|
|||
*/
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.solr.common.ResourceLoader;
|
||||
import org.apache.solr.common.SolrException;
|
||||
|
@ -53,8 +55,17 @@ public class MockExchangeRateProvider implements ExchangeRateProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String[] listAvailableCurrencies() {
|
||||
return map.keySet().toArray(new String[1]);
|
||||
public Set<String> listAvailableCurrencies() {
|
||||
Set<String> currenciesPairs = map.keySet();
|
||||
Set<String> returnSet;
|
||||
|
||||
returnSet = new HashSet<String>();
|
||||
for (String c : currenciesPairs) {
|
||||
String[] pairs = c.split(",");
|
||||
returnSet.add(pairs[0]);
|
||||
returnSet.add(pairs[1]);
|
||||
}
|
||||
return returnSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
package org.apache.solr.schema;
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
import org.apache.solr.common.ResourceLoader;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.core.SolrResourceLoader;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Tests currency field type.
|
||||
*/
|
||||
public class OpenExchangeRatesOrgProviderTest extends SolrTestCaseJ4 {
|
||||
OpenExchangeRatesOrgProvider oerp;
|
||||
ResourceLoader loader;
|
||||
private final Map<String,String> emptyParams = new HashMap<String,String>();
|
||||
private Map<String,String> mockParams;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mockParams = new HashMap<String,String>();;
|
||||
mockParams.put(OpenExchangeRatesOrgProvider.PARAM_RATES_FILE_LOCATION, "open-exchange-rates.json");
|
||||
oerp = new OpenExchangeRatesOrgProvider();
|
||||
loader = new SolrResourceLoader("solr");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInit() throws Exception {
|
||||
oerp.init(emptyParams);
|
||||
assertTrue("Wrong default url", oerp.ratesFileLocation.toString().equals("http://openexchangerates.org/latest.json"));
|
||||
assertTrue("Wrong default interval", oerp.refreshInterval == 1440);
|
||||
|
||||
Map<String,String> params = new HashMap<String,String>();
|
||||
params.put(OpenExchangeRatesOrgProvider.PARAM_RATES_FILE_LOCATION, "http://foo.bar/baz");
|
||||
params.put(OpenExchangeRatesOrgProvider.PARAM_REFRESH_INTERVAL, "100");
|
||||
oerp.init(params);
|
||||
assertTrue("Wrong param set url", oerp.ratesFileLocation.equals("http://foo.bar/baz"));
|
||||
assertTrue("Wrong param interval", oerp.refreshInterval == 100);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testList() {
|
||||
oerp.init(mockParams);
|
||||
oerp.inform(loader);
|
||||
assertEquals(159, oerp.listAvailableCurrencies().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetExchangeRate() {
|
||||
oerp.init(mockParams);
|
||||
oerp.inform(loader);
|
||||
assertTrue(5.73163 == oerp.getExchangeRate("USD", "NOK"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReload() {
|
||||
oerp.init(mockParams);
|
||||
oerp.inform(loader);
|
||||
assertTrue(oerp.reload());
|
||||
assertEquals("USD", oerp.rates.getBaseCurrency());
|
||||
assertEquals(new Long(1332070464L), new Long(oerp.rates.getTimestamp()));
|
||||
}
|
||||
|
||||
@Test(expected=SolrException.class)
|
||||
public void testNoInit() {
|
||||
oerp.getExchangeRate("ABC", "DEF");
|
||||
assertTrue("Should have thrown exception if not initialized", false);
|
||||
}
|
||||
}
|
|
@ -459,12 +459,15 @@
|
|||
Parameters:
|
||||
defaultCurrency: Specifies the default currency if none specified. Defaults to "USD"
|
||||
precisionStep: Specifies the precisionStep for the TrieLong field used for the amount
|
||||
providerClass: Lets you plug in other exchange backend. Defaults to FileExchangeRateProvider
|
||||
The FileExchangeRateProvider takes one parameter:
|
||||
providerClass: Lets you plug in other exchange provider backend:
|
||||
solr.FileExchangeRateProvider is the default and takes one parameter:
|
||||
currencyConfig: name of an xml file holding exhange rates
|
||||
solr.OpenExchangeRatesOrgProvider uses rates from openexchangerates.org:
|
||||
ratesFileLocation: URL or path to rates JSON file (default latest.json on the web)
|
||||
refreshInterval: Number of minutes between each rates fetch (default: 1440, min: 60)
|
||||
-->
|
||||
<fieldType name="currency" class="solr.CurrencyField" precisionStep="8" defaultCurrency="USD" currencyConfig="currency.xml" />
|
||||
|
||||
|
||||
<!-- some examples for different languages (generally ordered by ISO code) -->
|
||||
|
||||
<!-- Arabic -->
|
||||
|
|
Loading…
Reference in New Issue