Search in sources :

Example 16 with ServiceUnavailableException

use of io.cdap.cdap.common.ServiceUnavailableException in project cdap by cdapio.

the class LeaderElectionMessagingServiceTest method testTransition.

@Test
public void testTransition() throws Throwable {
    final TopicId topicId = NamespaceId.SYSTEM.topic("topic");
    Injector injector1 = createInjector(0);
    Injector injector2 = createInjector(1);
    // Start a messaging service, which would becomes leader
    ZKClientService zkClient1 = injector1.getInstance(ZKClientService.class);
    zkClient1.startAndWait();
    final MessagingService firstService = injector1.getInstance(MessagingService.class);
    if (firstService instanceof Service) {
        ((Service) firstService).startAndWait();
    }
    // Publish a message with the leader
    firstService.publish(StoreRequestBuilder.of(topicId).addPayload("Testing1").build());
    // Start another messaging service, this one would be follower
    ZKClientService zkClient2 = injector2.getInstance(ZKClientService.class);
    zkClient2.startAndWait();
    final MessagingService secondService = injector2.getInstance(MessagingService.class);
    if (secondService instanceof Service) {
        ((Service) secondService).startAndWait();
    }
    // Try to call the follower, should get service unavailable.
    try {
        secondService.listTopics(NamespaceId.SYSTEM);
        Assert.fail("Expected service unavailable");
    } catch (ServiceUnavailableException e) {
    // Expected
    }
    // Make the ZK session timeout for the leader service. The second one should pickup.
    KillZKSession.kill(zkClient1.getZooKeeperSupplier().get(), zkClient1.getConnectString(), 10000);
    // Publish one more message and then fetch from the current leader
    List<String> messages = Retries.callWithRetries(new Retries.Callable<List<String>, Throwable>() {

        @Override
        public List<String> call() throws Throwable {
            secondService.publish(StoreRequestBuilder.of(topicId).addPayload("Testing2").build());
            List<String> messages = new ArrayList<>();
            try (CloseableIterator<RawMessage> iterator = secondService.prepareFetch(topicId).fetch()) {
                while (iterator.hasNext()) {
                    messages.add(new String(iterator.next().getPayload(), "UTF-8"));
                }
            }
            return messages;
        }
    }, RetryStrategies.timeLimit(10, TimeUnit.SECONDS, RetryStrategies.fixDelay(1, TimeUnit.SECONDS)));
    Assert.assertEquals(Arrays.asList("Testing1", "Testing2"), messages);
    // Shutdown the current leader. The session timeout one should becomes leader again.
    if (secondService instanceof Service) {
        ((Service) secondService).stopAndWait();
    }
    // Try to fetch message from the current leader again.
    // Should see two messages (because the cache is cleared and fetch is from the backing store).
    messages = Retries.callWithRetries(new Retries.Callable<List<String>, Throwable>() {

        @Override
        public List<String> call() throws Throwable {
            List<String> messages = new ArrayList<>();
            try (CloseableIterator<RawMessage> iterator = firstService.prepareFetch(topicId).fetch()) {
                while (iterator.hasNext()) {
                    messages.add(new String(iterator.next().getPayload(), "UTF-8"));
                }
            }
            return messages;
        }
    }, RetryStrategies.timeLimit(10, TimeUnit.SECONDS, RetryStrategies.fixDelay(1, TimeUnit.SECONDS)));
    Assert.assertEquals(Arrays.asList("Testing1", "Testing2"), messages);
    zkClient1.stopAndWait();
    zkClient2.stopAndWait();
}
Also used : CloseableIterator(io.cdap.cdap.api.dataset.lib.CloseableIterator) ArrayList(java.util.ArrayList) NoOpMetricsCollectionService(io.cdap.cdap.common.metrics.NoOpMetricsCollectionService) MessagingService(io.cdap.cdap.messaging.MessagingService) ZKClientService(org.apache.twill.zookeeper.ZKClientService) Service(com.google.common.util.concurrent.Service) MetricsCollectionService(io.cdap.cdap.api.metrics.MetricsCollectionService) ServiceUnavailableException(io.cdap.cdap.common.ServiceUnavailableException) Callable(java.util.concurrent.Callable) MessagingService(io.cdap.cdap.messaging.MessagingService) ZKClientService(org.apache.twill.zookeeper.ZKClientService) Injector(com.google.inject.Injector) Retries(io.cdap.cdap.common.service.Retries) TopicId(io.cdap.cdap.proto.id.TopicId) List(java.util.List) ArrayList(java.util.ArrayList) RawMessage(io.cdap.cdap.messaging.data.RawMessage) Test(org.junit.Test)

Example 17 with ServiceUnavailableException

use of io.cdap.cdap.common.ServiceUnavailableException in project cdap by cdapio.

the class RuntimeServiceRoutingHandler method openConnection.

/**
 * Opens a {@link HttpURLConnection} to the given service for the given program run.
 *
 * @throws BadRequestException if the request for service routing is not valid
 */
private HttpURLConnection openConnection(HttpRequest request, String namespace, String app, String version, String programType, String program, String run, String service) throws BadRequestException {
    ApplicationId appId = new NamespaceId(namespace).app(app, version);
    ProgramRunId programRunId = new ProgramRunId(appId, ProgramType.valueOfCategoryName(programType, BadRequestException::new), program, run);
    requestValidator.getProgramRunStatus(programRunId, request);
    Discoverable discoverable = endpointStrategyLoadingCache.getUnchecked(service).pick(2, TimeUnit.SECONDS);
    if (discoverable == null) {
        throw new ServiceUnavailableException(service);
    }
    String prefix = String.format("%s/runtime/namespaces/%s/apps/%s/versions/%s/%s/%s/runs/%s/services/%s", Constants.Gateway.INTERNAL_API_VERSION_3, namespace, app, version, programType, program, run, service);
    URI uri = URIScheme.createURI(discoverable, request.uri().substring(prefix.length()));
    try {
        URL url = uri.toURL();
        HttpURLConnection urlConn;
        try {
            urlConn = (HttpURLConnection) url.openConnection();
        } catch (IOException e) {
            // If fail to open the connection, treat it as service unavailable so that the client can retry
            throw new ServiceUnavailableException(service);
        }
        if (urlConn instanceof HttpsURLConnection) {
            new HttpsEnabler().setTrustAll(true).enable((HttpsURLConnection) urlConn);
        }
        for (Map.Entry<String, String> header : request.headers().entries()) {
            urlConn.setRequestProperty(header.getKey(), header.getValue());
        }
        urlConn.setRequestMethod(request.method().name());
        urlConn.setDoInput(true);
        return urlConn;
    } catch (MalformedURLException | ProtocolException e) {
        // This can only happen if the incoming request is bad
        throw new BadRequestException("Invalid request due to " + e.getMessage(), e);
    }
}
Also used : ProtocolException(java.net.ProtocolException) Discoverable(org.apache.twill.discovery.Discoverable) MalformedURLException(java.net.MalformedURLException) ServiceUnavailableException(io.cdap.cdap.common.ServiceUnavailableException) IOException(java.io.IOException) URI(java.net.URI) URL(java.net.URL) HttpURLConnection(java.net.HttpURLConnection) BadRequestException(io.cdap.cdap.common.BadRequestException) HttpsEnabler(io.cdap.cdap.common.security.HttpsEnabler) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) ProgramRunId(io.cdap.cdap.proto.id.ProgramRunId) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) Map(java.util.Map) HttpsURLConnection(javax.net.ssl.HttpsURLConnection)

Example 18 with ServiceUnavailableException

use of io.cdap.cdap.common.ServiceUnavailableException in project cdap by cdapio.

the class DatasetServiceClient method doRequest.

