Search in sources :

Example 11 with RetryableException

use of io.cdap.cdap.api.retry.RetryableException in project cdap by cdapio.

the class AbstractArtifactLocalizer method getLastModifiedHeader.

/**
 * Helper function for verifying, extracting and converting the Last-Modified header from the URL connection.
 */
private ZonedDateTime getLastModifiedHeader(HttpURLConnection urlConn) {
    Map<String, List<String>> headers = urlConn.getHeaderFields();
    ZonedDateTime lastModified = headers.entrySet().stream().filter(headerEntry -> HttpHeaders.LAST_MODIFIED.equalsIgnoreCase(headerEntry.getKey())).map(Map.Entry::getValue).flatMap(Collection::stream).findFirst().map(s -> ZonedDateTime.parse(s, DateTimeFormatter.RFC_1123_DATE_TIME)).orElse(null);
    if (lastModified == null) {
        // If it does happen we should retry.
        throw new RetryableException(String.format("The response from %s did not contain the %s header.", urlConn.getURL(), HttpHeaders.LAST_MODIFIED));
    }
    return lastModified;
}
Also used : HttpURLConnection(java.net.HttpURLConnection) RetryStrategy(io.cdap.cdap.common.service.RetryStrategy) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) ZonedDateTime(java.time.ZonedDateTime) LoggerFactory(org.slf4j.LoggerFactory) ServiceUnavailableException(io.cdap.cdap.common.ServiceUnavailableException) StandardCopyOption(java.nio.file.StandardCopyOption) HttpHeaders(com.google.common.net.HttpHeaders) CharStreams(com.google.common.io.CharStreams) RemoteClient(io.cdap.cdap.common.internal.remote.RemoteClient) Map(java.util.Map) ArtifactId(io.cdap.cdap.proto.id.ArtifactId) Path(java.nio.file.Path) Nullable(javax.annotation.Nullable) FileUtils(io.cdap.cdap.common.utils.FileUtils) HttpMethod(io.cdap.common.http.HttpMethod) Logger(org.slf4j.Logger) Files(java.nio.file.Files) RetryableException(io.cdap.cdap.api.retry.RetryableException) Collection(java.util.Collection) IOException(java.io.IOException) Reader(java.io.Reader) Instant(java.time.Instant) InputStreamReader(java.io.InputStreamReader) File(java.io.File) StandardCharsets(java.nio.charset.StandardCharsets) ZoneId(java.time.ZoneId) List(java.util.List) ArtifactNotFoundException(io.cdap.cdap.common.ArtifactNotFoundException) DateTimeFormatter(java.time.format.DateTimeFormatter) Constants(io.cdap.cdap.common.conf.Constants) DirUtils(io.cdap.cdap.common.utils.DirUtils) ArtifactScope(io.cdap.cdap.api.artifact.ArtifactScope) InputStream(java.io.InputStream) RetryableException(io.cdap.cdap.api.retry.RetryableException) ZonedDateTime(java.time.ZonedDateTime) List(java.util.List)

Example 12 with RetryableException

use of io.cdap.cdap.api.retry.RetryableException in project cdap by caskdata.

the class AbstractArtifactLocalizer method fetchArtifact.

/**
 * fetchArtifact attempts to connect to app fabric to download the given artifact. This method will throw
 * {@link RetryableException} in certain circumstances.
 *
 * @param artifactId The ArtifactId of the artifact to fetch
 * @param remoteClient The remote client used to connect to appfabric on the peer
 * @param artifactDir The directory where the artifact will be stored
 * @return The Local Location for this artifact
 * @throws IOException If an unexpected error occurs while writing the artifact to the filesystem
 * @throws ArtifactNotFoundException If the given artifact does not exist
 */
protected File fetchArtifact(ArtifactId artifactId, RemoteClient remoteClient, File artifactDir) throws IOException, ArtifactNotFoundException {
    Long lastModifiedTimestamp = getCurrentLastModifiedTimestamp(artifactDir);
    HttpURLConnection urlConn = openConnection(artifactId, remoteClient);
    try {
        if (lastModifiedTimestamp != null) {
            LOG.debug("Found existing local version for {} with timestamp {}", artifactId, lastModifiedTimestamp);
            ZonedDateTime lastModifiedDate = ZonedDateTime.ofInstant(Instant.ofEpochMilli(lastModifiedTimestamp), ZoneId.of("GMT"));
            urlConn.setRequestProperty(HttpHeaders.IF_MODIFIED_SINCE, lastModifiedDate.format(DateTimeFormatter.RFC_1123_DATE_TIME));
        }
        // If we get this response that means we already have the most up to date artifact
        if (lastModifiedTimestamp != null && urlConn.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
            LOG.debug("Call to app fabric returned NOT_MODIFIED for {} with lastModifiedTimestamp of {}", artifactId, lastModifiedTimestamp);
            File artifactJarLocation = getArtifactJarLocation(artifactDir, lastModifiedTimestamp);
            if (!artifactJarLocation.exists()) {
                throw new RetryableException(String.format("Locally cached artifact jar for %s is missing.", artifactId));
            }
            return artifactJarLocation;
        }
        throwIfError(urlConn, artifactId);
        ZonedDateTime newModifiedDate = getLastModifiedHeader(urlConn);
        long newTimestamp = newModifiedDate.toInstant().toEpochMilli();
        File newLocation = getArtifactJarLocation(artifactDir, newTimestamp);
        DirUtils.mkdirs(newLocation.getParentFile());
        // Download the artifact to a temporary file then atomically rename it to the final name to
        // avoid race conditions with multiple threads.
        Path tempFile = Files.createTempFile(newLocation.getParentFile().toPath(), String.valueOf(newTimestamp), ".jar");
        return downloadArtifact(urlConn, newLocation.toPath(), tempFile);
    } finally {
        urlConn.disconnect();
    }
}
Also used : Path(java.nio.file.Path) HttpURLConnection(java.net.HttpURLConnection) RetryableException(io.cdap.cdap.api.retry.RetryableException) ZonedDateTime(java.time.ZonedDateTime) File(java.io.File)

Example 13 with RetryableException

use of io.cdap.cdap.api.retry.RetryableException in project cdap by caskdata.

the class UpgradeJobMain method suspendSchedulesAndStopPipelines.

private static void suspendSchedulesAndStopPipelines(ClientConfig clientConfig) throws Exception {
    ApplicationClient applicationClient = new ApplicationClient(clientConfig);
    ScheduleClient scheduleClient = new ScheduleClient(clientConfig);
    ProgramClient programClient = new ProgramClient(clientConfig);
    NamespaceClient namespaceClient = new NamespaceClient(clientConfig);
    boolean shouldRetry = false;
    List<NamespaceId> namespaceIdList = namespaceClient.list().stream().map(NamespaceMeta::getNamespaceId).collect(Collectors.toList());
    namespaceIdList.add(NamespaceId.SYSTEM);
    for (NamespaceId namespaceId : namespaceIdList) {
        for (ApplicationRecord record : applicationClient.list(namespaceId)) {
            ApplicationId applicationId = new ApplicationId(namespaceId.getNamespace(), record.getName(), record.getAppVersion());
            LOG.debug("Trying to stop schedule and workflows for application " + applicationId);
            List<WorkflowId> workflowIds = applicationClient.get(applicationId).getPrograms().stream().filter(programRecord -> programRecord.getType().equals(ProgramType.WORKFLOW)).map(programRecord -> new WorkflowId(applicationId, programRecord.getName())).collect(Collectors.toList());
            for (WorkflowId workflowId : workflowIds) {
                List<ScheduleId> scheduleIds = scheduleClient.listSchedules(workflowId).stream().map(scheduleDetail -> new ScheduleId(namespaceId.getNamespace(), record.getName(), record.getAppVersion(), scheduleDetail.getName())).collect(Collectors.toList());
                for (ScheduleId scheduleId : scheduleIds) {
                    if (scheduleClient.getStatus(scheduleId).equals(SCHEDULED)) {
                        scheduleClient.suspend(scheduleId);
                    }
                }
                // Need to stop workflows first or else the program will fail to stop below
                if (!programClient.getStatus(workflowId).equals(ProgramStatus.STOPPED.toString())) {
                    try {
                        programClient.stop(workflowId);
                    } catch (BadRequestException e) {
                        // transitioned to stop state since it was checked earlier or not.
                        if (!programClient.getStatus(workflowId).equals(ProgramStatus.STOPPED.toString())) {
                            // Pipeline still in running state. Continue with stopping rest of the pipelines in this namespace and
                            // next retry should try to stop/verify status for this pipeline.
                            shouldRetry = true;
                        }
                    }
                }
            }
        }
        // At least one pipeline is still in running state so retry to verify pipeline status .
        if (shouldRetry) {
            throw new RetryableException("At least one pipeline in namespace " + namespaceId + " is still running.");
        }
        // All schedules are stopped, now stop all programs
        programClient.stopAll(namespaceId);
    }
}
Also used : Retries(io.cdap.cdap.common.service.Retries) RetryStrategy(io.cdap.cdap.common.service.RetryStrategy) WorkflowId(io.cdap.cdap.proto.id.WorkflowId) ScheduleClient(io.cdap.cdap.client.ScheduleClient) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) LoggerFactory(org.slf4j.LoggerFactory) NamespaceClient(io.cdap.cdap.client.NamespaceClient) RetryStrategies(io.cdap.cdap.common.service.RetryStrategies) ProgramType(io.cdap.cdap.proto.ProgramType) ApplicationClient(io.cdap.cdap.client.ApplicationClient) ScheduleId(io.cdap.cdap.proto.id.ScheduleId) ConnectionConfig(io.cdap.cdap.client.config.ConnectionConfig) ProgramStatus(io.cdap.cdap.proto.ProgramStatus) ProgramClient(io.cdap.cdap.client.ProgramClient) Logger(org.slf4j.Logger) RetryableException(io.cdap.cdap.api.retry.RetryableException) IOException(java.io.IOException) BadRequestException(io.cdap.cdap.common.BadRequestException) Collectors(java.util.stream.Collectors) TimeUnit(java.util.concurrent.TimeUnit) NamespaceMeta(io.cdap.cdap.proto.NamespaceMeta) List(java.util.List) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) ClientConfig(io.cdap.cdap.client.config.ClientConfig) Constants(io.cdap.cdap.common.conf.Constants) ApplicationRecord(io.cdap.cdap.proto.ApplicationRecord) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) NotFoundException(io.cdap.cdap.common.NotFoundException) SecurityUtil(io.cdap.cdap.security.impersonation.SecurityUtil) ApplicationClient(io.cdap.cdap.client.ApplicationClient) ProgramClient(io.cdap.cdap.client.ProgramClient) WorkflowId(io.cdap.cdap.proto.id.WorkflowId) ScheduleId(io.cdap.cdap.proto.id.ScheduleId) ApplicationRecord(io.cdap.cdap.proto.ApplicationRecord) RetryableException(io.cdap.cdap.api.retry.RetryableException) NamespaceClient(io.cdap.cdap.client.NamespaceClient) BadRequestException(io.cdap.cdap.common.BadRequestException) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) ScheduleClient(io.cdap.cdap.client.ScheduleClient)

Example 14 with RetryableException

use of io.cdap.cdap.api.retry.RetryableException in project cdap by caskdata.

the class RuntimeServiceMainTest method createProgramStateWriter.

/**
 * Creates a {@link ProgramStateWriter} that writes to {@link RuntimeClient} directly.
 *
 * @param injector the injector for creating the {@link RuntimeClient}
 * @param programRunId the {@link ProgramRunId} for the program state change
 * @return a {@link ProgramStateWriter}
 */
