-
Notifications
You must be signed in to change notification settings - Fork 26
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
Extract environment settings from appengine-web.xml and set them for devappserver1 runs #378
Conversation
…devappserver1 runs
Map<String, String> getAllAppEngineEnvironment(List<File> services) { | ||
Map<String, String> allAppEngineEnvironment = Maps.newHashMap(); | ||
for (File serviceDirectory : services) { | ||
Path appengineWebXml = serviceDirectory.toPath().resolve("WEB-INF/appengine-web.xml"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know theres some duplication here with isJava8; looking at refactoring a little.
The fact that the environment variables can clash between services looks
like a problem for the devappserver1 multi-module model.
…On Wed, Apr 19, 2017 at 2:24 PM, Etan Shaul ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/main/java/com/google/cloud/tools/appengine/cloudsdk/
CloudSdkAppEngineDevServer1.java
<#378 (comment)>
:
> @@ -194,4 +199,22 @@ boolean isJava8(List<File> services) {
}
return java8Detected;
}
+
+ @VisibleForTesting
+ Map<String, String> getAllAppEngineEnvironment(List<File> services) {
+ Map<String, String> allAppEngineEnvironment = Maps.newHashMap();
+ for (File serviceDirectory : services) {
+ Path appengineWebXml = serviceDirectory.toPath().resolve("WEB-INF/appengine-web.xml");
I know theres some duplication here with isJava8; looking at refactoring a
little.
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#378 (review)>,
or mute the thread
</~https://github.com/notifications/unsubscribe-auth/AHf5HRecWder1GtvSMGUclEMky6QU8n7ks5rxlFKgaJpZM4NCDy9>
.
|
That's true. However isn't that a problem for devappserver2 as well? I wonder how it handles it. |
return null; | ||
} | ||
|
||
private static Map<String, String> getAttributeMap(Node node, String key, String value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized I need to update this to also search for a target child node by name. E.g.:
<env-variables>
<env-var name="ENDPOINTS_SERVICE_NAME" value="some_value" />
</env-variables>
The logic should probably search for the tag 'env-var'.
devappserver2 uses a different jvm for each service.
In any case this seems better than what we have now. Even if there's
potential for a clash.
…On Wed, Apr 19, 2017 at 2:28 PM, Etan Shaul ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/main/java/com/google/cloud/tools/appengine/AppEngineDescriptor.java
<#378 (comment)>
:
> @@ -99,16 +105,55 @@ public boolean isJava8() {
&& getRuntime().startsWith("java8");
}
- private static String getTopLevelValue(Document doc, String parentTagName, String childTagName) {
+ public Map<String, String> getEnvironment() {
+ Node environmentParentNode = getTargetNode(document, "appengine-web-app", "env-variables");
+ return getAttributeMap(environmentParentNode, "name", "value");
+ }
+
+ private static String getText(Node node) {
+ if (node != null) {
+ return node.getTextContent();
+ }
+
+ return null;
+ }
+
+ private static Map<String, String> getAttributeMap(Node node, String key, String value) {
I realized I need to update this to also search for a target child node by
name. E.g.:
<env-variables>
<env-var name="ENDPOINTS_SERVICE_NAME" value="some_value" />
</env-variables>
The logic should probably search for the tag 'env-var'.
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#378 (review)>,
or mute the thread
</~https://github.com/notifications/unsubscribe-auth/AHf5HTo-UTc-Laos-rrL6H1tMHaj0bhdks5rxlJHgaJpZM4NCDy9>
.
|
oh, I see. yeah the effect of the clash here is simply to use the value from the last service in the list. |
that's probably worth warning on.
…On Apr 19, 2017 2:31 PM, "Etan Shaul" ***@***.***> wrote:
oh, I see. yeah the effect of the clash here is simply to use the value
from the last service in the list.
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#378 (comment)>,
or mute the thread
</~https://github.com/notifications/unsubscribe-auth/AHf5HQU7rTU1ok1aOPEosJXu5h44dNjaks5rxlMIgaJpZM4NCDy9>
.
|
…node in attribute map construction
Codecov Report
@@ Coverage Diff @@
## master #378 +/- ##
=========================================
+ Coverage 63.82% 64.3% +0.47%
=========================================
Files 66 66
Lines 1703 1751 +48
Branches 252 264 +12
=========================================
+ Hits 1087 1126 +39
- Misses 508 513 +5
- Partials 108 112 +4
Continue to review full report at Codecov.
|
@elharo since you previously commented, are you good with this now? |
Map<String, String> nameValueAttributeMap = Maps.newHashMap(); | ||
|
||
if (parent.hasChildNodes()) { | ||
for (int i = 0; i < parent.getChildNodes().getLength(); ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i++ is more common
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea, not sure why its like that, Ill update
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kinda disappointing that we can't use the shortened for loop syntax here 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
} | ||
|
||
/** | ||
* Returns a map formed from the attributes of the nodes contained within the parent node. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if two child elements have attributes with the same name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then the last one found will be added to the map (according to the contract of Map#put)
@@ -292,7 +293,6 @@ public void runDevAppServer1Command(List<String> jvmArgs, List<String> args) | |||
|
|||
logCommand(command); | |||
|
|||
Map<String, String> environment = Maps.newHashMap(); | |||
environment.put("JAVA_HOME", javaHomePath.toAbsolutePath().toString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we be copying the provided environment and avoid side-effects?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
@elharo @briandealwis please take a look to see if I've addressed all your comments. |
Map<String, String> existingEnvironment, | ||
String service) { | ||
for (String key : newEnvironment.keySet()) { | ||
if (existingEnvironment.containsKey(key)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Downside to this detection approach is that it doesn't provide the source of the original definitions. But this can be left as a todo for later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea, I was aware of this when implementing it. I didn't think it was that essential to justify the extra logic to deliver this (knowing one of the offending files to me was adequate). But yea, can be a todo.
Map<String, String> appEngineEnvironment = AppEngineDescriptor.parse(is).getEnvironment(); | ||
if (appEngineEnvironment != null) { | ||
checkAndWarnDuplicateEnvironmentVariables( | ||
appEngineEnvironment, allAppEngineEnvironment, serviceDirectory.getName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you are parsing the appengine-web.xml
, why not report the real service name rather than the directory? The directory name may not correspond to the service name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@briandealwis updated
@briandealwis / @elharo do I have the ok? I'd love to merge this in today if you have no further comments. |
@etanshaul What do you guys think of a log.info message tell the user we're setting these environment variables? |
LGTM @etanshaul +1 to logging the environment variables: that would help the developer figure out where values are coming from. |
processRunner.setEnvironment(environment); | ||
Map<String, String> devServerEnvironment = Maps.newHashMap(environment); | ||
if (!devServerEnvironment.isEmpty()) { | ||
logger.info("Setting user supplied environment variables: " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think you need to let them know this is coming from appengine-web.xml :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
processRunner.setEnvironment(environment); | ||
Map<String, String> devServerEnvironment = Maps.newHashMap(environment); | ||
if (!devServerEnvironment.isEmpty()) { | ||
logger.info("Setting appengine-web.xml configured environment variables: " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK now I am being a total PITA but I worry that some other entrypoint might pass environment that's not based off of appengine-web.xml. Perhaps this logging statement belongs closer to CloudSdkAppEngineDevServer1:120?
Feel free to throw darts at an effigy of me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, you're right. I was planning on improving this in the other PR (that allows client supplied env vars) since we'll have to differentiate between them. But yea, I think maybe moving them to the other class is the right approach.
* Returns the first node found matching the given name contained within the parent node. | ||
*/ | ||
private static Node getNode(Document doc, String parentNodeName, String targetNodeName) { | ||
NodeList parentElements = doc.getElementsByTagNameNS(APP_ENGINE_NAMESPACE, parentNodeName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why you're using the parentNodeName here. You could jump straight to the relevant nodes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I figured this helps to ensure the xml for the env vars is properly formed: e.g. env-var
elements contained within a parent env-variables
. If I skipped straight to env-vars
then wouldn't it match against invalid parent elements?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, this method is used by all the extractors (service, version etc. Not just for environment). Its pretty much a direct refactor of what was there before (getTopLevelValue
as it was previously called).
if (parent.hasChildNodes()) { | ||
for (int i = 0; i < parent.getChildNodes().getLength(); i++) { | ||
Node child = parent.getChildNodes().item(i); | ||
if (child.getNodeName().equals(targetNodeName)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Theoretically you should be checking namesapces here too. Probalby doesn't matter much in practice. However there are a lot of ways this navigtion could go wrong is the appen gine-web.xml file is not as required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you be more specific regarding your last sentence? e.g. what could go wrong and do you think I should be handling it here?
@@ -0,0 +1,31 @@ | |||
<?xml version="1.0" encoding="utf-8"?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can make these test data file smaller if all they're used for is to test the environment variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
discussed with @elharo offline and we are good to go with this. will merge |
…devappserver1 runs (#378)
* Remove v2-alpha devappserver support * Admin Override: MacOS test could be broken (because of test machine jdk config)
What do you think of this approach?
If ok, I'll go ahead and add unit tests.
I tested this with devappserver1 and IntelliJ.