private HttpResponse doRequest(HttpRequest.Builder requestBuilder) throws DatasetManagementException, UnauthorizedException {
    HttpRequest request = addUserIdHeader(requestBuilder).build();
    try {
        LOG.trace("Executing {} {}", request.getMethod(), request.getURL().getPath());
        HttpResponse response = remoteClient.execute(request);
        LOG.trace("Executed {} {}", request.getMethod(), request.getURL().getPath());
        return response;
    } catch (ServiceUnavailableException e) {
        // thrown by RemoteClient in case of ConnectException
        logThreadDump();
        LOG.trace("Caught exception for {} {}", request.getMethod(), request.getURL().getPath(), e);
        throw e;
    } catch (SocketTimeoutException e) {
        // passed through by RemoteClient
        logThreadDump();
        LOG.trace("Caught exception for {} {}", request.getMethod(), request.getURL().getPath(), e);
        throw new DatasetManagementException(remoteClient.createErrorMessage(request, null), e);
    } catch (IOException e) {
        // other network exceptions
        LOG.trace("Caught exception for {} {}", request.getMethod(), request.getURL().getPath(), e);
        throw new DatasetManagementException(remoteClient.createErrorMessage(request, null), e);
    } catch (Throwable e) {
        // anything unexpected
        LOG.trace("Caught exception for {} {}", request.getMethod(), request.getURL().getPath(), e);
        throw e;
    }
}
Also used : HttpRequest(io.cdap.common.http.HttpRequest) DatasetManagementException(io.cdap.cdap.api.dataset.DatasetManagementException) SocketTimeoutException(java.net.SocketTimeoutException) HttpResponse(io.cdap.common.http.HttpResponse) ServiceUnavailableException(io.cdap.cdap.common.ServiceUnavailableException) IOException(java.io.IOException)

Example 19 with ServiceUnavailableException

use of io.cdap.cdap.common.ServiceUnavailableException in project cdap by cdapio.

the class LocalLogAppenderResilientTest method testResilientLogging.

@Test
public void testResilientLogging() throws Exception {
    Configuration hConf = new Configuration();
    CConfiguration cConf = CConfiguration.create();
    File datasetDir = new File(tmpFolder.newFolder(), "datasetUser");
    // noinspection ResultOfMethodCallIgnored
    datasetDir.mkdirs();
    cConf.set(Constants.Dataset.Manager.OUTPUT_DIR, datasetDir.getAbsolutePath());
    cConf.set(Constants.Service.MASTER_SERVICES_BIND_ADDRESS, "localhost");
    cConf.set(Constants.Dataset.Executor.ADDRESS, "localhost");
    cConf.setInt(Constants.Dataset.Executor.PORT, Networks.getRandomPort());
    cConf.set(Constants.CFG_LOCAL_DATA_DIR, tmpFolder.newFolder().getAbsolutePath());
    Injector injector = Guice.createInjector(new ConfigModule(cConf, hConf), RemoteAuthenticatorModules.getNoOpModule(), new IOModule(), new ZKClientModule(), new KafkaClientModule(), new InMemoryDiscoveryModule(), new NonCustomLocationUnitTestModule(), new DataFabricModules().getInMemoryModules(), new DataSetsModules().getStandaloneModules(), new DataSetServiceModules().getInMemoryModules(), new TransactionMetricsModule(), new ExploreClientModule(), new LocalLogAppenderModule(), new NamespaceAdminTestModule(), new AuthorizationTestModule(), new AuthorizationEnforcementModule().getInMemoryModules(), new AuthenticationContextModules().getMasterModule(), new AbstractModule() {

        @Override
        protected void configure() {
            bind(UGIProvider.class).to(UnsupportedUGIProvider.class);
            bind(OwnerAdmin.class).to(NoOpOwnerAdmin.class);
            bind(MetadataServiceClient.class).to(NoOpMetadataServiceClient.class);
        }
    });
    TransactionManager txManager = injector.getInstance(TransactionManager.class);
    txManager.startAndWait();
    StoreDefinition.createAllTables(injector.getInstance(StructuredTableAdmin.class));
    DatasetOpExecutorService opExecutorService = injector.getInstance(DatasetOpExecutorService.class);
    opExecutorService.startAndWait();
    // Start the logging before starting the service.
    LoggingContextAccessor.setLoggingContext(new WorkerLoggingContext("TRL_ACCT_1", "APP_1", "WORKER_1", "RUN", "INSTANCE"));
    String logBaseDir = "trl-log/log_files_" + new Random(System.currentTimeMillis()).nextLong();
    cConf.set(LoggingConfiguration.LOG_BASE_DIR, logBaseDir);
    cConf.setInt(LoggingConfiguration.LOG_MAX_FILE_SIZE_BYTES, 20 * 1024);
    final LogAppender appender = injector.getInstance(LocalLogAppender.class);
    new LogAppenderInitializer(appender).initialize("TestResilientLogging");
    int failureMsgCount = 3;
    final CountDownLatch failureLatch = new CountDownLatch(failureMsgCount);
    LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
    loggerContext.getStatusManager().add(new StatusListener() {

        @Override
        public void addStatusEvent(Status status) {
            if (status.getLevel() != Status.ERROR || status.getOrigin() != appender) {
                return;
            }
            Throwable cause = status.getThrowable();
            if (cause != null) {
                Throwable rootCause = Throwables.getRootCause(cause);
                if (rootCause instanceof ServiceUnavailableException) {
                    String serviceName = ((ServiceUnavailableException) rootCause).getServiceName();
                    if (Constants.Service.DATASET_MANAGER.equals(serviceName)) {
                        failureLatch.countDown();
                    }
                }
            }
        }
    });
    Logger logger = LoggerFactory.getLogger("TestResilientLogging");
    for (int i = 0; i < failureMsgCount; ++i) {
        Exception e1 = new Exception("Test Exception1");
        Exception e2 = new Exception("Test Exception2", e1);
        logger.warn("Test log message " + i + " {} {}", "arg1", "arg2", e2);
    }
    // Wait for the three failure to append to happen
    // The wait time has to be > 3 seconds because DatasetServiceClient has 1 second timeout on discovery
    failureLatch.await(5, TimeUnit.SECONDS);
    // Start dataset service, wait for it to be discoverable
    DatasetService dsService = injector.getInstance(DatasetService.class);
    dsService.startAndWait();
    final CountDownLatch startLatch = new CountDownLatch(1);
    DiscoveryServiceClient discoveryClient = injector.getInstance(DiscoveryServiceClient.class);
    discoveryClient.discover(Constants.Service.DATASET_MANAGER).watchChanges(new ServiceDiscovered.ChangeListener() {

        @Override
        public void onChange(ServiceDiscovered serviceDiscovered) {
            if (!Iterables.isEmpty(serviceDiscovered)) {
                startLatch.countDown();
            }
        }
    }, Threads.SAME_THREAD_EXECUTOR);
    startLatch.await(5, TimeUnit.SECONDS);
    // Do some more logging after the service is started.
    for (int i = 5; i < 10; ++i) {
        Exception e1 = new Exception("Test Exception1");
        Exception e2 = new Exception("Test Exception2", e1);
        logger.warn("Test log message " + i + " {} {}", "arg1", "arg2", e2);
    }
    appender.stop();
    // Verify - we should have at least 5 events.
    LoggingContext loggingContext = new WorkerLoggingContext("TRL_ACCT_1", "APP_1", "WORKER_1", "RUN", "INSTANCE");
    FileLogReader logTail = injector.getInstance(FileLogReader.class);
    LoggingTester.LogCallback logCallback1 = new LoggingTester.LogCallback();
    logTail.getLogPrev(loggingContext, ReadRange.LATEST, 10, Filter.EMPTY_FILTER, logCallback1);
    List<LogEvent> allEvents = logCallback1.getEvents();
    Assert.assertTrue(allEvents.toString(), allEvents.size() >= 5);
    // Finally - stop all services
    Services.chainStop(dsService, opExecutorService, txManager);
}
Also used : NoOpOwnerAdmin(io.cdap.cdap.security.impersonation.NoOpOwnerAdmin) DataSetServiceModules(io.cdap.cdap.data.runtime.DataSetServiceModules) DiscoveryServiceClient(org.apache.twill.discovery.DiscoveryServiceClient) Configuration(org.apache.hadoop.conf.Configuration) LoggingConfiguration(io.cdap.cdap.logging.LoggingConfiguration) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) LocalLogAppender(io.cdap.cdap.logging.framework.local.LocalLogAppender) DatasetService(io.cdap.cdap.data2.datafabric.dataset.service.DatasetService) TransactionMetricsModule(io.cdap.cdap.data.runtime.TransactionMetricsModule) FileLogReader(io.cdap.cdap.logging.read.FileLogReader) Random(java.util.Random) Injector(com.google.inject.Injector) KafkaClientModule(io.cdap.cdap.common.guice.KafkaClientModule) Status(ch.qos.logback.core.status.Status) LogEvent(io.cdap.cdap.logging.read.LogEvent) AuthenticationContextModules(io.cdap.cdap.security.auth.context.AuthenticationContextModules) ServiceDiscovered(org.apache.twill.discovery.ServiceDiscovered) NonCustomLocationUnitTestModule(io.cdap.cdap.common.guice.NonCustomLocationUnitTestModule) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) ExploreClientModule(io.cdap.cdap.explore.guice.ExploreClientModule) TransactionManager(org.apache.tephra.TransactionManager) NoOpMetadataServiceClient(io.cdap.cdap.data2.metadata.writer.NoOpMetadataServiceClient) File(java.io.File) DataFabricModules(io.cdap.cdap.data.runtime.DataFabricModules) AuthorizationEnforcementModule(io.cdap.cdap.security.authorization.AuthorizationEnforcementModule) IOModule(io.cdap.cdap.common.guice.IOModule) InMemoryDiscoveryModule(io.cdap.cdap.common.guice.InMemoryDiscoveryModule) WorkerLoggingContext(io.cdap.cdap.logging.context.WorkerLoggingContext) NamespaceAdminTestModule(io.cdap.cdap.common.guice.NamespaceAdminTestModule) LoggingContext(io.cdap.cdap.common.logging.LoggingContext) WorkerLoggingContext(io.cdap.cdap.logging.context.WorkerLoggingContext) ConfigModule(io.cdap.cdap.common.guice.ConfigModule) StructuredTableAdmin(io.cdap.cdap.spi.data.StructuredTableAdmin) ServiceUnavailableException(io.cdap.cdap.common.ServiceUnavailableException) Logger(org.slf4j.Logger) ZKClientModule(io.cdap.cdap.common.guice.ZKClientModule) UnsupportedUGIProvider(io.cdap.cdap.security.impersonation.UnsupportedUGIProvider) DataSetsModules(io.cdap.cdap.data.runtime.DataSetsModules) CountDownLatch(java.util.concurrent.CountDownLatch) AuthorizationTestModule(io.cdap.cdap.security.authorization.AuthorizationTestModule) LoggerContext(ch.qos.logback.classic.LoggerContext) ServiceUnavailableException(io.cdap.cdap.common.ServiceUnavailableException) AbstractModule(com.google.inject.AbstractModule) LocalLogAppenderModule(io.cdap.cdap.logging.guice.LocalLogAppenderModule) DatasetOpExecutorService(io.cdap.cdap.data2.datafabric.dataset.service.executor.DatasetOpExecutorService) StatusListener(ch.qos.logback.core.status.StatusListener) Test(org.junit.Test)