private ProgramStateWriter createProgramStateWriter(Injector injector, ProgramRunId programRunId) {
    RuntimeClient runtimeClient = injector.getInstance(RuntimeClient.class);
    // We write to the record event directly to skip the app-fabric to process it
    // This is because we don't follow the normal event flow here for testing
    TopicId topicId = NamespaceId.SYSTEM.topic(injector.getInstance(CConfiguration.class).get(Constants.AppFabric.PROGRAM_STATUS_RECORD_EVENT_TOPIC));
    RetryStrategy retryStrategy = RetryStrategies.timeLimit(5, TimeUnit.SECONDS, RetryStrategies.fixDelay(200, TimeUnit.MILLISECONDS));
    return new MessagingProgramStateWriter((notificationType, properties) -> {
        Notification notification = new Notification(notificationType, properties);
        try {
            Retries.callWithRetries((Retries.Callable<Void, Exception>) () -> {
                runtimeClient.sendMessages(programRunId, topicId, Collections.singleton(createMessage(notification)).iterator());
                return null;
            }, retryStrategy, t -> t instanceof IOException || t instanceof RetryableException);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    });
}
Also used : RuntimeClient(io.cdap.cdap.internal.app.runtime.monitor.RuntimeClient) RetryableException(io.cdap.cdap.api.retry.RetryableException) Retries(io.cdap.cdap.common.service.Retries) TopicId(io.cdap.cdap.proto.id.TopicId) IOException(java.io.IOException) MessagingProgramStateWriter(io.cdap.cdap.internal.app.program.MessagingProgramStateWriter) RetryStrategy(io.cdap.cdap.common.service.RetryStrategy) Notification(io.cdap.cdap.proto.Notification) RetryableException(io.cdap.cdap.api.retry.RetryableException) IOException(java.io.IOException)

Example 15 with RetryableException

use of io.cdap.cdap.api.retry.RetryableException in project cdap by caskdata.

the class DatasetServiceStore method startUp.

@Override
protected void startUp() throws Exception {
    final DatasetId serviceStoreDatasetInstanceId = NamespaceId.SYSTEM.dataset(Constants.Service.SERVICE_INSTANCE_TABLE_NAME);
    table = Retries.supplyWithRetries(() -> {
        try {
            return DatasetsUtil.getOrCreateDataset(dsFramework, serviceStoreDatasetInstanceId, NoTxKeyValueTable.class.getName(), DatasetProperties.EMPTY, null);
        } catch (Exception e) {
            // Throwing RetryableException here is just to make it retry getting the dataset
            // an exception here usually means there is an hbase problem
            LOG.warn("Error getting service store dataset {}. Will retry after some time: {}", serviceStoreDatasetInstanceId, e.getMessage());
            throw new RetryableException(e);
        }
    }, RetryStrategies.exponentialDelay(1, 30, TimeUnit.SECONDS));
}
Also used : RetryableException(io.cdap.cdap.api.retry.RetryableException) RetryableException(io.cdap.cdap.api.retry.RetryableException) DatasetId(io.cdap.cdap.proto.id.DatasetId)

Aggregations

RetryableException (io.cdap.cdap.api.retry.RetryableException)28 IOException (java.io.IOException)16 RetryStrategy (io.cdap.cdap.common.service.RetryStrategy)6 NotFoundException (io.cdap.cdap.common.NotFoundException)5 ApplicationId (io.cdap.cdap.proto.id.ApplicationId)5 Constants (io.cdap.cdap.common.conf.Constants)4 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)4 HttpResponse (io.cdap.common.http.HttpResponse)4 File (java.io.File)4 HttpURLConnection (java.net.HttpURLConnection)4 Path (java.nio.file.Path)4 ZonedDateTime (java.time.ZonedDateTime)4 ArtifactSummary (io.cdap.cdap.api.artifact.ArtifactSummary)3 DatasetManagementException (io.cdap.cdap.api.dataset.DatasetManagementException)3 TopicNotFoundException (io.cdap.cdap.api.messaging.TopicNotFoundException)3 AccessException (io.cdap.cdap.api.security.AccessException)3 InvalidArtifactException (io.cdap.cdap.common.InvalidArtifactException)3 ServiceUnavailableException (io.cdap.cdap.common.ServiceUnavailableException)3 Retries (io.cdap.cdap.common.service.Retries)3 Notification (io.cdap.cdap.proto.Notification)3