Repository: ctripcorp/apollo
Pull request #3401 (2020-11-28 04:59:51)

Feature: custom server file location
## What's the purpose of this PR

Let user can custom file `server.properties`'s location through system property or environment variable.

## Which issue(s) this PR fixes:

#2734 

#3389 

## Brief changelog

Resolve the path of file `server.properties` in `com.ctrip.framework.foundation.internals.constant.PathConstants.ResolvedPaths#SERVER_PROPERTIES`, 
and change `com.ctrip.framework.foundation.internals.provider.DefaultServerProvider` to use it directly.

Follow this checklist to help us incorporate your contribution quickly and easily:

- [x] Read the [Contributing Guide](https://github.com/ctripcorp/apollo/blob/master/CONTRIBUTING.md) before making this pull request.
- [x] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
- [x] Write necessary unit tests to verify the code.
- [x] Run `mvn clean test` to make sure this pull request doesn't break anything.


codecov-io: # [Codecov](https://codecov.io/gh/ctripcorp/apollo/pull/3401?src=pr&el=h1) Report
> Merging [#3401](https://codecov.io/gh/ctripcorp/apollo/pull/3401?src=pr&el=desc) (7b9be71) into [master](https://codecov.io/gh/ctripcorp/apollo/commit/c2a87269104fbf182a8e8983d754e485d91b9b14?el=desc) (c2a8726) will **increase** coverage by `0.01%`.
> The diff coverage is `73.68%`.

[![Impacted file tree graph](https://codecov.io/gh/ctripcorp/apollo/pull/3401/graphs/tree.svg?width=650&height=150&src=pr&token=2USkCxREbZ)](https://codecov.io/gh/ctripcorp/apollo/pull/3401?src=pr&el=tree)

```diff
@@             Coverage Diff              @@
##             master    #3401      +/-   ##
============================================
+ Coverage     51.51%   51.52%   +0.01%     
- Complexity     2307     2310       +3     
============================================
  Files           441      444       +3     
  Lines         13762    13778      +16     
  Branches       1400     1404       +4     
============================================
+ Hits           7089     7099      +10     
- Misses         6185     6189       +4     
- Partials        488      490       +2     
```


| [Impacted Files](https://codecov.io/gh/ctripcorp/apollo/pull/3401?src=pr&el=tree) | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| [...framework/foundation/internals/util/PathUtils.java](https://codecov.io/gh/ctripcorp/apollo/pull/3401/diff?src=pr&el=tree#diff-YXBvbGxvLWNvcmUvc3JjL21haW4vamF2YS9jb20vY3RyaXAvZnJhbWV3b3JrL2ZvdW5kYXRpb24vaW50ZXJuYWxzL3V0aWwvUGF0aFV0aWxzLmphdmE=) | `60.00% <60.00%> (ø)` | `2.00 <2.00> (?)` | |
| [...amework/foundation/internals/util/ConfigUtils.java](https://codecov.io/gh/ctripcorp/apollo/pull/3401/diff?src=pr&el=tree#diff-YXBvbGxvLWNvcmUvc3JjL21haW4vamF2YS9jb20vY3RyaXAvZnJhbWV3b3JrL2ZvdW5kYXRpb24vaW50ZXJuYWxzL3V0aWwvQ29uZmlnVXRpbHMuamF2YQ==) | `62.50% <62.50%> (ø)` | `2.00 <2.00> (?)` | |
| [...k/foundation/internals/constant/PathConstants.java](https://codecov.io/gh/ctripcorp/apollo/pull/3401/diff?src=pr&el=tree#diff-YXBvbGxvLWNvcmUvc3JjL21haW4vamF2YS9jb20vY3RyaXAvZnJhbWV3b3JrL2ZvdW5kYXRpb24vaW50ZXJuYWxzL2NvbnN0YW50L1BhdGhDb25zdGFudHMuamF2YQ==) | `100.00% <100.00%> (ø)` | `0.00 <0.00> (?)` | |
| [...tion/internals/provider/DefaultServerProvider.java](https://codecov.io/gh/ctripcorp/apollo/pull/3401/diff?src=pr&el=tree#diff-YXBvbGxvLWNvcmUvc3JjL21haW4vamF2YS9jb20vY3RyaXAvZnJhbWV3b3JrL2ZvdW5kYXRpb24vaW50ZXJuYWxzL3Byb3ZpZGVyL0RlZmF1bHRTZXJ2ZXJQcm92aWRlci5qYXZh) | `63.01% <100.00%> (+0.85%)` | `16.00 <1.00> (ø)` | |
| [.../apollo/internals/RemoteConfigLongPollService.java](https://codecov.io/gh/ctripcorp/apollo/pull/3401/diff?src=pr&el=tree#diff-YXBvbGxvLWNsaWVudC9zcmMvbWFpbi9qYXZhL2NvbS9jdHJpcC9mcmFtZXdvcmsvYXBvbGxvL2ludGVybmFscy9SZW1vdGVDb25maWdMb25nUG9sbFNlcnZpY2UuamF2YQ==) | `77.10% <0.00%> (-1.21%)` | `28.00% <0.00%> (-1.00%)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/ctripcorp/apollo/pull/3401?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/ctripcorp/apollo/pull/3401?src=pr&el=footer). Last update [c2a8726...7b9be71](https://codecov.io/gh/ctripcorp/apollo/pull/3401?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/DefaultServerProvider.java b/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/DefaultServerProvider.java
index 90076c0ca..d02e098e5 100644
--- a/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/DefaultServerProvider.java
+++ b/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/DefaultServerProvider.java
@@ -1,5 +1,24 @@
+/*
+ * 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 com.ctrip.framework.foundation.internals.provider;
 
+import com.google.common.base.Strings;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
@@ -16,20 +35,47 @@ import org.slf4j.LoggerFactory;
 
 public class DefaultServerProvider implements ServerProvider {
   private static final Logger logger = LoggerFactory.getLogger(DefaultServerProvider.class);
-  private static final String SERVER_PROPERTIES_LINUX = "/opt/settings/server.properties";
-  private static final String SERVER_PROPERTIES_WINDOWS = "C:/opt/settings/server.properties";
 
+  static final String DEFAULT_SERVER_PROPERTIES_PATH_ON_LINUX = "/opt/settings/server.properties";
+  static final String DEFAULT_SERVER_PROPERTIES_PATH_ON_WINDOWS = "C:/opt/settings/server.properties";
   private String m_env;
   private String m_dc;
 
-  private Properties m_serverProperties = new Properties();
+  private final Properties m_serverProperties = new Properties();
+
+  String getServerPropertiesPath() {
+    final String serverPropertiesPath = getCustomizedServerPropertiesPath();
+
+    if (!Strings.isNullOrEmpty(serverPropertiesPath)) {
+      return serverPropertiesPath;
+    }
+
+    return Utils.isOSWindows() ? DEFAULT_SERVER_PROPERTIES_PATH_ON_WINDOWS : DEFAULT_SERVER_PROPERTIES_PATH_ON_LINUX;
+  }
+
+  private String getCustomizedServerPropertiesPath() {
+    // 1. Get from System Property
+    final String serverPropertiesPathFromSystemProperty = System
+        .getProperty("apollo.path.server.properties");
+    if (!Strings.isNullOrEmpty(serverPropertiesPathFromSystemProperty)) {
+      return serverPropertiesPathFromSystemProperty;
+    }
+
+    // 2. Get from OS environment variable
+    final String serverPropertiesPathFromEnvironment = System
+        .getenv("APOLLO_PATH_SERVER_PROPERTIES");
+    if (!Strings.isNullOrEmpty(serverPropertiesPathFromEnvironment)) {
+      return serverPropertiesPathFromEnvironment;
+    }
+
+    // last, return null if there is no custom value
+    return null;
+  }
 
   @Override
   public void initialize() {
     try {
-      String path = Utils.isOSWindows() ? SERVER_PROPERTIES_WINDOWS : SERVER_PROPERTIES_LINUX;
-
-      File file = new File(path);
+      File file = new File(this.getServerPropertiesPath());
       if (file.exists() && file.canRead()) {
         logger.info("Loading {}", file.getAbsolutePath());
         FileInputStream fis = new FileInputStream(file);


Test patch:
diff --git a/apollo-core/src/test/java/com/ctrip/framework/foundation/internals/provider/DefaultServerProviderTest.java b/apollo-core/src/test/java/com/ctrip/framework/foundation/internals/provider/DefaultServerProviderTest.java
index e18086fa2..612d7b836 100644
--- a/apollo-core/src/test/java/com/ctrip/framework/foundation/internals/provider/DefaultServerProviderTest.java
+++ b/apollo-core/src/test/java/com/ctrip/framework/foundation/internals/provider/DefaultServerProviderTest.java
@@ -1,10 +1,13 @@
 package com.ctrip.framework.foundation.internals.provider;
 
+import static com.ctrip.framework.foundation.internals.provider.DefaultServerProvider.DEFAULT_SERVER_PROPERTIES_PATH_ON_LINUX;
+import static com.ctrip.framework.foundation.internals.provider.DefaultServerProvider.DEFAULT_SERVER_PROPERTIES_PATH_ON_WINDOWS;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import com.ctrip.framework.foundation.internals.Utils;
 import java.io.File;
 import java.io.FileInputStream;
 
@@ -31,6 +34,20 @@ public class DefaultServerProviderTest {
   private void cleanUp() {
     System.clearProperty("env");
     System.clearProperty("idc");
+    System.clearProperty("apollo.path.server.properties");
+  }
+
+  @Test
+  public void testGetServerPropertiesPathDefault() {
+    assertEquals(Utils.isOSWindows() ? DEFAULT_SERVER_PROPERTIES_PATH_ON_WINDOWS
+        : DEFAULT_SERVER_PROPERTIES_PATH_ON_LINUX, defaultServerProvider.getServerPropertiesPath());
+  }
+
+  @Test
+  public void testGetServerPropertiesPathCustom() {
+    final String customPath = "/simple/custom/path";
+    System.setProperty("apollo.path.server.properties", customPath);
+    assertEquals(customPath, defaultServerProvider.getServerPropertiesPath());
   }
 
   @Test