-
Notifications
You must be signed in to change notification settings - Fork 122
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added abstract RefreshableServiceProviderPlace
- Loading branch information
Showing
4 changed files
with
225 additions
and
119 deletions.
There are no files selected for viewing
126 changes: 126 additions & 0 deletions
126
src/main/java/emissary/place/RefreshableServiceProviderPlace.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package emissary.place; | ||
|
||
import emissary.config.ConfigUtil; | ||
import emissary.config.Configurator; | ||
|
||
import org.apache.commons.collections4.CollectionUtils; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.List; | ||
import java.util.concurrent.atomic.AtomicBoolean; | ||
import javax.annotation.Nullable; | ||
|
||
/** | ||
* | ||
*/ | ||
public abstract class RefreshableServiceProviderPlace extends ServiceProviderPlace { | ||
|
||
private final AtomicBoolean invalid = new AtomicBoolean(false); | ||
|
||
public RefreshableServiceProviderPlace() throws IOException {} | ||
|
||
public RefreshableServiceProviderPlace(final String thePlaceLocation) throws IOException { | ||
super(thePlaceLocation); | ||
} | ||
|
||
protected RefreshableServiceProviderPlace(final String configFile, @Nullable final String theDir, final String thePlaceLocation) | ||
throws IOException { | ||
super(configFile, theDir, thePlaceLocation); | ||
} | ||
|
||
protected RefreshableServiceProviderPlace(final InputStream configStream, @Nullable final String theDir, final String thePlaceLocation) | ||
throws IOException { | ||
super(configStream, theDir, thePlaceLocation); | ||
} | ||
|
||
protected RefreshableServiceProviderPlace(final InputStream configStream) throws IOException { | ||
super(configStream); | ||
} | ||
|
||
protected RefreshableServiceProviderPlace(final String configFile, final String placeLocation) throws IOException { | ||
super(configFile, placeLocation); | ||
} | ||
|
||
protected RefreshableServiceProviderPlace(final InputStream configStream, final String placeLocation) throws IOException { | ||
super(configStream, placeLocation); | ||
} | ||
|
||
public boolean isInvalid() { | ||
return this.invalid.get(); | ||
} | ||
|
||
public void invalidate() { | ||
this.invalid.set(true); | ||
} | ||
|
||
/** | ||
* Reinitialize the place by reloading the configurator and reconfiguring the place | ||
*/ | ||
public synchronized void refresh() { | ||
try { | ||
if (this.invalid.get()) { | ||
this.configG = reloadConfigurator(); | ||
reconfigurePlace(); | ||
} | ||
this.invalid.set(false); | ||
} catch (IOException e) { | ||
logger.error("Failed to reload configurator"); | ||
} | ||
} | ||
|
||
/** | ||
* Reinitialize the place by reloading the configurator and reconfiguring the place | ||
* | ||
* @param configStream the config data as an {@link InputStream} | ||
*/ | ||
public synchronized void refresh(final InputStream configStream) { | ||
try { | ||
if (this.invalid.get()) { | ||
this.configG = reloadConfigurator(configStream); | ||
reconfigurePlace(); | ||
} | ||
this.invalid.set(false); | ||
} catch (IOException e) { | ||
logger.error("Failed to reload configStream"); | ||
} | ||
} | ||
|
||
protected abstract void reconfigurePlace() throws IOException; | ||
|
||
/** | ||
* Reload the {@link Configurator} | ||
* | ||
* @throws IOException if there is an issue loading the config | ||
*/ | ||
private Configurator reloadConfigurator() throws IOException { | ||
return reloadConfigurator(this.configLocs); | ||
} | ||
|
||
/** | ||
* Reload the {@link Configurator} | ||
* | ||
* @param configLocations the list of configuration files to load | ||
* @throws IOException if there is an issue loading the config | ||
*/ | ||
private static Configurator reloadConfigurator(@Nullable final List<String> configLocations) throws IOException { | ||
if (CollectionUtils.isNotEmpty(configLocations)) { | ||
return ConfigUtil.getConfigInfo(configLocations); | ||
} | ||
throw new IOException("No config locations specified"); | ||
} | ||
|
||
/** | ||
* Reload the {@link Configurator} | ||
* | ||
* @param configStream the stream of configuration data | ||
* @throws IOException if there is an issue loading the config | ||
*/ | ||
private static Configurator reloadConfigurator(@Nullable final InputStream configStream) throws IOException { | ||
if (configStream != null) { | ||
return ConfigUtil.getConfigInfo(configStream); | ||
} | ||
throw new IOException("Null config stream supplied"); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
src/test/java/emissary/place/RefreshableServiceProviderPlaceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package emissary.place; | ||
|
||
import emissary.core.IBaseDataObject; | ||
import emissary.core.Namespace; | ||
import emissary.directory.DirectoryEntry; | ||
import emissary.test.core.junit5.UnitTest; | ||
|
||
import org.junit.jupiter.api.AfterEach; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import javax.annotation.Nullable; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
|
||
class RefreshableServiceProviderPlaceTest extends UnitTest { | ||
|
||
private static final byte[] cfgData = ("SERVICE_KEY = \"UNKNOWN.TEST_PLACE.ID.http://localhost:8001/RefreshablePlaceTest$6050\"\n" + | ||
"KEY_1 = 200").getBytes(); | ||
private static final byte[] cfgDataReload = ("SERVICE_KEY = \"*.TEST_PLACE.ID.http://localhost:8001/RefreshablePlaceTest$5060\"\n" + | ||
"KEY_1 = 300").getBytes(); | ||
|
||
@Nullable | ||
private RefreshablePlaceTest place = null; | ||
|
||
@Override | ||
@BeforeEach | ||
public void setUp() throws Exception { | ||
InputStream config = new ByteArrayInputStream(cfgData); | ||
place = new RefreshablePlaceTest(config, null, "http://localhost:8001/RefreshablePlaceTest"); | ||
} | ||
|
||
@Override | ||
@AfterEach | ||
public void tearDown() throws Exception { | ||
super.tearDown(); | ||
assertNotNull(place); | ||
place.shutDown(); | ||
place = null; | ||
} | ||
|
||
@Test | ||
void testReconfigure() { | ||
assertNotNull(place, "Place created and configured"); | ||
assertEquals("RefreshablePlaceTest", place.getPlaceName(), "Configured place name"); | ||
assertEquals("UNKNOWN", place.getPrimaryProxy(), "Primary proxy"); | ||
assertEquals("UNKNOWN.TEST_PLACE.ID.http://localhost:8001/RefreshablePlaceTest", place.getKey(), "Key generation"); | ||
DirectoryEntry de = place.getDirectoryEntry(); | ||
assertNotNull(de, "Directory entry"); | ||
assertEquals(60, de.getCost(), "Cost in directory entry"); | ||
assertEquals(50, de.getQuality(), "Quality in directory entry"); | ||
assertEquals("Description not available", de.getDescription(), "Description in directory entry"); | ||
assertNotNull(place.configG); | ||
assertEquals(200, place.configG.findIntEntry("KEY_1", 0)); | ||
assertDoesNotThrow(() -> Namespace.lookup("http://localhost:8001/RefreshablePlaceTest")); | ||
|
||
place.invalidate(); | ||
place.refresh(new ByteArrayInputStream(cfgDataReload)); | ||
assertNotNull(place, "Place created and configured"); | ||
assertEquals("RefreshablePlaceTest", place.getPlaceName(), "Configured place name"); | ||
// assertEquals("*", placeTest.getPrimaryProxy(), "Primary proxy"); | ||
assertEquals("UNKNOWN", place.getPrimaryProxy(), "Primary proxy"); | ||
// assertEquals("*.TEST_PLACE.ID.http://localhost:8001/PlaceTest", placeTest.getKey(), "Key generation"); | ||
assertEquals("UNKNOWN.TEST_PLACE.ID.http://localhost:8001/RefreshablePlaceTest", place.getKey(), "Key generation"); | ||
de = place.getDirectoryEntry(); | ||
assertNotNull(de, "Directory entry"); | ||
// assertEquals(50, de.getCost(), "Cost in directory entry"); | ||
assertEquals(60, de.getCost(), "Cost in directory entry"); | ||
// assertEquals(40, de.getQuality(), "Quality in directory entry"); | ||
assertEquals(50, de.getQuality(), "Quality in directory entry"); | ||
assertEquals("Description not available", de.getDescription(), "Description in directory entry"); | ||
assertNotNull(place.configG); | ||
assertEquals(300, place.configG.findIntEntry("KEY_1", 0)); | ||
assertDoesNotThrow(() -> Namespace.lookup("http://localhost:8001/RefreshablePlaceTest")); | ||
} | ||
|
||
private static final class RefreshablePlaceTest extends RefreshableServiceProviderPlace { | ||
|
||
public RefreshablePlaceTest(InputStream config, @Nullable String dir, @Nullable String loc) throws IOException { | ||
super(config, dir, loc); | ||
} | ||
|
||
@Override | ||
public void process(IBaseDataObject d) { | ||
assertNotNull(d); | ||
} | ||
|
||
@Override | ||
protected void reconfigurePlace() {} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters