Skip to content

Commit

Permalink
Merge pull request #4 from ctripcorp/master
Browse files Browse the repository at this point in the history
Allow repeatable deletions and enhance thread safety (apolloconfig#3069)
  • Loading branch information
Anilople authored May 17, 2020
2 parents 6e4299c + 0478122 commit dcc6eb6
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
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.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
Expand All @@ -38,8 +37,8 @@ public class EmbeddedApollo extends ExternalResource {
private static ConfigServiceLocator CONFIG_SERVICE_LOCATOR;

private final Gson gson = new Gson();
private final Map<String, Map<String, String>> addedOrModifiedPropertiesOfNamespace = new HashMap<>();
private final Map<String, Set<String>> deletedKeysOfNamespace = new HashMap<>();
private final Map<String, Map<String, String>> addedOrModifiedPropertiesOfNamespace = Maps.newConcurrentMap();
private final Map<String, Set<String>> deletedKeysOfNamespace = Maps.newConcurrentMap();

private MockWebServer server;

Expand Down Expand Up @@ -151,7 +150,7 @@ public void addOrModifyProperty(String namespace, String someKey, String someVal
if (addedOrModifiedPropertiesOfNamespace.containsKey(namespace)) {
addedOrModifiedPropertiesOfNamespace.get(namespace).put(someKey, someValue);
} else {
Map<String, String> m = new HashMap<>();
Map<String, String> m = Maps.newConcurrentMap();
m.put(someKey, someValue);
addedOrModifiedPropertiesOfNamespace.put(namespace, m);
}
Expand All @@ -164,7 +163,9 @@ public void deleteProperty(String namespace, String someKey) {
if (deletedKeysOfNamespace.containsKey(namespace)) {
deletedKeysOfNamespace.get(namespace).add(someKey);
} else {
deletedKeysOfNamespace.put(namespace, ImmutableSet.of(someKey));
Set<String> m = Sets.newConcurrentHashSet();
m.add(someKey);
deletedKeysOfNamespace.put(namespace, m);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.ctrip.framework.apollo.mockserver;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.ConfigService;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.google.common.util.concurrent.SettableFuture;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import org.junit.ClassRule;
import org.junit.Test;

Expand Down Expand Up @@ -51,7 +55,79 @@ public void onChange(ConfigChangeEvent changeEvent) {

assertEquals(someNewValue, otherConfig.getProperty("key1", null));
assertEquals("otherValue2", otherConfig.getProperty("key2", null));

assertTrue(changeEvent.isChanged("key1"));
}

@Test
public void testUpdateSamePropertyTwice() throws Exception {
String someNewValue = "someNewValue";

Config otherConfig = ConfigService.getConfig(anotherNamespace);

final Semaphore changes = new Semaphore(0);

otherConfig.addChangeListener(new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
changes.release();
}
});

assertEquals("otherValue3", otherConfig.getProperty("key3", null));

embeddedApollo.addOrModifyProperty(anotherNamespace, "key3", someNewValue);
embeddedApollo.addOrModifyProperty(anotherNamespace, "key3", someNewValue);

assertTrue(changes.tryAcquire(5, TimeUnit.SECONDS));
assertEquals(someNewValue, otherConfig.getProperty("key3", null));
assertEquals(0, changes.availablePermits());
}

@Test
public void testDeleteProperties() throws Exception {
Config otherConfig = ConfigService.getConfig(anotherNamespace);

final SettableFuture<ConfigChangeEvent> future = SettableFuture.create();

otherConfig.addChangeListener(new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
future.set(changeEvent);
}
});

assertEquals("otherValue4", otherConfig.getProperty("key4", null));
assertEquals("otherValue5", otherConfig.getProperty("key5", null));

embeddedApollo.deleteProperty(anotherNamespace, "key4");

ConfigChangeEvent changeEvent = future.get(5, TimeUnit.SECONDS);

assertNull(otherConfig.getProperty("key4", null));
assertEquals("otherValue5", otherConfig.getProperty("key5", null));
assertTrue(changeEvent.isChanged("key4"));
}

@Test
public void testDeleteSamePropertyTwice() throws Exception {
Config otherConfig = ConfigService.getConfig(anotherNamespace);

final Semaphore changes = new Semaphore(0);

otherConfig.addChangeListener(new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
changes.release();
}
});

assertEquals("otherValue6", otherConfig.getProperty("key6", null));

embeddedApollo.deleteProperty(anotherNamespace, "key6");
embeddedApollo.deleteProperty(anotherNamespace, "key6");

assertTrue(changes.tryAcquire(5, TimeUnit.SECONDS));
assertNull(otherConfig.getProperty("key6", null));
assertEquals(0, changes.availablePermits());
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
key1=otherValue1
key2=otherValue2
key3=otherValue3
key4=otherValue4
key5=otherValue5
key6=otherValue6

0 comments on commit dcc6eb6

Please sign in to comment.