Example 20 with ServiceUnavailableException

use of io.cdap.cdap.common.ServiceUnavailableException in project cdap by cdapio.

the class MonitorHandler method restartInstances.

private void restartInstances(HttpResponder responder, String serviceName, int instanceId, boolean restartAll) throws Exception {
    long startTimeMs = System.currentTimeMillis();
    boolean isSuccess = true;
    if (!serviceManagementMap.containsKey(serviceName)) {
        throw new NotFoundException(String.format("Invalid service name %s", serviceName));
    }
    SystemServiceId systemServiceId = new SystemServiceId(serviceName);
    contextAccessEnforcer.enforce(systemServiceId, ApplicationPermission.EXECUTE);
    MasterServiceManager masterServiceManager = serviceManagementMap.get(serviceName);
    try {
        if (!masterServiceManager.isServiceEnabled()) {
            String message = String.format("Failed to restart instance for %s because the service is not enabled.", serviceName);
            LOG.debug(message);
            isSuccess = false;
            throw new ForbiddenException(message);
        }
        if (restartAll) {
            masterServiceManager.restartAllInstances();
        } else {
            if (instanceId < 0 || instanceId >= masterServiceManager.getInstances()) {
                throw new IllegalArgumentException();
            }
            masterServiceManager.restartInstances(instanceId);
        }
        responder.sendStatus(HttpResponseStatus.OK);
    } catch (IllegalStateException ise) {
        String message = String.format("Failed to restart instance for %s because the service may not be ready yet", serviceName);
        LOG.debug(message, ise);
        isSuccess = false;
        throw new ServiceUnavailableException(message);
    } catch (IllegalArgumentException iex) {
        String message = String.format("Failed to restart instance %d for service: %s because invalid instance id", instanceId, serviceName);
        LOG.debug(message, iex);
        isSuccess = false;
        throw new BadRequestException(message);
    } catch (Exception ex) {
        LOG.warn(String.format("Exception when trying to restart instances for service %s", serviceName), ex);
        isSuccess = false;
        throw new Exception(String.format("Error restarting instance %d for service: %s", instanceId, serviceName));
    } finally {
        long endTimeMs = System.currentTimeMillis();
        if (restartAll) {
            serviceStore.setRestartAllInstancesRequest(serviceName, startTimeMs, endTimeMs, isSuccess);
        } else {
            serviceStore.setRestartInstanceRequest(serviceName, startTimeMs, endTimeMs, isSuccess, instanceId);
        }
    }
}
Also used : SystemServiceId(io.cdap.cdap.proto.id.SystemServiceId) ForbiddenException(io.cdap.cdap.common.ForbiddenException) MasterServiceManager(io.cdap.cdap.common.twill.MasterServiceManager) NotFoundException(io.cdap.cdap.common.NotFoundException) BadRequestException(io.cdap.cdap.common.BadRequestException) ServiceUnavailableException(io.cdap.cdap.common.ServiceUnavailableException) ForbiddenException(io.cdap.cdap.common.ForbiddenException) ServiceUnavailableException(io.cdap.cdap.common.ServiceUnavailableException) JsonSyntaxException(com.google.gson.JsonSyntaxException) BadRequestException(io.cdap.cdap.common.BadRequestException) NotFoundException(io.cdap.cdap.common.NotFoundException)

Aggregations

ServiceUnavailableException (io.cdap.cdap.common.ServiceUnavailableException)58 IOException (java.io.IOException)24 BadRequestException (io.cdap.cdap.common.BadRequestException)14 NotFoundException (io.cdap.cdap.common.NotFoundException)14 HttpResponse (io.cdap.common.http.HttpResponse)12 UnauthorizedException (io.cdap.cdap.security.spi.authorization.UnauthorizedException)10 HttpRequest (io.cdap.common.http.HttpRequest)10 Injector (com.google.inject.Injector)8 DatasetManagementException (io.cdap.cdap.api.dataset.DatasetManagementException)8 URL (java.net.URL)8 Path (javax.ws.rs.Path)8 JsonSyntaxException (com.google.gson.JsonSyntaxException)6 ForbiddenException (io.cdap.cdap.common.ForbiddenException)6 MasterServiceManager (io.cdap.cdap.common.twill.MasterServiceManager)6 SystemServiceId (io.cdap.cdap.proto.id.SystemServiceId)6 HttpURLConnection (java.net.HttpURLConnection)6 Test (org.junit.Test)6 Service (com.google.common.util.concurrent.Service)4 DatasetSpecification (io.cdap.cdap.api.dataset.DatasetSpecification)4 TopicNotFoundException (io.cdap.cdap.api.messaging.TopicNotFoundException)4