diff --git a/java/google/registry/config/RegistryConfig.java b/java/google/registry/config/RegistryConfig.java index 57babdde7..35ee2898a 100644 --- a/java/google/registry/config/RegistryConfig.java +++ b/java/google/registry/config/RegistryConfig.java @@ -31,6 +31,8 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.net.URI; import java.net.URL; +import java.util.Map; +import java.util.Map.Entry; import javax.annotation.Nullable; import javax.inject.Named; import javax.inject.Qualifier; @@ -736,17 +738,13 @@ public final class RegistryConfig { @Provides @Config("braintreeMerchantAccountIds") public static ImmutableMap provideBraintreeMerchantAccountId( - RegistryEnvironment environment) { - switch (environment) { - case PRODUCTION: - return ImmutableMap.of( - CurrencyUnit.USD, "charlestonregistryUSD", - CurrencyUnit.JPY, "charlestonregistryJPY"); - default: - return ImmutableMap.of( - CurrencyUnit.USD, "google", - CurrencyUnit.JPY, "google-jpy"); + RegistryConfigSettings config) { + Map merchantAccountIds = config.braintree.merchantAccountIdsMap; + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (Entry entry : merchantAccountIds.entrySet()) { + builder.put(CurrencyUnit.of(entry.getKey()), entry.getValue()); } + return builder.build(); } /** @@ -758,14 +756,8 @@ public final class RegistryConfig { */ @Provides @Config("braintreeMerchantId") - public static String provideBraintreeMerchantId(RegistryEnvironment environment) { - switch (environment) { - case PRODUCTION: - return "6gm2mm48k9ty4zmx"; - default: - // Valentine: Nomulus Braintree Sandbox - return "vqgn8khkq2cs6y9s"; - } + public static String provideBraintreeMerchantId(RegistryConfigSettings config) { + return config.braintree.merchantId; } /** @@ -778,14 +770,8 @@ public final class RegistryConfig { */ @Provides @Config("braintreePublicKey") - public static String provideBraintreePublicKey(RegistryEnvironment environment) { - switch (environment) { - case PRODUCTION: - return "tzcfxggzgbh2jg5x"; - default: - // Valentine: Nomulus Braintree Sandbox - return "tzcyzvm3mn7zkdnx"; - } + public static String provideBraintreePublicKey(RegistryConfigSettings config) { + return config.braintree.publicKey; } /** diff --git a/java/google/registry/config/RegistryConfigSettings.java b/java/google/registry/config/RegistryConfigSettings.java index 6a1d4a6c6..c4ef9a245 100644 --- a/java/google/registry/config/RegistryConfigSettings.java +++ b/java/google/registry/config/RegistryConfigSettings.java @@ -15,6 +15,7 @@ package google.registry.config; import java.util.List; +import java.util.Map; /** The POJO that YAML config files are deserialized into. */ public class RegistryConfigSettings { @@ -28,6 +29,7 @@ public class RegistryConfigSettings { public RegistrarConsole registrarConsole; public Monitoring monitoring; public Misc misc; + public Braintree braintree; /** Configuration options that apply to the entire App Engine project. */ public static class AppEngine { @@ -105,4 +107,11 @@ public class RegistryConfigSettings { public static class Misc { public String sheetExportId; } + + /** Configuration for Braintree credit card payment processing. */ + public static class Braintree { + public String merchantId; + public String publicKey; + public Map merchantAccountIdsMap; + } } diff --git a/java/google/registry/config/YamlUtils.java b/java/google/registry/config/YamlUtils.java index 7364364c3..f9af34d1f 100644 --- a/java/google/registry/config/YamlUtils.java +++ b/java/google/registry/config/YamlUtils.java @@ -1,11 +1,11 @@ // Copyright 2017 The Nomulus Authors. All Rights Reserved. -// +// // Licensed 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. @@ -82,7 +82,9 @@ public final class YamlUtils { * override a field that has a Map value in the default YAML with a field of any other type in the * custom YAML. * - *

Only maps are handled recursively; lists are simply overridden in place as-is. + *

Only maps are handled recursively; lists are simply overridden in place as-is, as are maps + * whose name is suffixed with "Map" -- this allows entire maps to be overridden, rather than + * merged. */ static String mergeYaml(String defaultYaml, String customYaml) { Yaml yaml = new Yaml(); @@ -107,19 +109,22 @@ public final class YamlUtils { *

All keys in the default map that are also specified in the custom map are overridden with * the custom map's value. This runs recursively on all contained maps. */ + @SuppressWarnings("unchecked") private static Map mergeMaps( Map defaultMap, Map customMap) { for (String key : defaultMap.keySet()) { if (!customMap.containsKey(key)) { continue; } - Object defaultValue = defaultMap.get(key); - @SuppressWarnings("unchecked") - Object newValue = - (defaultValue instanceof Map) - ? mergeMaps( - (Map) defaultValue, (Map) customMap.get(key)) - : customMap.get(key); + Object newValue; + if (defaultMap.get(key) instanceof Map && !key.endsWith("Map")) { + newValue = + mergeMaps( + (Map) defaultMap.get(key), + (Map) customMap.get(key)); + } else { + newValue = customMap.get(key); + } defaultMap.put(key, newValue); } return defaultMap; diff --git a/java/google/registry/config/default-config.yaml b/java/google/registry/config/default-config.yaml index b5fa93018..f2e092183 100644 --- a/java/google/registry/config/default-config.yaml +++ b/java/google/registry/config/default-config.yaml @@ -132,3 +132,18 @@ misc: # The ID of the Google Sheet (as found in the URL) to export registrar details # to. Leave this null to disable syncing. sheetExportId: null + +# Braintree is a credit card payment processor that is used on the registrar +# console to allow registrars to pay their invoices. +braintree: + # Merchant ID of the Braintree account. + merchantId: example + + # Public key used for accessing Braintree API (this is found on their site). + publicKey: example + + # A map of JODA Money CurrencyUnits, specified in three letter ISO-4217 + # format, to Braintree account IDs (each account is limited to a single + # currency). For example, one entry might be: + # USD: accountIdUsingUSD + merchantAccountIdsMap: {} diff --git a/java/google/registry/config/nomulus-config-production-sample.yaml b/java/google/registry/config/nomulus-config-production-sample.yaml index a0090048a..627d70386 100644 --- a/java/google/registry/config/nomulus-config-production-sample.yaml +++ b/java/google/registry/config/nomulus-config-production-sample.yaml @@ -42,3 +42,13 @@ registrarConsole: misc: sheetExportId: placeholder + +# You only need to specify this section if using Braintree. +braintree: + merchantId: placeholder + publicKey: placeholder + # Only include currencies that you use. + merchantAccountIdsMap: + EUR: placeholder + JPY: placeholder + USD: placeholder diff --git a/java/google/registry/config/unittest-config.yaml b/java/google/registry/config/unittest-config.yaml index 143e69a29..9a55fd1f2 100644 --- a/java/google/registry/config/unittest-config.yaml +++ b/java/google/registry/config/unittest-config.yaml @@ -23,3 +23,8 @@ caching: singletonCacheRefreshSeconds: 0 domainLabelCachingSeconds: 0 singletonCachePersistSeconds: 0 + +braintree: + merchantAccountIdsMap: + USD: accountIdUsd + JPY: accountIdJpy diff --git a/javatests/google/registry/config/YamlUtilsTest.java b/javatests/google/registry/config/YamlUtilsTest.java index 944d4a4d0..51f4e5960 100644 --- a/javatests/google/registry/config/YamlUtilsTest.java +++ b/javatests/google/registry/config/YamlUtilsTest.java @@ -53,7 +53,14 @@ public class YamlUtilsTest { public void testSuccess_mergeEmptyMap_isNoop() { String defaultYaml = join("one: ay", "two: bee", "three: sea"); assertThat(mergeYaml(defaultYaml, "# Just a comment\n")) - .isEqualTo("{one: ay, two: bee, three: sea}\n"); + .isEqualTo("{one: ay, two: bee, three: sea}\n"); + } + + @Test + public void testSuccess_mergeNamedMap_overwritesEntirelyWithNewKey() { + String defaultYaml = join("one: ay", "two: bee", "threeMap:", " foo: bar", " baz: gak"); + assertThat(mergeYaml(defaultYaml, "threeMap: {time: money}")) + .isEqualTo(join("one: ay", "two: bee", "threeMap: {time: money}")); } private static String join(CharSequence... strings) {