use of io.cdap.cdap.runtime.spi.provisioner.RetryableProvisionException in project cdap by cdapio.
the class DataprocClient method handleRetryableExceptions.
// Throws retryable Exception for the cases that are transient in nature
private static void handleRetryableExceptions(Exception e) throws RetryableProvisionException {
// if there was an SocketTimeoutException ( read time out ) , we can just try again
if (e instanceof SocketTimeoutException) {
throw new RetryableProvisionException(e);
}
// Attempt retry in case of rate limit errors and service unavailable
if (e instanceof GoogleJsonResponseException) {
GoogleJsonResponseException gError = ((GoogleJsonResponseException) e);
int statusCode = gError.getStatusCode();
if (statusCode == HttpURLConnection.HTTP_UNAVAILABLE) {
throw new RetryableProvisionException(e);
}
if (statusCode == HttpURLConnection.HTTP_FORBIDDEN || statusCode == DataprocUtils.RESOURCE_EXHAUSTED) {
boolean isRetryAble = gError.getDetails().getErrors().stream().anyMatch(errorInfo -> ERROR_INFO_REASONS.contains(errorInfo.getReason()));
if (isRetryAble) {
throw new RetryableProvisionException(e);
}
}
}
}
use of io.cdap.cdap.runtime.spi.provisioner.RetryableProvisionException in project cdap by caskdata.
the class DataprocClient method updateClusterLabels.
/**
* Updates labelsToSet on the given Dataproc cluster.
*
* @param clusterName name of the cluster
* @param labelsToSet Key/Value pairs to set on the Dataproc cluster.
* @param labelsToRemove collection of labels to remove from the Dataproc cluster.
*/
void updateClusterLabels(String clusterName, Map<String, String> labelsToSet, Collection<String> labelsToRemove) throws RetryableProvisionException, InterruptedException {
if (labelsToSet.isEmpty() && labelsToRemove.isEmpty()) {
return;
}
try {
Cluster cluster = getDataprocCluster(clusterName).filter(c -> c.getStatus().getState() == ClusterStatus.State.RUNNING).orElseThrow(() -> new DataprocRuntimeException("Dataproc cluster " + clusterName + " does not exist or not in running state"));
Map<String, String> existingLabels = cluster.getLabelsMap();
// no need to update the cluster labelsToSet.
if (labelsToSet.entrySet().stream().allMatch(e -> Objects.equals(e.getValue(), existingLabels.get(e.getKey()))) && labelsToRemove.stream().noneMatch(existingLabels::containsKey)) {
return;
}
Map<String, String> newLabels = new HashMap<>(existingLabels);
newLabels.keySet().removeAll(labelsToRemove);
newLabels.putAll(labelsToSet);
FieldMask updateMask = FieldMask.newBuilder().addPaths("labels").build();
OperationFuture<Cluster, ClusterOperationMetadata> operationFuture = client.updateClusterAsync(UpdateClusterRequest.newBuilder().setProjectId(conf.getProjectId()).setRegion(conf.getRegion()).setClusterName(clusterName).setCluster(cluster.toBuilder().clearLabels().putAllLabels(newLabels)).setUpdateMask(updateMask).build());
ClusterOperationMetadata metadata = operationFuture.getMetadata().get();
int numWarnings = metadata.getWarningsCount();
if (numWarnings > 0) {
LOG.warn("Encountered {} warning {} while setting labels on cluster:\n{}", numWarnings, numWarnings > 1 ? "s" : "", String.join("\n", metadata.getWarningsList()));
}
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof ApiException) {
throw handleApiException((ApiException) cause);
}
throw new DataprocRuntimeException(cause);
}
}
use of io.cdap.cdap.runtime.spi.provisioner.RetryableProvisionException in project cdap by caskdata.
the class DataprocClient method findNetwork.
private static String findNetwork(String project, Compute compute) throws IOException, RetryableProvisionException {
List<Network> networks;
try {
NetworkList networkList = compute.networks().list(project).execute();
networks = networkList.getItems();
} catch (Exception e) {
handleRetryableExceptions(e);
throw e;
}
if (networks == null || networks.isEmpty()) {
throw new IllegalArgumentException(String.format("Unable to find any networks in project '%s'. " + "Please create a network in the project.", project));
}
for (Network network : networks) {
if ("default".equals(network.getName())) {
return network.getName();
}
}
return networks.iterator().next().getName();
}
use of io.cdap.cdap.runtime.spi.provisioner.RetryableProvisionException in project cdap by caskdata.
the class DataprocClient method getFirewallTargetTags.
/**
* Finds ingress firewall rules for the configured network that matches the required firewall port as
* defined in {@link FirewallPort}.
*
* @return a {@link Collection} of tags that need to be added to the VM to have those firewall rules applies
* @throws IOException If failed to discover those firewall rules
*/
private List<String> getFirewallTargetTags(Network network, boolean useInternalIP) throws IOException, RetryableProvisionException {
FirewallList firewalls;
try {
firewalls = compute.firewalls().list(conf.getNetworkHostProjectID()).execute();
} catch (Exception e) {
handleRetryableExceptions(e);
throw e;
}
List<String> tags = new ArrayList<>();
Set<FirewallPort> requiredPorts = EnumSet.allOf(FirewallPort.class);
// Iterate all firewall rules and see if it has ingress rules for all required firewall port.
for (Firewall firewall : Optional.ofNullable(firewalls.getItems()).orElse(Collections.emptyList())) {
// network is a url like https://www.googleapis.com/compute/v1/projects/<project>/<region>/networks/<name>
// we want to get the last section of the path and compare to the configured network name
int idx = firewall.getNetwork().lastIndexOf('/');
String networkName = idx >= 0 ? firewall.getNetwork().substring(idx + 1) : firewall.getNetwork();
if (!networkName.equals(network.getName())) {
continue;
}
String direction = firewall.getDirection();
if (!"INGRESS".equals(direction) || firewall.getAllowed() == null) {
continue;
}
if (useInternalIP) {
// private IP blocks in order to be able to communicate with Dataproc.
try {
List<IPRange> sourceRanges = Optional.ofNullable(firewall.getSourceRanges()).map(DataprocUtils::parseIPRanges).orElse(Collections.emptyList());
if (!sourceRanges.isEmpty()) {
boolean isPrivate = PRIVATE_IP_RANGES.stream().anyMatch(privateRange -> sourceRanges.stream().anyMatch(privateRange::isOverlap));
if (!isPrivate) {
continue;
}
}
} catch (Exception e) {
LOG.warn("Failed to parse source ranges from firewall rule {}", firewall.getName(), e);
}
}
for (Firewall.Allowed allowed : firewall.getAllowed()) {
String protocol = allowed.getIPProtocol();
boolean addTag = false;
if ("all".equalsIgnoreCase(protocol)) {
requiredPorts.clear();
addTag = true;
} else if ("tcp".equalsIgnoreCase(protocol) && isPortAllowed(allowed.getPorts(), FirewallPort.SSH.port)) {
requiredPorts.remove(FirewallPort.SSH);
addTag = true;
}
if (addTag && firewall.getTargetTags() != null && !firewall.getTargetTags().isEmpty()) {
tags.add(firewall.getTargetTags().iterator().next());
}
}
}
if (!requiredPorts.isEmpty()) {
String portList = requiredPorts.stream().map(p -> String.valueOf(p.port)).collect(Collectors.joining(","));
throw new IllegalArgumentException(String.format("Could not find an ingress firewall rule for network '%s' in project '%s' for ports '%s'. " + "Please create a rule to allow incoming traffic on those ports for your IP range.", network.getName(), conf.getNetworkHostProjectID(), portList));
}
return tags;
}
use of io.cdap.cdap.runtime.spi.provisioner.RetryableProvisionException in project cdap by caskdata.
the class DataprocClient method handleRetryableExceptions.
// Throws retryable Exception for the cases that are transient in nature
private static void handleRetryableExceptions(Exception e) throws RetryableProvisionException {
// if there was an SocketTimeoutException ( read time out ) , we can just try again
if (e instanceof SocketTimeoutException) {
throw new RetryableProvisionException(e);
}
// Attempt retry in case of rate limit errors and service unavailable
if (e instanceof GoogleJsonResponseException) {
GoogleJsonResponseException gError = ((GoogleJsonResponseException) e);
int statusCode = gError.getStatusCode();
if (statusCode == HttpURLConnection.HTTP_UNAVAILABLE) {
throw new RetryableProvisionException(e);
}
if (statusCode == HttpURLConnection.HTTP_FORBIDDEN || statusCode == DataprocUtils.RESOURCE_EXHAUSTED) {
boolean isRetryAble = gError.getDetails().getErrors().stream().anyMatch(errorInfo -> ERROR_INFO_REASONS.contains(errorInfo.getReason()));
if (isRetryAble) {
throw new RetryableProvisionException(e);
}
}
}
}
Aggregations