/*
* 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.
*/
package gobblin.config.client;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.mockito.Mockito;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import com.typesafe.config.ConfigValue;
import gobblin.config.client.api.VersionStabilityPolicy;
import gobblin.config.common.impl.SingleLinkedListConfigKeyPath;
import gobblin.config.store.api.ConfigKeyPath;
import gobblin.config.store.api.ConfigStore;
import gobblin.config.store.api.ConfigStoreFactory;
@Test(groups = { "gobblin.config.common.impl" })
public class TestConfigClient {
private ConfigStore mockConfigStore;
private final String version = "V1.0";
private final ConfigKeyPath data = SingleLinkedListConfigKeyPath.ROOT.createChild("data");
private final ConfigKeyPath tag = SingleLinkedListConfigKeyPath.ROOT.createChild("tag");
private final ConfigKeyPath tag2 = SingleLinkedListConfigKeyPath.ROOT.createChild("tag2");
private final ConfigKeyPath databases = data.createChild("databases");
private final ConfigKeyPath identity = databases.createChild("identity");
private final ConfigKeyPath highPriorityTag = tag.createChild("highPriorityTag");
private final ConfigKeyPath espressoTag = tag.createChild("espressoTag");
private final ConfigKeyPath nertzTag2 = tag2.createChild("nertzTag2");
public void printConfig(Config config){
Set<Map.Entry<String,ConfigValue>> entrySet = config.entrySet();
for(Map.Entry<String,ConfigValue> entry: entrySet){
System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}
}
@BeforeClass
public void setup(){
// Topology for mock up config store
// ├── data
// │ └── databases
// │ └── identity
// ├── tag
// │ ├── espressoTag
// │ └── highPriorityTag
// └── tag2
// └── nertzTag2
mockConfigStore = mock(ConfigStore.class, Mockito.RETURNS_SMART_NULLS);
when(mockConfigStore.getCurrentVersion()).thenReturn(version);
List<ConfigKeyPath> emptyList = Collections.emptyList();
// mock up parent/children topology
List<ConfigKeyPath> rootChildren = new ArrayList<ConfigKeyPath>();
rootChildren.add(data);
rootChildren.add(tag);
rootChildren.add(tag2);
when(mockConfigStore.getChildren(SingleLinkedListConfigKeyPath.ROOT, version)).thenReturn(rootChildren);
List<ConfigKeyPath> dataChildren = new ArrayList<ConfigKeyPath>();
dataChildren.add(databases);
when(mockConfigStore.getChildren(data, version)).thenReturn(dataChildren);
List<ConfigKeyPath> databasesChildren = new ArrayList<ConfigKeyPath>();
databasesChildren.add(identity);
when(mockConfigStore.getChildren(databases, version)).thenReturn(databasesChildren);
when(mockConfigStore.getChildren(identity, version)).thenReturn(emptyList);
List<ConfigKeyPath> tagChildren = new ArrayList<ConfigKeyPath>();
tagChildren.add(highPriorityTag);
tagChildren.add(espressoTag);
when(mockConfigStore.getChildren(tag, version)).thenReturn(tagChildren);
when(mockConfigStore.getChildren(highPriorityTag, version)).thenReturn(emptyList);
when(mockConfigStore.getChildren(espressoTag, version)).thenReturn(emptyList);
List<ConfigKeyPath> tag2Children = new ArrayList<ConfigKeyPath>();
tag2Children.add(nertzTag2);
when(mockConfigStore.getChildren(tag2, version)).thenReturn(tag2Children);
when(mockConfigStore.getChildren(nertzTag2, version)).thenReturn(emptyList);
// mock up import links
// identity import espressoTag and highPriorityTag
List<ConfigKeyPath> identityImports = new ArrayList<ConfigKeyPath>();
identityImports.add(espressoTag);
identityImports.add(highPriorityTag);
when(mockConfigStore.getOwnImports(identity, version)).thenReturn(identityImports);
// espressoTag imports nertzTag2
List<ConfigKeyPath> espressoImports = new ArrayList<ConfigKeyPath>();
espressoImports.add(nertzTag2);
when(mockConfigStore.getOwnImports(espressoTag, version)).thenReturn(espressoImports);
mockupConfigValues();
}
private void mockupConfigValues(){
/**
* each node will have a common key "generalKey" with value as "generalValue_${node}"
* this key will be overwrite
*
* each node will have own key "keyOf_${node}" with value "valueOf_${node}"
* this key will be inherent
*/
// mock up the configuration values for root
Map<String, String> rootMap = new HashMap<>();
rootMap.put("keyOf_Root", "valueOf_Root");
rootMap.put("generalKey", "generalValue_root"); // keys will be overwrite
when(mockConfigStore.getOwnConfig(SingleLinkedListConfigKeyPath.ROOT, version)).thenReturn(ConfigFactory.parseMap(rootMap));
// mock up the configuration values for /data
Map<String, String> dataMap = new HashMap<>();
dataMap.put("keyOf_data", "valueOf_data");
dataMap.put("generalKey", "generalValue_data");
when(mockConfigStore.getOwnConfig(data, version)).thenReturn(ConfigFactory.parseMap(dataMap));
// mock up the configuration values for /data/databases
Map<String, String> databasesMap = new HashMap<>();
databasesMap.put("keyOf_databases", "valueOf_databases");
databasesMap.put("generalKey", "generalValue_data_databases");
when(mockConfigStore.getOwnConfig(databases, version)).thenReturn(ConfigFactory.parseMap(databasesMap));
// mock up the configuration values for /data/databases/identity
Map<String, String> identityMap = new HashMap<>();
identityMap.put("keyOf_identity", "valueOf_identity");
identityMap.put("generalKey", "generalValue_data_databases_identity");
when(mockConfigStore.getOwnConfig(identity, version)).thenReturn(ConfigFactory.parseMap(identityMap));
// mock up the configuration values for /tag
Map<String, String> tagMap = new HashMap<>();
tagMap.put("keyOf_tag", "valueOf_tag");
tagMap.put("generalKey", "generalValue_tag");
when(mockConfigStore.getOwnConfig(tag, version)).thenReturn(ConfigFactory.parseMap(tagMap));
// mock up the configuration values for /tag/espressoTag
Map<String, String> espressoTagMap = new HashMap<>();
espressoTagMap.put("keyOf_espressoTag", "valueOf_espressoTag");
espressoTagMap.put("generalKey", "generalValue_tag_espressoTag");
when(mockConfigStore.getOwnConfig(espressoTag, version)).thenReturn(ConfigFactory.parseMap(espressoTagMap));
// mock up the configuration values for /tag/highPriorityTag
Map<String, String> highPriorityTagMap = new HashMap<>();
highPriorityTagMap.put("keyOf_highPriorityTag", "valueOf_highPriorityTag");
highPriorityTagMap.put("generalKey", "generalValue_tag_highPriorityTag");
when(mockConfigStore.getOwnConfig(highPriorityTag, version)).thenReturn(ConfigFactory.parseMap(highPriorityTagMap));
// mock up the configuration values for /tag2
Map<String, String> tag2Map = new HashMap<>();
tag2Map.put("keyOf_tag2", "valueOf_tag2");
tag2Map.put("generalKey", "generalValue_tag2");
when(mockConfigStore.getOwnConfig(tag2, version)).thenReturn(ConfigFactory.parseMap(tag2Map));
// mock up the configuration values for /tag2/nertzTag2
Map<String, String> nertzTag2Map = new HashMap<>();
nertzTag2Map.put("keyOf_nertzTag2", "valueOf_nertzTag2");
nertzTag2Map.put("generalKey", "generalValue_tag2_nertzTag2");
when(mockConfigStore.getOwnConfig(nertzTag2, version)).thenReturn(ConfigFactory.parseMap(nertzTag2Map));
}
private void checkValuesForIdentity(Config resolvedConfig){
Assert.assertTrue(resolvedConfig.getString("keyOf_data").equals("valueOf_data"));
Assert.assertTrue(resolvedConfig.getString("keyOf_identity").equals("valueOf_identity"));
Assert.assertTrue(resolvedConfig.getString("keyOf_espressoTag").equals("valueOf_espressoTag"));
Assert.assertTrue(resolvedConfig.getString("keyOf_Root").equals("valueOf_Root"));
Assert.assertTrue(resolvedConfig.getString("keyOf_nertzTag2").equals("valueOf_nertzTag2"));
Assert.assertTrue(resolvedConfig.getString("keyOf_highPriorityTag").equals("valueOf_highPriorityTag"));
Assert.assertTrue(resolvedConfig.getString("keyOf_tag2").equals("valueOf_tag2"));
Assert.assertTrue(resolvedConfig.getString("keyOf_tag").equals("valueOf_tag"));
Assert.assertTrue(resolvedConfig.getString("keyOf_databases").equals("valueOf_databases"));
Assert.assertTrue(resolvedConfig.getString("generalKey").equals("generalValue_data_databases_identity"));
}
@Test
private void testFromClient() throws Exception{
ConfigStoreFactoryRegister mockConfigStoreFactoryRegister;
ConfigStoreFactory mockConfigStoreFactory;
URI relativeURI = new URI("etl-hdfs:///data/databases/identity");
URI absoluteURI = new URI("etl-hdfs://eat1-nertznn01.grid.linkedin.com:9000/user/mitu/HdfsBasedConfigTest/data/databases/identity");
when(mockConfigStore.getStoreURI()).thenReturn(new URI("etl-hdfs://eat1-nertznn01.grid.linkedin.com:9000/user/mitu/HdfsBasedConfigTest"));
mockConfigStoreFactory = mock(ConfigStoreFactory.class, Mockito.RETURNS_SMART_NULLS);
when(mockConfigStoreFactory.getScheme()).thenReturn("etl-hdfs");
when(mockConfigStoreFactory.createConfigStore(absoluteURI)).thenReturn(mockConfigStore);
when(mockConfigStoreFactory.createConfigStore(relativeURI)).thenReturn(mockConfigStore);
mockConfigStoreFactoryRegister = mock(ConfigStoreFactoryRegister.class, Mockito.RETURNS_SMART_NULLS);
when(mockConfigStoreFactoryRegister.getConfigStoreFactory("etl-hdfs")).thenReturn(mockConfigStoreFactory);
ConfigClient client = new ConfigClient(VersionStabilityPolicy.STRONG_LOCAL_STABILITY, mockConfigStoreFactoryRegister);
Config resolved = client.getConfig(relativeURI);
checkValuesForIdentity(resolved);
resolved = client.getConfig(absoluteURI);
checkValuesForIdentity(resolved);
// importedBy using relative URI
String[] expectedImportedBy = {"etl-hdfs:/tag/espressoTag", "etl-hdfs:/data/databases/identity"};
URI nertzTagURI = new URI("etl-hdfs:///tag2/nertzTag2");
Collection<URI> importedBy = client.getImportedBy(nertzTagURI, false);
Assert.assertEquals(importedBy.size(), 1);
Assert.assertEquals(importedBy.iterator().next().toString(), expectedImportedBy[0]);
importedBy = client.getImportedBy(nertzTagURI, true);
Assert.assertEquals(importedBy.size(), 2);
for(URI u: importedBy){
Assert.assertTrue(u.toString().equals(expectedImportedBy[0]) ||
u.toString().equals(expectedImportedBy[1]));
}
// importedBy using abs URI
String[] expectedImportedBy_abs = {"etl-hdfs://eat1-nertznn01.grid.linkedin.com:9000/user/mitu/HdfsBasedConfigTest/tag/espressoTag",
"etl-hdfs://eat1-nertznn01.grid.linkedin.com:9000/user/mitu/HdfsBasedConfigTest/data/databases/identity"};
nertzTagURI = new URI("etl-hdfs://eat1-nertznn01.grid.linkedin.com:9000/user/mitu/HdfsBasedConfigTest/tag2/nertzTag2");
importedBy = client.getImportedBy(nertzTagURI, false);
Assert.assertEquals(importedBy.size(), 1);
Assert.assertEquals(importedBy.iterator().next().toString(), expectedImportedBy_abs[0]);
importedBy = client.getImportedBy(nertzTagURI, true);
Assert.assertEquals(importedBy.size(), 2);
for(URI u: importedBy){
Assert.assertTrue(u.toString().equals(expectedImportedBy_abs[0]) ||
u.toString().equals(expectedImportedBy_abs[1]));
}
}
}