Repository: ansible/ansible

Issue:
maven_artifact doesn't read the proper snapshotVersion of the artifact
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
Bug Report

##### COMPONENT NAME
maven_artifact

##### ANSIBLE VERSION
```
ansible 2.3.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]
```

##### CONFIGURATION
<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->

##### SUMMARY
<!--- Explain the problem briefly -->
Given multiple Maven artifacts with same `groupId` and `artifactId` but different `extension` and/or `classifier`, Ansible doesn't read `snapshotVersions` in `maven-metadata.xml`.

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->
Create a dummy Maven repository with dummy artifacts `foo:bar:1.2.3-SNAPSHOT:pom`, `foo:bar:1.2.3-SNAPSHOT:war` and `foo:bar:1.2.3-SNAPSHOT:properties`.
```
mkdir -p foo/bar/1.2.3-SNAPSHOT

echo "<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1.0">
  <groupId>foo</groupId>
  <artifactId>bar</artifactId>
  <version>1.2.3-SNAPSHOT</version>
  <versioning>
    <snapshot>
      <timestamp>20170719.155215</timestamp>
      <buildNumber>9</buildNumber>
    </snapshot>
    <lastUpdated>20170720025620</lastUpdated>
    <snapshotVersions>
      <snapshotVersion>
        <extension>pom</extension>
        <value>1.2.3-20170719.155215-10</value>
        <updated>20170719155215</updated>
      </snapshotVersion>
      <snapshotVersion>
        <extension>war</extension>
        <value>1.2.3-20170719.155215-10</value>
        <updated>20170719155215</updated>
      </snapshotVersion>
      <snapshotVersion>
        <extension>properties</extension>
        <value>1.2.3-20170719.155215-9</value>
        <updated>20170719155215</updated>
      </snapshotVersion>
    </snapshotVersions>
  </versioning>
</metadata>" > foo/bar/1.2.3-SNAPSHOT/maven-metadata.xml

touch foo/bar/1.2.3-SNAPSHOT/bar-1.2.3-20170719.155215-10.pom \
  foo/bar/1.2.3-SNAPSHOT/bar-1.2.3-20170719.155215-10.war \
  foo/bar/1.2.3-SNAPSHOT/bar-1.2.3-20170719.155215-9.properties

for i in foo/bar/1.2.3-SNAPSHOT/bar-1.2.3-* ; do
  md5sum $i > $i.md5
done

python -m SimpleHTTPServer
```

Artifacts download with Maven is working fine :
```
mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:get \                                                                                           [8d8ef76]
  -DrepoUrl=http://localhost:8000/ \
  -Dartifact=foo:bar:1.2.3-SNAPSHOT:pom

mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:get \                                                                                           [8d8ef76]
  -DrepoUrl=http://localhost:8000/ \
  -Dartifact=foo:bar:1.2.3-SNAPSHOT:war

mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:get \                                                                                           [8d8ef76]
  -DrepoUrl=http://localhost:8000/ \
  -Dartifact=foo:bar:1.2.3-SNAPSHOT:properties
```

Artifacts download with Ansible fails :
```yaml
---
- hosts: localhost
  tasks:

    - maven_artifact:
        group_id: foo
        artifact_id: bar
        version: 1.2.3-SNAPSHOT
        extension: pom
        dest: /tmp/bar.pom
        repository_url: http://localhost:8000/

    - maven_artifact:
        group_id: foo
        artifact_id: bar
        version: 1.2.3-SNAPSHOT
        extension: war
        dest: /tmp/bar.war
        repository_url: http://localhost:8000/

    - maven_artifact:
        group_id: foo
        artifact_id: bar
        version: 1.2.3-SNAPSHOT
        extension: properties
        dest: /tmp/bar.properties
        repository_url: http://localhost:8000/
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Ansible shouldn't fail to download the artifacts.

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
TASK [maven_artifact] *************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "Failed to download artifact foo:bar:pom:1.2.3-SNAPSHOT because of HTTP Error 404: File not foundfor URL http://localhost:8000/foo/bar/1.2.3-SNAPSHOT/bar-1.2.3-20170719.155215-9.pom"}
```



Discussion:

Resolving patch:
diff --git a/lib/ansible/modules/packaging/language/maven_artifact.py b/lib/ansible/modules/packaging/language/maven_artifact.py
--- a/lib/ansible/modules/packaging/language/maven_artifact.py
+++ b/lib/ansible/modules/packaging/language/maven_artifact.py
@@ -154,7 +154,7 @@
 
 
 class Artifact(object):
-    def __init__(self, group_id, artifact_id, version, classifier=None, extension='jar'):
+    def __init__(self, group_id, artifact_id, version, classifier='', extension='jar'):
         if not group_id:
             raise ValueError("group_id must be set")
         if not artifact_id:
@@ -245,10 +245,9 @@ def find_uri_for_artifact(self, artifact):
             timestamp = xml.xpath("/metadata/versioning/snapshot/timestamp/text()")[0]
             buildNumber = xml.xpath("/metadata/versioning/snapshot/buildNumber/text()")[0]
             for snapshotArtifact in xml.xpath("/metadata/versioning/snapshotVersions/snapshotVersion"):
-                if (len(snapshotArtifact.xpath("classifier/text()")) > 0 and
-                        snapshotArtifact.xpath("classifier/text()")[0] == artifact.classifier and
-                        len(snapshotArtifact.xpath("extension/text()")) > 0 and
-                        snapshotArtifact.xpath("extension/text()")[0] == artifact.extension):
+                artifact_classifier = snapshotArtifact.xpath("classifier/text()")[0] if len(snapshotArtifact.xpath("classifier/text()")) > 0 else ''
+                artifact_extension = snapshotArtifact.xpath("extension/text()")[0] if len(snapshotArtifact.xpath("extension/text()")) > 0 else ''
+                if artifact_classifier == artifact.classifier and artifact_extension == artifact.extension:
                     return self._uri_for_artifact(artifact, snapshotArtifact.xpath("value/text()")[0])
             return self._uri_for_artifact(artifact, artifact.version.replace("SNAPSHOT", timestamp + "-" + buildNumber))
 
@@ -358,7 +357,7 @@ def main():
             group_id = dict(default=None),
             artifact_id = dict(default=None),
             version = dict(default="latest"),
-            classifier = dict(default=None),
+            classifier = dict(default=''),
             extension = dict(default='jar'),
             repository_url = dict(default=None),
             username = dict(default=None,aliases=['aws_secret_key']),


Test patch: