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

Extract environment settings from appengine-web.xml and set them for devappserver1 runs #378

Merged
merged 37 commits into from
Apr 25, 2017

Conversation

etanshaul
Copy link
Contributor

What do you think of this approach?

If ok, I'll go ahead and add unit tests.

I tested this with devappserver1 and IntelliJ.

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");
Copy link
Contributor Author

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.

@patflynn
Copy link
Contributor

patflynn commented Apr 19, 2017 via email

@etanshaul
Copy link
Contributor Author

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) {
Copy link
Contributor Author

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'.

@patflynn
Copy link
Contributor

patflynn commented Apr 19, 2017 via email

@etanshaul
Copy link
Contributor Author

oh, I see. yeah the effect of the clash here is simply to use the value from the last service in the list.

@patflynn
Copy link
Contributor

patflynn commented Apr 19, 2017 via email

@etanshaul etanshaul requested a review from elharo April 19, 2017 18:46
@codecov-io
Copy link

codecov-io commented Apr 19, 2017

Codecov Report

Merging #378 into master will increase coverage by 0.47%.
The diff coverage is 79.41%.

Impacted file tree graph

@@            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
Impacted Files Coverage Δ
...oogle/cloud/tools/appengine/cloudsdk/CloudSdk.java 40.76% <0%> (ø) ⬆️
...gle/cloud/tools/appengine/AppEngineDescriptor.java 76.47% <76.92%> (-5.68%) ⬇️
...ppengine/cloudsdk/CloudSdkAppEngineDevServer1.java 85.71% <92.3%> (+1.67%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 814aca9...55a5d75. Read the comment docs.

@etanshaul
Copy link
Contributor Author

@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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i++ is more common

Copy link
Contributor Author

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

Copy link
Contributor

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 😞

Copy link
Contributor Author

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.
Copy link
Contributor

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?

Copy link
Contributor Author

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());
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

@etanshaul
Copy link
Contributor Author

@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)) {
Copy link
Member

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.

Copy link
Contributor Author

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());
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@briandealwis updated

@etanshaul
Copy link
Contributor Author

@briandealwis / @elharo do I have the ok? I'd love to merge this in today if you have no further comments.

@patflynn
Copy link
Contributor

@etanshaul
@elharo
@briandealwis

What do you guys think of a log.info message tell the user we're setting these environment variables?

@briandealwis
Copy link
Member

briandealwis commented Apr 24, 2017

LGTM @etanshaul

+1 to logging the environment variables: that would help the developer figure out where values are coming from.

@etanshaul
Copy link
Contributor Author

@patflynn, added a logging statement ca8678e

processRunner.setEnvironment(environment);
Map<String, String> devServerEnvironment = Maps.newHashMap(environment);
if (!devServerEnvironment.isEmpty()) {
logger.info("Setting user supplied environment variables: "
Copy link
Contributor

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 :)

Copy link
Contributor Author

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: "
Copy link
Contributor

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.

Copy link
Contributor Author

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);
Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor Author

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)) {
Copy link
Contributor

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.

Copy link
Contributor Author

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"?>
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@etanshaul
Copy link
Contributor Author

discussed with @elharo offline and we are good to go with this. will merge

@etanshaul etanshaul merged commit 3ebe475 into master Apr 25, 2017
@chanseokoh chanseokoh deleted the set-environment branch May 5, 2017 17:46
JoeWang1127 pushed a commit that referenced this pull request Nov 29, 2023
JoeWang1127 pushed a commit that referenced this pull request Nov 29, 2023
* Remove v2-alpha devappserver support

* Admin Override: MacOS test could be broken (because of test machine jdk config)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants