Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhance to load mocked properties from apollo.cache-dir #58

Merged
merged 14 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import com.ctrip.framework.apollo.core.dto.ApolloConfigNotification;
import com.ctrip.framework.apollo.core.utils.ResourceUtils;
import com.ctrip.framework.apollo.internals.ConfigServiceLocator;
import com.ctrip.framework.apollo.util.ConfigUtil;
import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
Expand All @@ -33,14 +35,18 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Objects;

public class ApolloTestingServer implements AutoCloseable {

Expand All @@ -51,6 +57,12 @@ public class ApolloTestingServer implements AutoCloseable {
private static Method CONFIG_SERVICE_LOCATOR_CLEAR;
private static ConfigServiceLocator CONFIG_SERVICE_LOCATOR;

private static Method CONFIG_UTIL_LOCATOR_CLEAR;
private static ConfigUtil CONFIG_UTIL_LOCATOR;
cheese8 marked this conversation as resolved.
Show resolved Hide resolved
cheese8 marked this conversation as resolved.
Show resolved Hide resolved

private static Method RESOURCES_UTILS_LOCATOR_CLEAR;
cheese8 marked this conversation as resolved.
Show resolved Hide resolved
private static ResourceUtils RESOURCES_UTILS_LOCATOR;
cheese8 marked this conversation as resolved.
Show resolved Hide resolved

private static final Gson GSON = new Gson();
private final Map<String, Map<String, String>> addedOrModifiedPropertiesOfNamespace = Maps.newConcurrentMap();
private final Map<String, Set<String>> deletedKeysOfNamespace = Maps.newConcurrentMap();
Expand All @@ -67,6 +79,15 @@ public class ApolloTestingServer implements AutoCloseable {
CONFIG_SERVICE_LOCATOR = ApolloInjector.getInstance(ConfigServiceLocator.class);
CONFIG_SERVICE_LOCATOR_CLEAR = ConfigServiceLocator.class.getDeclaredMethod("initConfigServices");
CONFIG_SERVICE_LOCATOR_CLEAR.setAccessible(true);

CONFIG_UTIL_LOCATOR = ApolloInjector.getInstance(ConfigUtil.class);
CONFIG_UTIL_LOCATOR_CLEAR = ConfigUtil.class.getDeclaredMethod("getDefaultLocalCacheDir");
cheese8 marked this conversation as resolved.
Show resolved Hide resolved
CONFIG_UTIL_LOCATOR_CLEAR.setAccessible(true);

RESOURCES_UTILS_LOCATOR = ApolloInjector.getInstance(ResourceUtils.class);
RESOURCES_UTILS_LOCATOR_CLEAR = ResourceUtils.class.getDeclaredMethod("loadConfigFileFromDefaultSearchLocations",
new Class[] {String.class});
RESOURCES_UTILS_LOCATOR_CLEAR.setAccessible(true);
} catch (NoSuchMethodException e) {
logger.error(e.getMessage(), e);
}
Expand Down Expand Up @@ -135,8 +156,7 @@ private void mockConfigServiceUrl(String url) {
}

private String loadConfigFor(String namespace) {
String filename = String.format("mockdata-%s.properties", namespace);
final Properties prop = ResourceUtils.readConfigFile(filename, new Properties());
final Properties prop = loadPropertiesOfNamespace(namespace);
cheese8 marked this conversation as resolved.
Show resolved Hide resolved
Map<String, String> configurations = Maps.newHashMap();
for (String propertyName : prop.stringPropertyNames()) {
configurations.put(propertyName, prop.getProperty(propertyName));
Expand All @@ -148,6 +168,47 @@ private String loadConfigFor(String namespace) {
return GSON.toJson(apolloConfig);
}

private String getDefaultLocalCacheDir() {
Object defaultLocalCacheDir = null;
try {
defaultLocalCacheDir = CONFIG_UTIL_LOCATOR_CLEAR.invoke(CONFIG_UTIL_LOCATOR);
} catch (Exception e) {
logger.error("invoke config util locator clear failed.", e);
}
return (String) defaultLocalCacheDir;
}

private Properties loadPropertiesOfNamespace(String namespace) {
String filename = String.format("mockdata-%s.properties", namespace);
Object mockdataPropertiesExits = null;
try {
mockdataPropertiesExits = RESOURCES_UTILS_LOCATOR_CLEAR.invoke(RESOURCES_UTILS_LOCATOR, filename);
} catch (IllegalAccessException | InvocationTargetException e) {
logger.error("invoke resources util locator clear failed.", e);
}
if (!Objects.isNull(mockdataPropertiesExits)) {
logger.debug("load {} from {}", namespace, filename);
return ResourceUtils.readConfigFile(filename, new Properties());
}
String defaultLocalCacheDir = getDefaultLocalCacheDir();
return loadDefaultLocalCacheDir(namespace, defaultLocalCacheDir);
}

private Properties loadDefaultLocalCacheDir(String namespace, String defaultLocalCacheDir) {
cheese8 marked this conversation as resolved.
Show resolved Hide resolved
Properties prop = new Properties();
String appId = CONFIG_UTIL_LOCATOR.getAppId();
String cluster = CONFIG_UTIL_LOCATOR.getCluster();
String fileName = String.format("%s.properties", Joiner.on("+").join(appId, cluster, namespace));
File file = new File(defaultLocalCacheDir, fileName);
try (FileInputStream fis = new FileInputStream(file)) {
prop.load(fis);
} catch (IOException e) {
logger.error("load {} from {}{} failed.", namespace, defaultLocalCacheDir, fileName);
}
logger.debug("load {} from {}{}", namespace, defaultLocalCacheDir, fileName);
return prop;
}

private String mockLongPollBody(String notificationsStr) {
List<ApolloConfigNotification> oldNotifications = GSON.fromJson(notificationsStr, notificationType);
List<ApolloConfigNotification> newNotifications = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2022 Apollo Authors
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.ctrip.framework.apollo.mockserver;

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService;
import com.ctrip.framework.apollo.core.ApolloClientSystemConsts;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.util.ConfigUtil;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import org.junit.ClassRule;
import org.junit.Test;
import org.springframework.test.util.ReflectionTestUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.nio.file.Files;

import static org.junit.Assert.*;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;

public class ApolloMockServerApiWhileCacheDirSpecifiedTest {

@ClassRule
public static EmbeddedApollo embeddedApollo = new EmbeddedApollo();

@Test
public void testLoadDefaultLocalCacheDir() throws Exception {
String someCacheDir = "src/test/resources/config-cache";
String someAppId = "someAppId";
String someNamespace = "someNamespace";
String someKey = "someKey";
String someValue = "someValue";
System.setProperty(ApolloClientSystemConsts.APOLLO_CACHE_DIR, someCacheDir);

ConfigUtil configUtil = spy(new ConfigUtil());
doReturn(someAppId).when(configUtil).getAppId();
String defaultLocalCacheDir = ReflectionTestUtils.invokeMethod(configUtil, "getDefaultLocalCacheDir", new Object[]{});
assertEquals(someCacheDir + "/" + someAppId, defaultLocalCacheDir);

File someBaseDir = new File(defaultLocalCacheDir);
someBaseDir.mkdirs();
File file = new File(someBaseDir, String.format("%s.properties", Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR).join(
someAppId, "default", someNamespace)));
try (BufferedWriter writer = Files.newBufferedWriter(file.toPath(), Charsets.UTF_8)) {
writer.write(someKey + "=" + someValue);
}
Config config = ConfigService.getConfig(someNamespace);
assertEquals(someValue, config.getProperty(someKey, null));
file.deleteOnExit();
someBaseDir.deleteOnExit();
}
}
Loading