package org.jboss.tools.openshift.internal.ui.wizard.deployimage.search;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.eclipse.linuxtools.docker.core.IRepositoryTag;
import org.jboss.dmr.ModelNode;
import org.jboss.tools.openshift.internal.ui.OpenShiftUIActivator;
/**
* The default implementation is the Docker Hub registry (running Docker
* registry version 0.6.3)
*/
public class DockerHubRegistry {
private static final String REGISTRY_LOCATION = "https://registry.hub.docker.com/"; //$NON-NLS-1$
/**
* Searches for the tags of the given image on the Docker registry.
* @param repoName the repository/name of the image to search
* @return the list of tags for the given repository, or empty list if none was found
*/
public List<String> getTags(final String repoName) {
final HttpClient httpClient = HttpClientBuilder.create().build();
try {
// check that the registry supports the version 1 API
// see
// https://github.com/docker/docker-registry/blob/master/docker_registry/app.py
final HttpGet pingApiV1Request = new HttpGet(
URIBuilder.target(REGISTRY_LOCATION).path("v1").path("_ping").toString());
pingApiV1Request.setHeader("Accept", "application/json");
final HttpResponse pingApiV1Response = httpClient.execute(pingApiV1Request);
if (pingApiV1Response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new InvalidDockerRegistryException(REGISTRY_LOCATION);
}
// now perform the call to retrieve the list of tags for the given
// repo/name
final HttpGet getTagsRequest = new HttpGet(URIBuilder.target(REGISTRY_LOCATION).path("v1")
.path("repositories").path(repoName).path("tags").toString());
getTagsRequest.setHeader("Accept", "application/json");
final HttpResponse getTagsResponse = httpClient.execute(getTagsRequest);
if (getTagsResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
return Collections.emptyList();
}
final ModelNode tags = ModelNode.fromJSONStream(getTagsResponse.getEntity().getContent());
return tags.asList().stream().map(node -> node.get("name").asString()).collect(Collectors.toList());
} catch (final IOException e) {
OpenShiftUIActivator.getDefault().getLogger().logError("Failed to retrieve the tags for image named '" + repoName + "'", e);
}
return Collections.emptyList();
}
/**
* URI Builder
*/
private static class URIBuilder {
private final StringBuilder uri;
private URIBuilder(final String target) {
this.uri = new StringBuilder(target);
}
public static URIBuilder target(final String target) {
return new URIBuilder(target);
}
/**
* Appends the given {@code path} to the current URI.
* @param path the path to append
* @return this {@link URIBuilder}, for fluent chaining with other paths.
*/
public URIBuilder path(final String path) {
if(path.charAt(0) != '/') {
this.uri.append('/');
}
this.uri.append(path);
return this;
}
@Override
public String toString() {
return this.uri.toString();
}
}
/**
* Repository tag retrieved from Docker Registry version 0.6.3
*
*/
@Deprecated
public class RepositoryTag implements IRepositoryTag {
private String layer;
private String name;
/**
* @return the layer
*/
@Override
public String getLayer() {
return layer;
}
/**
* @param layer
* the layer to set
*/
public void setLayer(String layer) {
this.layer = layer;
}
/**
* @return the name
*/
@Override
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
}
}