/*
* Copyright © 2015 Cask Data, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package co.cask.cdap.client;
import co.cask.cdap.api.annotation.Beta;
import co.cask.cdap.api.artifact.ArtifactScope;
import co.cask.cdap.api.data.schema.Schema;
import co.cask.cdap.api.plugin.PluginClass;
import co.cask.cdap.client.config.ClientConfig;
import co.cask.cdap.client.util.RESTClient;
import co.cask.cdap.common.ArtifactAlreadyExistsException;
import co.cask.cdap.common.ArtifactNotFoundException;
import co.cask.cdap.common.ArtifactRangeNotFoundException;
import co.cask.cdap.common.BadRequestException;
import co.cask.cdap.common.NotFoundException;
import co.cask.cdap.common.UnauthenticatedException;
import co.cask.cdap.internal.io.SchemaTypeAdapter;
import co.cask.cdap.proto.Id;
import co.cask.cdap.proto.artifact.ApplicationClassInfo;
import co.cask.cdap.proto.artifact.ApplicationClassSummary;
import co.cask.cdap.proto.artifact.ArtifactInfo;
import co.cask.cdap.proto.artifact.ArtifactRange;
import co.cask.cdap.proto.artifact.ArtifactSummary;
import co.cask.cdap.proto.artifact.PluginInfo;
import co.cask.cdap.proto.artifact.PluginSummary;
import co.cask.common.http.HttpMethod;
import co.cask.common.http.HttpRequest;
import co.cask.common.http.HttpResponse;
import co.cask.common.http.ObjectResponse;
import com.google.common.base.Joiner;
import com.google.common.io.InputSupplier;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import javax.inject.Inject;
/**
* Provides ways to interact with CDAP Artifacts.
*/
@Beta
public class ArtifactClient {
private static final Type ARTIFACT_SUMMARIES_TYPE = new TypeToken<List<ArtifactSummary>>() { }.getType();
private static final Type APPCLASS_SUMMARIES_TYPE = new TypeToken<List<ApplicationClassSummary>>() { }.getType();
private static final Type APPCLASS_INFOS_TYPE = new TypeToken<List<ApplicationClassInfo>>() { }.getType();
private static final Type EXTENSIONS_TYPE = new TypeToken<List<String>>() { }.getType();
private static final Type PLUGIN_SUMMARIES_TYPE = new TypeToken<List<PluginSummary>>() { }.getType();
private static final Type PLUGIN_INFOS_TYPE = new TypeToken<List<PluginInfo>>() { }.getType();
private static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(Schema.class, new SchemaTypeAdapter())
.create();
private final RESTClient restClient;
private final ClientConfig config;
@Inject
public ArtifactClient(ClientConfig config, RESTClient restClient) {
this.config = config;
this.restClient = restClient;
}
public ArtifactClient(ClientConfig config) {
this(config, new RESTClient(config));
}
/**
* Lists all artifacts in the given namespace, including all system artifacts.
*
* @param namespace the namespace to list artifacts in
* @return list of {@link ArtifactSummary}
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
* @throws NotFoundException if the namespace could not be found
*/
public List<ArtifactSummary> list(Id.Namespace namespace)
throws IOException, UnauthenticatedException, NotFoundException {
return list(namespace, null);
}
/**
* Lists all artifacts in the given namespace, optionally including system artifacts.
*
* @param namespace the namespace to list artifacts in
* @param scope the scope of the artifacts to get. If null, both user and system artifacts are listed
* @return list of {@link ArtifactSummary}
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
* @throws NotFoundException if the namespace could not be found
*/
public List<ArtifactSummary> list(Id.Namespace namespace, @Nullable ArtifactScope scope)
throws IOException, UnauthenticatedException, NotFoundException {
URL url = scope == null ? config.resolveNamespacedURLV3(namespace, "artifacts") :
config.resolveNamespacedURLV3(namespace, String.format("artifacts?scope=%s", scope.name()));
HttpResponse response =
restClient.execute(HttpMethod.GET, url, config.getAccessToken(), HttpURLConnection.HTTP_NOT_FOUND);
if (response.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
throw new NotFoundException(namespace);
}
return ObjectResponse.<List<ArtifactSummary>>fromJsonBody(response, ARTIFACT_SUMMARIES_TYPE).getResponseObject();
}
/**
* Lists all versions of the given artifact in the given namespace.
*
* @param namespace the namespace to list artifact versions in
* @param artifactName the name of the artifact
* @return list of {@link ArtifactSummary}
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
* @throws ArtifactNotFoundException if the given artifact does not exist
*/
public List<ArtifactSummary> listVersions(Id.Namespace namespace, String artifactName)
throws UnauthenticatedException, IOException, ArtifactNotFoundException {
return listVersions(namespace, artifactName, null);
}
/**
* Lists all versions of the given artifact in the given namespace.
*
* @param namespace the namespace to list artifact versions in
* @param artifactName the name of the artifact
* @param scope the scope of artifacts to get. If none is given, the scope defaults to the user scope
* @return list of {@link ArtifactSummary}
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
* @throws ArtifactNotFoundException if the given artifact does not exist
*/
public List<ArtifactSummary> listVersions(Id.Namespace namespace, String artifactName, @Nullable ArtifactScope scope)
throws UnauthenticatedException, IOException, ArtifactNotFoundException {
URL url = scope == null ? config.resolveNamespacedURLV3(namespace, String.format("artifacts/%s", artifactName)) :
config.resolveNamespacedURLV3(namespace, String.format("artifacts/%s?scope=%s", artifactName, scope.name()));
HttpResponse response = restClient.execute(
HttpMethod.GET, url, config.getAccessToken(), HttpURLConnection.HTTP_NOT_FOUND);
if (response.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
throw new ArtifactNotFoundException(namespace, artifactName);
}
return ObjectResponse.<List<ArtifactSummary>>fromJsonBody(response, ARTIFACT_SUMMARIES_TYPE).getResponseObject();
}
/**
* Gets information about a specific artifact version.
*
* @param artifactId the id of the artifact to get
* @return information about the given artifact
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
* @throws ArtifactNotFoundException if the given artifact does not exist
*/
public ArtifactInfo getArtifactInfo(Id.Artifact artifactId)
throws IOException, UnauthenticatedException, ArtifactNotFoundException {
ArtifactInfo info;
try {
info = getArtifactInfo(artifactId, ArtifactScope.SYSTEM);
} catch (ArtifactNotFoundException e) {
info = getArtifactInfo(artifactId, ArtifactScope.USER);
}
return info;
}
/**
* Gets information about a specific artifact version.
*
* @param artifactId the id of the artifact to get
* @param scope the scope of the artifact
* @return information about the given artifact
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
* @throws ArtifactNotFoundException if the given artifact does not exist
*/
public ArtifactInfo getArtifactInfo(Id.Artifact artifactId, ArtifactScope scope)
throws IOException, UnauthenticatedException, ArtifactNotFoundException {
String path = String.format("artifacts/%s/versions/%s?scope=%s",
artifactId.getName(), artifactId.getVersion().getVersion(), scope.name());
URL url = config.resolveNamespacedURLV3(artifactId.getNamespace(), path);
HttpResponse response =
restClient.execute(HttpMethod.GET, url, config.getAccessToken(), HttpURLConnection.HTTP_NOT_FOUND);
if (response.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
throw new ArtifactNotFoundException(artifactId);
}
return ObjectResponse.fromJsonBody(response, ArtifactInfo.class, GSON).getResponseObject();
}
/**
* Get summaries of all application classes in the given namespace, including classes from system artifacts.
*
* @param namespace the namespace to list application classes from
* @return summaries of all application classes in the given namespace, including classes from system artifacts
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public List<ApplicationClassSummary> getApplicationClasses(Id.Namespace namespace)
throws IOException, UnauthenticatedException {
return getApplicationClasses(namespace, (ArtifactScope) null);
}
/**
* Get summaries of all application classes in the given namespace,
* optionally including classes from system artifacts.
*
* @param namespace the namespace to list application classes from
* @param scope the scope to list application classes in. If null, classes from all scopes are returned
* @return summaries of all application classes in the given namespace, including classes from system artifacts
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public List<ApplicationClassSummary> getApplicationClasses(Id.Namespace namespace,
@Nullable ArtifactScope scope)
throws IOException, UnauthenticatedException {
String path = scope == null ? "classes/apps" : String.format("classes/apps?scope=%s", scope.name());
URL url = config.resolveNamespacedURLV3(namespace, path);
HttpResponse response = restClient.execute(HttpMethod.GET, url, config.getAccessToken());
return ObjectResponse.<List<ApplicationClassSummary>>fromJsonBody(
response, APPCLASS_SUMMARIES_TYPE).getResponseObject();
}
/**
* Get information about all application classes in the specified namespace, of the specified class name.
*
* @param namespace the namespace to list application classes from
* @return summaries of all application classes in the given namespace, including classes from system artifacts
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public List<ApplicationClassInfo> getApplicationClasses(Id.Namespace namespace, String className)
throws IOException, UnauthenticatedException {
return getApplicationClasses(namespace, className, ArtifactScope.USER);
}
/**
* Get information about all application classes in the specified namespace, of the specified class name.
*
* @param namespace the namespace to list application classes from
* @param scope the scope to list application classes in
* @return summaries of all application classes in the given namespace, including classes from system artifacts
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public List<ApplicationClassInfo> getApplicationClasses(Id.Namespace namespace, String className, ArtifactScope scope)
throws IOException, UnauthenticatedException {
String path = String.format("classes/apps/%s?scope=%s", className, scope.name());
URL url = config.resolveNamespacedURLV3(namespace, path);
HttpResponse response = restClient.execute(HttpMethod.GET, url, config.getAccessToken());
return ObjectResponse.<List<ApplicationClassInfo>>fromJsonBody(
response, APPCLASS_INFOS_TYPE, GSON).getResponseObject();
}
/**
* Gets all the plugin types available to a specific artifact.
*
* @param artifactId the id of the artifact to get
* @return list of plugin types available to the given artifact.
* @throws ArtifactNotFoundException if the given artifact does not exist
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public List<String> getPluginTypes(Id.Artifact artifactId)
throws IOException, UnauthenticatedException, ArtifactNotFoundException {
List<String> pluginTypes;
try {
pluginTypes = getPluginTypes(artifactId, ArtifactScope.SYSTEM);
} catch (ArtifactNotFoundException e) {
pluginTypes = getPluginTypes(artifactId, ArtifactScope.USER);
}
return pluginTypes;
}
/**
* Gets all the plugin types available to a specific artifact.
*
* @param artifactId the id of the artifact to get
* @param scope the scope of the artifact
* @return list of plugin types available to the given artifact.
* @throws ArtifactNotFoundException if the given artifact does not exist
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public List<String> getPluginTypes(Id.Artifact artifactId, ArtifactScope scope)
throws IOException, UnauthenticatedException, ArtifactNotFoundException {
String path = String.format("artifacts/%s/versions/%s/extensions?scope=%s",
artifactId.getName(), artifactId.getVersion().getVersion(), scope.name());
URL url = config.resolveNamespacedURLV3(artifactId.getNamespace(), path);
HttpResponse response = restClient.execute(HttpMethod.GET, url, config.getAccessToken(),
HttpURLConnection.HTTP_NOT_FOUND);
if (response.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
throw new ArtifactNotFoundException(artifactId);
}
return ObjectResponse.<List<String>>fromJsonBody(response, EXTENSIONS_TYPE).getResponseObject();
}
/**
* Gets all the plugins of the given type available to the given artifact.
*
* @param artifactId the id of the artifact to get
* @param pluginType the type of plugins to get
* @return list of {@link PluginSummary}
* @throws ArtifactNotFoundException if the given artifact does not exist
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public List<PluginSummary> getPluginSummaries(Id.Artifact artifactId, String pluginType)
throws IOException, UnauthenticatedException, ArtifactNotFoundException {
List<PluginSummary> pluginSummary;
try {
pluginSummary = getPluginSummaries(artifactId, pluginType, ArtifactScope.SYSTEM);
} catch (ArtifactNotFoundException e) {
pluginSummary = getPluginSummaries(artifactId, pluginType, ArtifactScope.USER);
}
return pluginSummary;
}
/**
* Gets all the plugins of the given type available to the given artifact.
*
* @param artifactId the id of the artifact to get
* @param pluginType the type of plugins to get
* @param scope the scope of the artifact
* @return list of {@link PluginSummary}
* @throws ArtifactNotFoundException if the given artifact does not exist
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public List<PluginSummary> getPluginSummaries(Id.Artifact artifactId, String pluginType, ArtifactScope scope)
throws IOException, UnauthenticatedException, ArtifactNotFoundException {
String path = String.format("artifacts/%s/versions/%s/extensions/%s?scope=%s",
artifactId.getName(), artifactId.getVersion().getVersion(), pluginType, scope.name());
URL url = config.resolveNamespacedURLV3(artifactId.getNamespace(), path);
HttpResponse response = restClient.execute(HttpMethod.GET, url, config.getAccessToken(),
HttpURLConnection.HTTP_NOT_FOUND);
if (response.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
throw new ArtifactNotFoundException(artifactId);
}
return ObjectResponse.<List<PluginSummary>>fromJsonBody(response, PLUGIN_SUMMARIES_TYPE).getResponseObject();
}
/**
* Gets all the plugins of the given type and name available to the given artifact.
*
* @param artifactId the id of the artifact to get
* @param pluginType the type of plugins to get
* @param pluginName the name of the plugins to get
* @return list of {@link PluginInfo}
* @throws NotFoundException if the given artifact does not exist or plugins for that artifact do not exist
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public List<PluginInfo> getPluginInfo(Id.Artifact artifactId, String pluginType, String pluginName)
throws IOException, UnauthenticatedException, NotFoundException {
List<PluginInfo> pluginInfo;
try {
pluginInfo = getPluginInfo(artifactId, pluginType, pluginName, ArtifactScope.SYSTEM);
} catch (NotFoundException e) {
pluginInfo = getPluginInfo(artifactId, pluginType, pluginName, ArtifactScope.USER);
}
return pluginInfo;
}
/**
* Gets all the plugins of the given type and name available to the given artifact.
*
* @param artifactId the id of the artifact to get
* @param pluginType the type of plugins to get
* @param pluginName the name of the plugins to get
* @param scope the scope of the artifact
* @return list of {@link PluginInfo}
* @throws NotFoundException if the given artifact does not exist or plugins for that artifact do not exist
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public List<PluginInfo> getPluginInfo(Id.Artifact artifactId, String pluginType, String pluginName,
ArtifactScope scope)
throws IOException, UnauthenticatedException, NotFoundException {
String path = String.format("artifacts/%s/versions/%s/extensions/%s/plugins/%s?scope=%s",
artifactId.getName(), artifactId.getVersion().getVersion(), pluginType, pluginName, scope.name());
URL url = config.resolveNamespacedURLV3(artifactId.getNamespace(), path);
HttpResponse response = restClient.execute(HttpMethod.GET, url, config.getAccessToken(),
HttpURLConnection.HTTP_NOT_FOUND);
if (response.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
throw new NotFoundException(response.getResponseBodyAsString());
}
return ObjectResponse.<List<PluginInfo>>fromJsonBody(response, PLUGIN_INFOS_TYPE).getResponseObject();
}
/**
* Add an artifact.
*
* @param artifactId the id of the artifact to add
* @param parentArtifacts the set of artifacts this artifact extends
* @param artifactContents an input supplier for the contents of the artifact
* @throws ArtifactAlreadyExistsException if the artifact already exists
* @throws BadRequestException if the request is invalid. For example, if the artifact name or version is invalid
* @throws ArtifactRangeNotFoundException if the parent artifacts do not exist
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public void add(Id.Artifact artifactId, @Nullable Set<ArtifactRange> parentArtifacts,
InputSupplier<? extends InputStream> artifactContents)
throws UnauthenticatedException, BadRequestException, ArtifactRangeNotFoundException,
ArtifactAlreadyExistsException, IOException {
add(artifactId.getNamespace(), artifactId.getName(), artifactContents,
artifactId.getVersion().getVersion(), parentArtifacts);
}
/**
* Add an artifact.
*
* @param namespace the namespace to add the artifact to
* @param artifactName the name of the artifact to add
* @param artifactContents an input supplier for the contents of the artifact
* @param artifactVersion the version of the artifact to add. If null, the version will be derived from the
* manifest of the artifact.
* @throws ArtifactAlreadyExistsException if the artifact already exists
* @throws BadRequestException if the request is invalid. For example, if the artifact name or version is invalid
* @throws ArtifactRangeNotFoundException if the parent artifacts do not exist
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public void add(Id.Namespace namespace, String artifactName,
InputSupplier<? extends InputStream> artifactContents,
@Nullable String artifactVersion)
throws ArtifactAlreadyExistsException, BadRequestException, IOException,
UnauthenticatedException, ArtifactRangeNotFoundException {
add(namespace, artifactName, artifactContents, artifactVersion, null, null);
}
/**
* Add an artifact.
*
* @param namespace the namespace to add the artifact to
* @param artifactName the name of the artifact to add
* @param artifactContents an input supplier for the contents of the artifact
* @param artifactVersion the version of the artifact to add. If null, the version will be derived from the
* manifest of the artifact
* @param parentArtifacts the set of artifacts this artifact extends
* @throws ArtifactAlreadyExistsException if the artifact already exists
* @throws BadRequestException if the request is invalid. For example, if the artifact name or version is invalid
* @throws ArtifactRangeNotFoundException if the parent artifacts do not exist
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public void add(Id.Namespace namespace, String artifactName, InputSupplier<? extends InputStream> artifactContents,
@Nullable String artifactVersion, @Nullable Set<ArtifactRange> parentArtifacts)
throws ArtifactAlreadyExistsException, BadRequestException, IOException,
UnauthenticatedException, ArtifactRangeNotFoundException {
add(namespace, artifactName, artifactContents, artifactVersion, parentArtifacts, null);
}
/**
* Add an artifact.
*
* @param namespace the namespace to add the artifact to
* @param artifactName the name of the artifact to add
* @param artifactContents an input supplier for the contents of the artifact
* @param artifactVersion the version of the artifact to add. If null, the version will be derived from the
* manifest of the artifact
* @param parentArtifacts the set of artifacts this artifact extends
* @param additionalPlugins the set of plugins contained in the artifact that cannot be determined
* through jar inspection. This set should include any classes that are plugins but could
* not be annotated as such. For example, 3rd party classes like jdbc drivers fall into
* this category.
* @throws ArtifactAlreadyExistsException if the artifact already exists
* @throws BadRequestException if the request is invalid. For example, if the artifact name or version is invalid
* @throws ArtifactRangeNotFoundException if the parent artifacts do not exist
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public void add(Id.Namespace namespace, String artifactName,
InputSupplier<? extends InputStream> artifactContents,
@Nullable String artifactVersion,
@Nullable Set<ArtifactRange> parentArtifacts,
@Nullable Set<PluginClass> additionalPlugins)
throws ArtifactAlreadyExistsException, BadRequestException, IOException,
UnauthenticatedException, ArtifactRangeNotFoundException {
URL url = config.resolveNamespacedURLV3(namespace, String.format("artifacts/%s", artifactName));
HttpRequest.Builder requestBuilder = HttpRequest.post(url);
if (artifactVersion != null) {
requestBuilder.addHeader("Artifact-Version", artifactVersion);
}
if (parentArtifacts != null && !parentArtifacts.isEmpty()) {
requestBuilder.addHeader("Artifact-Extends", Joiner.on('/').join(parentArtifacts));
}
if (additionalPlugins != null && !additionalPlugins.isEmpty()) {
requestBuilder.addHeader("Artifact-Plugins", GSON.toJson(additionalPlugins));
}
HttpRequest request = requestBuilder.withBody(artifactContents).build();
HttpResponse response = restClient.execute(request, config.getAccessToken(),
HttpURLConnection.HTTP_CONFLICT, HttpURLConnection.HTTP_BAD_REQUEST, HttpURLConnection.HTTP_NOT_FOUND);
int responseCode = response.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_CONFLICT) {
throw new ArtifactAlreadyExistsException(response.getResponseBodyAsString());
} else if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
throw new BadRequestException(response.getResponseBodyAsString());
} else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
throw new ArtifactRangeNotFoundException(parentArtifacts);
}
}
/**
* Delete an artifact.
*
* @param artifactId the artifact to delete
*
* @throws BadRequestException if the request is invalid. For example, if the artifact name or version is invalid
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public void delete(Id.Artifact artifactId) throws IOException, UnauthenticatedException, BadRequestException {
URL url = config.resolveNamespacedURLV3(artifactId.getNamespace(),
String.format("artifacts/%s/versions/%s", artifactId.getName(), artifactId.getVersion().getVersion()));
HttpRequest request = HttpRequest.delete(url).build();
HttpResponse response = restClient.execute(request, config.getAccessToken(), HttpURLConnection.HTTP_BAD_REQUEST);
int responseCode = response.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
throw new BadRequestException(response.getResponseBodyAsString());
}
}
/**
* Write properties for an artifact. Any existing properties will be overwritten.
*
* @param artifactId the artifact to add properties to
* @param properties the properties to add
* @throws BadRequestException if the request is invalid. For example, if the artifact name or version is invalid
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
* @throws ArtifactNotFoundException if the artifact does not exist
* @throws IOException if a network error occurred
*/
public void writeProperties(Id.Artifact artifactId, Map<String, String> properties)
throws IOException, UnauthenticatedException, ArtifactNotFoundException, BadRequestException {
String path = String.format("artifacts/%s/versions/%s/properties",
artifactId.getName(),
artifactId.getVersion().getVersion());
URL url = config.resolveNamespacedURLV3(artifactId.getNamespace(), path);
HttpRequest.Builder requestBuilder = HttpRequest.put(url);
HttpRequest request = requestBuilder.withBody(GSON.toJson(properties)).build();
HttpResponse response = restClient.execute(request, config.getAccessToken(),
HttpURLConnection.HTTP_BAD_REQUEST, HttpURLConnection.HTTP_NOT_FOUND);
int responseCode = response.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
throw new ArtifactNotFoundException(artifactId);
} else if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
throw new BadRequestException(response.getResponseBodyAsString());
}
}
/**
* Delete all properties for an artifact. If no properties exist, this will be a no-op.
*
* @param artifactId the artifact to delete properties from
* @throws BadRequestException if the request is invalid. For example, if the artifact name or version is invalid
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
* @throws ArtifactNotFoundException if the artifact does not exist
* @throws IOException if a network error occurred
*/
public void deleteProperties(Id.Artifact artifactId)
throws IOException, UnauthenticatedException, ArtifactNotFoundException, BadRequestException {
String path = String.format("artifacts/%s/versions/%s/properties",
artifactId.getName(),
artifactId.getVersion().getVersion());
URL url = config.resolveNamespacedURLV3(artifactId.getNamespace(), path);
HttpRequest.Builder requestBuilder = HttpRequest.delete(url);
HttpRequest request = requestBuilder.build();
HttpResponse response = restClient.execute(request, config.getAccessToken(),
HttpURLConnection.HTTP_BAD_REQUEST, HttpURLConnection.HTTP_NOT_FOUND);
int responseCode = response.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
throw new ArtifactNotFoundException(artifactId);
} else if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
throw new BadRequestException(response.getResponseBodyAsString());
}
}
/**
* Write a property for an artifact. If the property already exists, it will be overwritten. If the property
* does not exist, it will be added.
*
* @param artifactId the artifact to write the property to
* @param key the property key to write
* @param value the property value to write
* @throws BadRequestException if the request is invalid. For example, if the artifact name or version is invalid
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
* @throws ArtifactNotFoundException if the artifact does not exist
* @throws IOException if a network error occurred
*/
public void writeProperty(Id.Artifact artifactId, String key, String value)
throws IOException, UnauthenticatedException, ArtifactNotFoundException, BadRequestException {
String path = String.format("artifacts/%s/versions/%s/properties/%s",
artifactId.getName(),
artifactId.getVersion().getVersion(),
key);
URL url = config.resolveNamespacedURLV3(artifactId.getNamespace(), path);
HttpRequest.Builder requestBuilder = HttpRequest.put(url);
HttpRequest request = requestBuilder.withBody(value).build();
HttpResponse response = restClient.execute(request, config.getAccessToken(),
HttpURLConnection.HTTP_BAD_REQUEST, HttpURLConnection.HTTP_NOT_FOUND);
int responseCode = response.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
throw new ArtifactNotFoundException(artifactId);
} else if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
throw new BadRequestException(response.getResponseBodyAsString());
}
}
/**
* Delete a property for an artifact. If the property does not exist, this will be a no-op.
*
* @param artifactId the artifact to delete a property from
* @param key the property to delete
* @throws BadRequestException if the request is invalid. For example, if the artifact name or version is invalid
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
* @throws ArtifactNotFoundException if the artifact does not exist
* @throws IOException if a network error occurred
*/
public void deleteProperty(Id.Artifact artifactId, String key)
throws IOException, UnauthenticatedException, ArtifactNotFoundException, BadRequestException {
String path = String.format("artifacts/%s/versions/%s/properties/%s",
artifactId.getName(),
artifactId.getVersion().getVersion(),
key);
URL url = config.resolveNamespacedURLV3(artifactId.getNamespace(), path);
HttpRequest.Builder requestBuilder = HttpRequest.delete(url);
HttpRequest request = requestBuilder.build();
HttpResponse response = restClient.execute(request, config.getAccessToken(),
HttpURLConnection.HTTP_BAD_REQUEST, HttpURLConnection.HTTP_NOT_FOUND);
int responseCode = response.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
throw new ArtifactNotFoundException(artifactId);
} else if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
throw new BadRequestException(response.getResponseBodyAsString());
}
}
}