blob: c005f37a3527d7648819fa26219d8a7198dd49f0 [file] [log] [blame]
/*
* 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 org.apache.samza.util;
import java.util.HashMap;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import org.apache.samza.SamzaException;
import org.apache.samza.config.Config;
import org.apache.samza.config.ConfigException;
import org.apache.samza.config.ConfigRewriter;
import org.apache.samza.config.JobConfig;
import org.apache.samza.config.MapConfig;
import org.apache.samza.config.loaders.PropertiesConfigLoaderFactory;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class TestConfigUtil {
private static final String CONFIG_KEY = "config.key";
private static final String CONFIG_VALUE = "value";
private static final String NEW_CONFIG_KEY = "new.rewritten.config.key";
private static final String REWRITER_NAME = "propertyRewriter";
private static final String OTHER_REWRITER_NAME = "otherPropertyRewriter";
@Test
public void testRewriteConfig() {
Map<String, String> baseConfigMap = ImmutableMap.of(CONFIG_KEY, CONFIG_VALUE);
// no rewriters
Map<String, String> fullConfig = new HashMap<>(baseConfigMap);
assertEquals(fullConfig, ConfigUtil.rewriteConfig(new MapConfig(fullConfig)));
// rewriter that adds property
fullConfig = new HashMap<>(baseConfigMap);
fullConfig.put(JobConfig.CONFIG_REWRITERS, REWRITER_NAME);
fullConfig.put(String.format(JobConfig.CONFIG_REWRITER_CLASS, REWRITER_NAME), NewPropertyRewriter.class.getName());
Map<String, String> expectedConfigMap = new HashMap<>(fullConfig);
expectedConfigMap.put(NEW_CONFIG_KEY, CONFIG_VALUE);
assertEquals(new MapConfig(expectedConfigMap), ConfigUtil.rewriteConfig(new MapConfig(fullConfig)));
// rewriter that updates property
fullConfig = new HashMap<>(baseConfigMap);
fullConfig.put(JobConfig.CONFIG_REWRITERS, REWRITER_NAME);
fullConfig.put(String.format(JobConfig.CONFIG_REWRITER_CLASS, REWRITER_NAME),
UpdatePropertyRewriter.class.getName());
expectedConfigMap = new HashMap<>(fullConfig);
expectedConfigMap.put(CONFIG_KEY, CONFIG_VALUE + CONFIG_VALUE);
assertEquals(new MapConfig(expectedConfigMap), ConfigUtil.rewriteConfig(new MapConfig(fullConfig)));
// rewriter that removes property
fullConfig = new HashMap<>(baseConfigMap);
fullConfig.put(JobConfig.CONFIG_REWRITERS, REWRITER_NAME);
fullConfig.put(String.format(JobConfig.CONFIG_REWRITER_CLASS, REWRITER_NAME),
DeletePropertyRewriter.class.getName());
expectedConfigMap = new HashMap<>(fullConfig);
expectedConfigMap.remove(CONFIG_KEY);
assertEquals(new MapConfig(expectedConfigMap), ConfigUtil.rewriteConfig(new MapConfig(fullConfig)));
// only apply rewriters from rewriters list
fullConfig = new HashMap<>(baseConfigMap);
fullConfig.put(JobConfig.CONFIG_REWRITERS, OTHER_REWRITER_NAME);
fullConfig.put(String.format(JobConfig.CONFIG_REWRITER_CLASS, REWRITER_NAME), NewPropertyRewriter.class.getName());
fullConfig.put(String.format(JobConfig.CONFIG_REWRITER_CLASS, OTHER_REWRITER_NAME),
UpdatePropertyRewriter.class.getName());
expectedConfigMap = new HashMap<>(fullConfig);
expectedConfigMap.put(CONFIG_KEY, CONFIG_VALUE + CONFIG_VALUE);
assertEquals(new MapConfig(expectedConfigMap), ConfigUtil.rewriteConfig(new MapConfig(fullConfig)));
// two rewriters; second rewriter overwrites configs from first
fullConfig = new HashMap<>(baseConfigMap);
fullConfig.put(JobConfig.CONFIG_REWRITERS, REWRITER_NAME + "," + OTHER_REWRITER_NAME);
fullConfig.put(String.format(JobConfig.CONFIG_REWRITER_CLASS, REWRITER_NAME), NewPropertyRewriter.class.getName());
fullConfig.put(String.format(JobConfig.CONFIG_REWRITER_CLASS, OTHER_REWRITER_NAME),
UpdatePropertyRewriter.class.getName());
expectedConfigMap = new HashMap<>(fullConfig);
expectedConfigMap.put(NEW_CONFIG_KEY, CONFIG_VALUE + CONFIG_VALUE);
assertEquals(new MapConfig(expectedConfigMap), ConfigUtil.rewriteConfig(new MapConfig(fullConfig)));
}
/**
* This fails because Util will interpret the empty string value as a single rewriter which has the empty string as a
* name, and there is no rewriter class config for a rewriter name which is the empty string.
* TODO: should this be fixed to interpret the empty string as an empty list?
*/
@Test(expected = SamzaException.class)
public void testRewriteConfigConfigRewritersEmptyString() {
Config config = new MapConfig(ImmutableMap.of(JobConfig.CONFIG_REWRITERS, ""));
ConfigUtil.rewriteConfig(config);
}
@Test(expected = SamzaException.class)
public void testRewriteConfigNoClassForConfigRewriterName() {
Config config =
new MapConfig(ImmutableMap.of(CONFIG_KEY, CONFIG_VALUE, JobConfig.CONFIG_REWRITERS, "unknownRewriter"));
ConfigUtil.rewriteConfig(config);
}
@Test(expected = SamzaException.class)
public void testRewriteConfigRewriterClassDoesNotExist() {
Config config = new MapConfig(ImmutableMap.of(CONFIG_KEY, CONFIG_VALUE, JobConfig.CONFIG_REWRITERS, REWRITER_NAME,
String.format(JobConfig.CONFIG_REWRITER_CLASS, REWRITER_NAME), "not_a_class"));
ConfigUtil.rewriteConfig(config);
}
@Test
public void testApplyRewriter() {
// new property
Map<String, String> fullConfig =
ImmutableMap.of(CONFIG_KEY, CONFIG_VALUE, String.format(JobConfig.CONFIG_REWRITER_CLASS, REWRITER_NAME),
NewPropertyRewriter.class.getName());
Map<String, String> expectedConfigMap = new HashMap<>(fullConfig);
expectedConfigMap.put(NEW_CONFIG_KEY, CONFIG_VALUE);
assertEquals(new MapConfig(expectedConfigMap), ConfigUtil.applyRewriter(new MapConfig(fullConfig), REWRITER_NAME));
// update property
fullConfig =
ImmutableMap.of(CONFIG_KEY, CONFIG_VALUE, String.format(JobConfig.CONFIG_REWRITER_CLASS, REWRITER_NAME),
UpdatePropertyRewriter.class.getName());
expectedConfigMap = new HashMap<>(fullConfig);
expectedConfigMap.put(CONFIG_KEY, CONFIG_VALUE + CONFIG_VALUE);
assertEquals(new MapConfig(expectedConfigMap), ConfigUtil.applyRewriter(new MapConfig(fullConfig), REWRITER_NAME));
// remove property
fullConfig =
ImmutableMap.of(CONFIG_KEY, CONFIG_VALUE, String.format(JobConfig.CONFIG_REWRITER_CLASS, REWRITER_NAME),
DeletePropertyRewriter.class.getName());
expectedConfigMap = new HashMap<>(fullConfig);
expectedConfigMap.remove(CONFIG_KEY);
assertEquals(new MapConfig(expectedConfigMap), ConfigUtil.applyRewriter(new MapConfig(fullConfig), REWRITER_NAME));
}
@Test(expected = SamzaException.class)
public void testApplyRewriterNoClassForConfigRewriterName() {
Map<String, String> fullConfig = ImmutableMap.of(CONFIG_KEY, CONFIG_VALUE);
ConfigUtil.applyRewriter(new MapConfig(fullConfig), REWRITER_NAME);
}
@Test(expected = SamzaException.class)
public void testApplyRewriterClassDoesNotExist() {
Map<String, String> fullConfig =
ImmutableMap.of(CONFIG_KEY, CONFIG_VALUE, String.format(JobConfig.CONFIG_REWRITER_CLASS, REWRITER_NAME),
"not_a_class");
Config expectedConfig = new MapConfig(ImmutableMap.of(CONFIG_KEY, CONFIG_VALUE, NEW_CONFIG_KEY, CONFIG_VALUE));
assertEquals(expectedConfig, ConfigUtil.applyRewriter(new MapConfig(fullConfig), REWRITER_NAME));
}
@Test(expected = ConfigException.class)
public void testLoadConfigWithoutLoader() {
Map<String, String> config = new HashMap<>();
config.put(JobConfig.JOB_NAME, "new-test-job");
ConfigUtil.loadConfig(new MapConfig(config));
}
@Test
public void testLoadConfigWithOverridesAndRewrites() {
Map<String, String> config = new HashMap<>();
config.put(JobConfig.CONFIG_LOADER_FACTORY, PropertiesConfigLoaderFactory.class.getCanonicalName());
config.put(JobConfig.JOB_NAME, "new-test-job");
config.put(JobConfig.CONFIG_REWRITERS, REWRITER_NAME);
config.put(CONFIG_KEY, CONFIG_VALUE);
config.put(String.format(JobConfig.CONFIG_REWRITER_CLASS, REWRITER_NAME), NewPropertyRewriter.class.getName());
config.put(PropertiesConfigLoaderFactory.CONFIG_LOADER_PROPERTIES_PREFIX + "path", getClass().getResource("/test.properties").getPath());
Config actual = ConfigUtil.loadConfig(new MapConfig(config));
assertEquals("org.apache.samza.job.MockJobFactory", actual.get("job.factory.class"));
assertEquals("bar", actual.get("foo"));
// overridden value
assertEquals("new-test-job", actual.get("job.name"));
// rewritten value
assertEquals(CONFIG_VALUE, actual.get(NEW_CONFIG_KEY));
}
/**
* Adds a new config entry for the key {@link #NEW_CONFIG_KEY} which has the same value as {@link #CONFIG_KEY}.
*/
public static class NewPropertyRewriter implements ConfigRewriter {
@Override
public Config rewrite(String name, Config config) {
ImmutableMap.Builder<String, String> newConfigMapBuilder = new ImmutableMap.Builder<>();
newConfigMapBuilder.putAll(config);
newConfigMapBuilder.put(NEW_CONFIG_KEY, config.get(CONFIG_KEY));
return new MapConfig(newConfigMapBuilder.build());
}
}
/**
* If an entry at {@link #NEW_CONFIG_KEY} exists, overwrites it to be the value concatenated with itself. Otherwise,
* updates the entry at {@link #CONFIG_KEY} to be the value concatenated to itself.
*/
public static class UpdatePropertyRewriter implements ConfigRewriter {
@Override
public Config rewrite(String name, Config config) {
Map<String, String> newConfigMap = new HashMap<>(config);
if (config.containsKey(NEW_CONFIG_KEY)) {
// for testing overwriting of new configs
newConfigMap.put(NEW_CONFIG_KEY, config.get(NEW_CONFIG_KEY) + config.get(NEW_CONFIG_KEY));
} else {
newConfigMap.put(CONFIG_KEY, config.get(CONFIG_KEY) + config.get(CONFIG_KEY));
}
return new MapConfig(newConfigMap);
}
}
/**
* Removes config entry for the key {@link #CONFIG_KEY} and {@link #NEW_CONFIG_KEY}.
*/
public static class DeletePropertyRewriter implements ConfigRewriter {
@Override
public Config rewrite(String name, Config config) {
Map<String, String> newConfigMap = new HashMap<>(config);
newConfigMap.remove(CONFIG_KEY);
return new MapConfig(newConfigMap);
}
}
}