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

feat: support for use through jvm -javaagent command line option #289

Merged
merged 1 commit into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,23 @@ $ dcm -p 12345 getNegativePolicy
$ dcm -p 12345 setNegativePolicy 0
```

### Load Cache Entries from File

```bash
$ dcm -p 12345 load /foo/bar/my-cache.properties
```

### Manipulate cache with a command line option at JVM startup

To manipulate dns entries at jvm startup, add the following jvm-options:

```bash
# Set individual entry
java -javaagent:<path to jar>="set foo.com 1.1.1.1" --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/sun.net=ALL-UNNAMED ...
# Load entries from file
java -javaagent:<path to jar>="load my-cache.properties" --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/sun.net=ALL-UNNAMED ...
```

## 📚 Related information

* [Java Agent Specification](http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html)
Expand Down
1 change: 1 addition & 0 deletions library/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
<configuration>
<archive>
<manifestEntries>
<Premain-Class>com.alibaba.dcm.agent.DcmAgent</Premain-Class>
<Agent-Class>com.alibaba.dcm.agent.DcmAgent</Agent-Class>
<Can-Redefine-Classes>false</Can-Redefine-Classes>
<Can-Retransform-Classes>false</Can-Retransform-Classes>
Expand Down
22 changes: 22 additions & 0 deletions library/src/main/java/com/alibaba/dcm/DnsCacheManipulator.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -144,6 +145,27 @@ public static void loadDnsCacheConfig(String propertiesFileName) {
}
}

/**
* Load dns config from the specified properties file in filesystem, then set dns cache.
*
* @param propertiesFileName specified properties file name in filesystem.
* @throws DnsCacheManipulatorException Operation fail
* @see DnsCacheManipulator#setDnsCache(java.util.Properties)
*/
public static void loadDnsCacheConfigFromFileSystem(String propertiesFileName) {
try {
InputStream inputStream = new FileInputStream(propertiesFileName);
Properties properties = new Properties();
properties.load(inputStream);
inputStream.close();
setDnsCache(properties);
} catch (Exception e) {
final String message = String.format("Fail to loadDnsCacheConfig from %s, cause: %s",
propertiesFileName, e);
throw new DnsCacheManipulatorException(message, e);
}
}

/**
* Get a dns cache entry by {@code host}.
*
Expand Down
11 changes: 10 additions & 1 deletion library/src/main/java/com/alibaba/dcm/agent/DcmAgent.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@ public class DcmAgent {
static final String DCM_AGENT_SUCCESS_MARK_LINE = "!!DCM SUCCESS!!";

/**
* Entrance method of DCM Java Agent.
* Entrance method of DCM Java Agent when used through a jvm command line option.
*/
public static void premain(@Nonnull String agentArgument) throws Exception {
agentmain(agentArgument);
}

/**
* Entrance method of DCM Java Agent when connecting to a running jvm.
*/
@SuppressFBWarnings("THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION")
public static void agentmain(@Nonnull String agentArgument) throws Exception {
Expand Down Expand Up @@ -264,6 +271,8 @@ private static synchronized void initAction2Method() throws NoSuchMethodExceptio
map.put("ls", DnsCacheManipulator.class.getMethod("getWholeDnsCache"));
map.put("clear", DnsCacheManipulator.class.getMethod("clearDnsCache"));

map.put("load", DnsCacheManipulator.class.getMethod("loadDnsCacheConfigFromFileSystem", String.class));

map.put("setPolicy", DnsCacheManipulator.class.getMethod("setDnsCachePolicy", int.class));
map.put("getPolicy", DnsCacheManipulator.class.getMethod("getDnsCachePolicy"));
map.put("setNegativePolicy", DnsCacheManipulator.class.getMethod("setDnsNegativeCachePolicy", int.class));
Expand Down
34 changes: 26 additions & 8 deletions library/src/test/java/com/alibaba/dcm/DnsCacheManipulatorTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ package com.alibaba.dcm
import com.alibaba.dcm.internal.InetAddressCacheUtilCommons.isNewInetAddressImpl
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.AnnotationSpec
import io.kotest.matchers.collections.shouldBeEmpty
import io.kotest.matchers.collections.shouldContainExactly
import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder
import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.matchers.collections.*
import io.kotest.matchers.longs.shouldBeBetween
import io.kotest.matchers.nulls.shouldBeNull
import io.kotest.matchers.shouldBe
import io.kotest.matchers.types.shouldNotBeSameInstanceAs

import kotlin.io.path.writeText

private const val IP1 = "42.42.42.1"
private const val IP2 = "42.42.42.2"
Expand Down Expand Up @@ -276,13 +273,13 @@ class DnsCacheManipulatorTests : AnnotationSpec() {
}

@Test
fun test_loadDnsCacheConfig_fromMyConfig() {
fun test_loadDnsCacheConfig_fromMyConfigClassPath() {
DnsCacheManipulator.loadDnsCacheConfig("my-dns-cache.properties")
"www.hello2.com".lookupIpByName() shouldBe IP2
}

@Test
fun test_multi_ips_in_config_file() {
fun test_multi_ips_in_config_file_classpath() {
DnsCacheManipulator.loadDnsCacheConfig("dns-cache-multi-ips.properties")

val host = "www.hello-multi-ips.com"
Expand All @@ -299,11 +296,32 @@ class DnsCacheManipulatorTests : AnnotationSpec() {
}

@Test
fun test_configNotFound() {
fun test_configNotFound_classpath() {
val ex = shouldThrow<DnsCacheManipulatorException> {
DnsCacheManipulator.loadDnsCacheConfig("not-existed.properties")
}

ex.message shouldBe "Fail to find not-existed.properties on classpath!"
}

@Test
fun test_loadDnsCacheConfig_fromMyConfigFileSystem() {
val tempFile = kotlin.io.path.createTempFile("dns-cache-test", ".properties")
tempFile.writeText("www.hello2.com $IP2")
tempFile.toFile().deleteOnExit()

DnsCacheManipulator.loadDnsCacheConfigFromFileSystem(tempFile.toAbsolutePath().toString())
"www.hello2.com".lookupIpByName() shouldBe IP2
}

@Test
fun test_configNotFound_fileSystem() {
val ex = shouldThrow<DnsCacheManipulatorException> {
DnsCacheManipulator.loadDnsCacheConfigFromFileSystem("not-existed.properties")
}

ex.message shouldBeIn arrayOf(
"Fail to loadDnsCacheConfig from not-existed.properties, cause: java.io.FileNotFoundException: not-existed.properties (No such file or directory)",
"Fail to loadDnsCacheConfig from not-existed.properties, cause: java.io.FileNotFoundException: not-existed.properties (The system cannot find the file specified)")
}
}