June 27, 2016

Artifactory Java Client API Examples (Part 2)

Picking up where I left off with my previous Artifactory Java Client API Example post, I now offer a Java example which utilizes the Artifactory Java Client API and the Artifactory Query Language (AQL). Introduced in Artifactory 3.5.0, the AQL provides a flexible and high performance search.

Please note, as written on Stackoverflow.com by fundeldman (to whom I owe my gratitude for giving me the direction I was looking for)…

“The Artifactory Java Client does not support AQL queries natively. You can however use the generic REST call interface it provides to create an ArtifactoryRequest pointing to the AQL API endpoint.”

First, I construct the AQL query (to find all artifacts that match a given name (pattern) and repo and that were created after a given date)…

String artifactoryRepo = "my-release-local";
String name = "ivy-*.xml";

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
String createDateMarginStr = simpleDateFormat.format(createDateMargin);

StringBuilder builder = new StringBuilder(256);
builder.append("items.find("));

builder.append("{\"repo\" : {\"$eq\" : \"" + artifactoryRepo + "\"}}");
builder.append(",{\"name\" : {\"$match\" : \"" + name + "\"}}");
builder.append(",{\"created\" : {\"$gt\" : \"" + createDateMarginStr + "\"}}");

/*
* Please note, users without admin privileges have the following restriction:
*
* The following three fields must be included in the include directive: name, repo, and path.
*
* Note, however, that once this restriction is met, you may include any other accessible field in the include directive.
*/
builder.append(".include(\"repo\", \"path\", \"name\")");

String aqlQuery = builder.toString();

Next, I construct the ArtifactoryRequest…

ArtifactoryRequest aqlRequest = new ArtifactoryRequestImpl().method(ArtifactoryRequest.Method.POST)
        .apiUrl(api/search/aql)
        .requestType(ArtifactoryRequest.ContentType.TEXT)
        .responseType(ArtifactoryRequest.ContentType.JSON)
        .requestBody(aqlQuery);

Notice the fact that the apiUrl does not begin with a forward slash. This was not immediately obvious as this was not the case in my previous experiences. See Part I.

Next, I create the ArtifactoryClient (with artifactoryUrl, username, and password) and execute the REST request…

Artifactory artifactory =  ArtifactoryClient.create(artifactoryUrl, username, password);
Map aqlResponse = artifactory.restCall(aqlRequest);

Note, the username and password are required for AQL queries.

And lastly, I parse the results…

List paths = new ArrayList();
List<map name="name" id="name"><div>> resultsList = (List<map name="name"><div>>) aqlResponse.get("results");
resultsList.stream().forEach(resultMap -> 
        rupReceiptPaths.add(resultMap.get("path") + "/" + resultMap.get("name")));

Gradle Dependencies

To build via Gradle, please note the following dependencies.

compile("org.jfrog.artifactory.client:artifactory-java-client-api:1.2.2")
compile("org.jfrog.artifactory.client:artifactory-java-client-services:1.2.2")

References

The Artifactory REST API

The Artifactory Query Language

Looking for Artifactory Query Language example in Java

Tom Muldoon

Software Architect