Search in sources :

Example 56 with Stat

use of org.apache.flink.shaded.zookeeper3.org.apache.zookeeper.data.Stat in project camel by apache.

the class ExistsOperation method getResult.

@Override
public OperationResult<String> getResult() {
    try {
        Stat statistics = connection.exists(node, true);
        boolean ok = isOk(statistics);
        if (LOG.isTraceEnabled()) {
            LOG.trace(ok ? "node exists" : "node does not exist");
        }
        return new OperationResult<String>(node, statistics, ok);
    } catch (Exception e) {
        return new OperationResult<String>(e);
    }
}
Also used : Stat(org.apache.zookeeper.data.Stat)

Example 57 with Stat

use of org.apache.flink.shaded.zookeeper3.org.apache.zookeeper.data.Stat in project pulsar by yahoo.

the class BrokerService method updateDynamicServiceConfiguration.

private void updateDynamicServiceConfiguration() {
    try {
        Optional<Map<String, String>> data = dynamicConfigurationCache.get(BROKER_SERVICE_CONFIGURATION_PATH);
        if (data.isPresent() && data.get() != null) {
            data.get().forEach((key, value) -> {
                try {
                    Field field = ServiceConfiguration.class.getDeclaredField(key);
                    if (field != null && field.isAnnotationPresent(FieldContext.class)) {
                        field.setAccessible(true);
                        field.set(pulsar().getConfiguration(), FieldParser.value(value, field));
                        log.info("Successfully updated {}/{}", key, value);
                    }
                } catch (Exception e) {
                    log.warn("Failed to update service configuration {}/{}, {}", key, value, e.getMessage());
                }
            });
        }
        // register a listener: it updates field value and triggers appropriate registered field-listener only if
        // field's value has been changed so, registered doesn't have to update field value in ServiceConfiguration
        dynamicConfigurationCache.registerListener(new ZooKeeperCacheListener<Map<String, String>>() {

            @SuppressWarnings("unchecked")
            @Override
            public void onUpdate(String path, Map<String, String> data, Stat stat) {
                if (BROKER_SERVICE_CONFIGURATION_PATH.equalsIgnoreCase(path) && data != null) {
                    data.forEach((configKey, value) -> {
                        Field configField = dynamicConfigurationMap.get(configKey);
                        Object newValue = FieldParser.value(data.get(configKey), configField);
                        if (configField != null) {
                            Consumer listener = configRegisteredListeners.get(configKey);
                            try {
                                Object existingValue = configField.get(pulsar.getConfiguration());
                                configField.set(pulsar.getConfiguration(), newValue);
                                log.info("Successfully updated configuration {}/{}", configKey, data.get(configKey));
                                if (listener != null && !existingValue.equals(newValue)) {
                                    listener.accept(newValue);
                                }
                            } catch (Exception e) {
                                log.error("Failed to update config {}/{}", configKey, newValue);
                            }
                        } else {
                            log.error("Found non-dynamic field in dynamicConfigMap {}/{}", configKey, newValue);
                        }
                    });
                }
            }
        });
    } catch (Exception e) {
        log.warn("Failed to read zookeeper path [{}]:", BROKER_SERVICE_CONFIGURATION_PATH, e);
    }
}
Also used : DefaultThreadFactory(io.netty.util.concurrent.DefaultThreadFactory) LoggerFactory(org.slf4j.LoggerFactory) NamespaceBundleStats(com.yahoo.pulsar.common.policies.data.loadbalancer.NamespaceBundleStats) Stat(org.apache.zookeeper.data.Stat) Policies(com.yahoo.pulsar.common.policies.data.Policies) EpollMode(io.netty.channel.epoll.EpollMode) PersistencePolicies(com.yahoo.pulsar.common.policies.data.PersistencePolicies) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) PersistentOfflineTopicStats(com.yahoo.pulsar.common.policies.data.PersistentOfflineTopicStats) ClusterData(com.yahoo.pulsar.common.policies.data.ClusterData) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) ManagedLedgerConfig(org.apache.bookkeeper.mledger.ManagedLedgerConfig) Map(java.util.Map) ZooKeeperCacheListener(com.yahoo.pulsar.zookeeper.ZooKeeperCacheListener) PulsarService(com.yahoo.pulsar.broker.PulsarService) FieldParser(com.yahoo.pulsar.common.util.FieldParser) PulsarClientImpl(com.yahoo.pulsar.client.impl.PulsarClientImpl) FutureUtil(com.yahoo.pulsar.client.util.FutureUtil) URI(java.net.URI) PulsarClient(com.yahoo.pulsar.client.api.PulsarClient) SystemUtils(org.apache.commons.lang.SystemUtils) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) DigestType(org.apache.bookkeeper.client.BookKeeper.DigestType) PersistenceException(com.yahoo.pulsar.broker.service.BrokerServiceException.PersistenceException) Set(java.util.Set) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) PooledByteBufAllocator(io.netty.buffer.PooledByteBufAllocator) InetSocketAddress(java.net.InetSocketAddress) Executors(java.util.concurrent.Executors) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) ObjectMapperFactory(com.yahoo.pulsar.common.util.ObjectMapperFactory) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) Metrics(com.yahoo.pulsar.broker.stats.Metrics) List(java.util.List) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) AdminResource(com.yahoo.pulsar.broker.admin.AdminResource) ClientConfiguration(com.yahoo.pulsar.client.api.ClientConfiguration) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) Optional(java.util.Optional) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException) ManagedLedgerFactory(org.apache.bookkeeper.mledger.ManagedLedgerFactory) ChannelOption(io.netty.channel.ChannelOption) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) SafeRun.safeRun(org.apache.bookkeeper.mledger.util.SafeRun.safeRun) PersistentTopicStats(com.yahoo.pulsar.common.policies.data.PersistentTopicStats) EpollChannelOption(io.netty.channel.epoll.EpollChannelOption) Lists(com.google.common.collect.Lists) FieldContext(com.yahoo.pulsar.common.configuration.FieldContext) ByteBuf(io.netty.buffer.ByteBuf) EpollServerSocketChannel(io.netty.channel.epoll.EpollServerSocketChannel) RetentionPolicies(com.yahoo.pulsar.common.policies.data.RetentionPolicies) ConcurrentOpenHashSet(com.yahoo.pulsar.common.util.collections.ConcurrentOpenHashSet) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) EpollEventLoopGroup(io.netty.channel.epoll.EpollEventLoopGroup) ConcurrentOpenHashMap(com.yahoo.pulsar.common.util.collections.ConcurrentOpenHashMap) AdaptiveRecvByteBufAllocator(io.netty.channel.AdaptiveRecvByteBufAllocator) NamespaceBundle(com.yahoo.pulsar.common.naming.NamespaceBundle) NamespaceBundleFactory(com.yahoo.pulsar.common.naming.NamespaceBundleFactory) PersistentReplicator(com.yahoo.pulsar.broker.service.persistent.PersistentReplicator) ClusterReplicationMetrics(com.yahoo.pulsar.broker.stats.ClusterReplicationMetrics) Logger(org.slf4j.Logger) ZooKeeperDataCache(com.yahoo.pulsar.zookeeper.ZooKeeperDataCache) EventLoopGroup(io.netty.channel.EventLoopGroup) KeeperException(org.apache.zookeeper.KeeperException) Semaphore(java.util.concurrent.Semaphore) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) ServerMetadataException(com.yahoo.pulsar.broker.service.BrokerServiceException.ServerMetadataException) IOException(java.io.IOException) NamespaceName(com.yahoo.pulsar.common.naming.NamespaceName) Field(java.lang.reflect.Field) ServiceUnitNotReadyException(com.yahoo.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) OpenLedgerCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.OpenLedgerCallback) ServiceConfiguration(com.yahoo.pulsar.broker.ServiceConfiguration) PulsarWebResource(com.yahoo.pulsar.broker.web.PulsarWebResource) Closeable(java.io.Closeable) CollectionUtils.isEmpty(org.apache.commons.collections.CollectionUtils.isEmpty) AuthorizationManager(com.yahoo.pulsar.broker.authorization.AuthorizationManager) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) AuthenticationService(com.yahoo.pulsar.broker.authentication.AuthenticationService) FieldContext(com.yahoo.pulsar.common.configuration.FieldContext) PersistenceException(com.yahoo.pulsar.broker.service.BrokerServiceException.PersistenceException) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException) KeeperException(org.apache.zookeeper.KeeperException) ServerMetadataException(com.yahoo.pulsar.broker.service.BrokerServiceException.ServerMetadataException) IOException(java.io.IOException) ServiceUnitNotReadyException(com.yahoo.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) Field(java.lang.reflect.Field) Stat(org.apache.zookeeper.data.Stat) Consumer(java.util.function.Consumer) Map(java.util.Map) HashMap(java.util.HashMap) ConcurrentOpenHashMap(com.yahoo.pulsar.common.util.collections.ConcurrentOpenHashMap)

Example 58 with Stat

use of org.apache.flink.shaded.zookeeper3.org.apache.zookeeper.data.Stat in project pulsar by yahoo.

the class Namespaces method setRetention.

@POST
@Path("/{property}/{cluster}/{namespace}/retention")
@ApiOperation(value = " Set retention configuration on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace does not exist"), @ApiResponse(code = 409, message = "Concurrent modification"), @ApiResponse(code = 412, message = "Retention Quota must exceed backlog quota") })
public void setRetention(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, RetentionPolicies retention) {
    validatePoliciesReadOnlyAccess();
    try {
        Stat nodeStat = new Stat();
        final String path = path("policies", property, cluster, namespace);
        byte[] content = globalZk().getData(path, null, nodeStat);
        Policies policies = jsonMapper().readValue(content, Policies.class);
        if (!checkQuotas(policies, retention)) {
            log.warn("[{}] Failed to update retention configuration for namespace {}/{}/{}: conflicts with backlog quota", clientAppId(), property, cluster, namespace);
            throw new RestException(Status.PRECONDITION_FAILED, "Retention Quota must exceed configured backlog quota for namespace.");
        }
        policies.retention_policies = retention;
        globalZk().setData(path, jsonMapper().writeValueAsBytes(policies), nodeStat.getVersion());
        policiesCache().invalidate(path("policies", property, cluster, namespace));
        log.info("[{}] Successfully updated retention configuration: namespace={}/{}/{}, map={}", clientAppId(), property, cluster, namespace, jsonMapper().writeValueAsString(policies.retention_policies));
    } catch (KeeperException.NoNodeException e) {
        log.warn("[{}] Failed to update retention configuration for namespace {}/{}/{}: does not exist", clientAppId(), property, cluster, namespace);
        throw new RestException(Status.NOT_FOUND, "Namespace does not exist");
    } catch (KeeperException.BadVersionException e) {
        log.warn("[{}] Failed to update retention configuration for namespace {}/{}/{}: concurrent modification", clientAppId(), property, cluster, namespace);
        throw new RestException(Status.CONFLICT, "Concurrent modification");
    } catch (RestException pfe) {
        throw pfe;
    } catch (Exception e) {
        log.error("[{}] Failed to update retention configuration for namespace {}/{}/{}", clientAppId(), property, cluster, namespace, e);
        throw new RestException(e);
    }
}
Also used : Stat(org.apache.zookeeper.data.Stat) Policies(com.yahoo.pulsar.common.policies.data.Policies) PersistencePolicies(com.yahoo.pulsar.common.policies.data.PersistencePolicies) RetentionPolicies(com.yahoo.pulsar.common.policies.data.RetentionPolicies) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) RestException(com.yahoo.pulsar.broker.web.RestException) KeeperException(org.apache.zookeeper.KeeperException) RestException(com.yahoo.pulsar.broker.web.RestException) WebApplicationException(javax.ws.rs.WebApplicationException) SubscriptionBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) KeeperException(org.apache.zookeeper.KeeperException) PulsarAdminException(com.yahoo.pulsar.client.admin.PulsarAdminException) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) PulsarServerException(com.yahoo.pulsar.broker.PulsarServerException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 59 with Stat

use of org.apache.flink.shaded.zookeeper3.org.apache.zookeeper.data.Stat in project pulsar by yahoo.

the class Namespaces method deleteNamespace.

@DELETE
@Path("/{property}/{cluster}/{namespace}")
@ApiOperation(value = "Delete a namespace and all the destinations under it.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Property or cluster or namespace doesn't exist"), @ApiResponse(code = 409, message = "Namespace is not empty") })
public void deleteNamespace(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) {
    NamespaceName nsName = new NamespaceName(property, cluster, namespace);
    validateAdminAccessOnProperty(property);
    validatePoliciesReadOnlyAccess();
    // ensure that non-global namespace is directed to the correct cluster
    validateClusterOwnership(cluster);
    Entry<Policies, Stat> policiesNode = null;
    Policies policies = null;
    // ensure the local cluster is the only cluster for the global namespace configuration
    try {
        policiesNode = policiesCache().getWithStat(path("policies", property, cluster, namespace)).orElseThrow(() -> new RestException(Status.NOT_FOUND, "Namespace " + nsName + " does not exist."));
        policies = policiesNode.getKey();
        if (cluster.equals(Namespaces.GLOBAL_CLUSTER)) {
            if (policies.replication_clusters.size() > 1) {
                // There are still more than one clusters configured for the global namespace
                throw new RestException(Status.PRECONDITION_FAILED, "Cannot delete the global namespace " + nsName + ". There are still more than one replication clusters configured.");
            }
            if (policies.replication_clusters.size() == 1 && !policies.replication_clusters.contains(config().getClusterName())) {
                // the only replication cluster is other cluster, redirect
                String replCluster = policies.replication_clusters.get(0);
                ClusterData replClusterData = clustersCache().get(AdminResource.path("clusters", replCluster)).orElseThrow(() -> new RestException(Status.NOT_FOUND, "Cluser " + replCluster + " does not exist"));
                URL replClusterUrl;
                if (!config().isTlsEnabled()) {
                    replClusterUrl = new URL(replClusterData.getServiceUrl());
                } else if (!replClusterData.getServiceUrlTls().isEmpty()) {
                    replClusterUrl = new URL(replClusterData.getServiceUrlTls());
                } else {
                    throw new RestException(Status.PRECONDITION_FAILED, "The replication cluster does not provide TLS encrypted service");
                }
                URI redirect = UriBuilder.fromUri(uri.getRequestUri()).host(replClusterUrl.getHost()).port(replClusterUrl.getPort()).replaceQueryParam("authoritative", false).build();
                log.debug("[{}] Redirecting the rest call to {}: cluster={}", clientAppId(), redirect, cluster);
                throw new WebApplicationException(Response.temporaryRedirect(redirect).build());
            }
        }
    } catch (WebApplicationException wae) {
        throw wae;
    } catch (Exception e) {
        throw new RestException(e);
    }
    List<String> destinations = getDestinations(property, cluster, namespace);
    if (!destinations.isEmpty()) {
        log.info("Found destinations: {}", destinations);
        throw new RestException(Status.CONFLICT, "Cannot delete non empty namespace");
    }
    // set the policies to deleted so that somebody else cannot acquire this namespace
    try {
        policies.deleted = true;
        globalZk().setData(path("policies", property, cluster, namespace), jsonMapper().writeValueAsBytes(policies), policiesNode.getValue().getVersion());
        policiesCache().invalidate(path("policies", property, cluster, namespace));
    } catch (Exception e) {
        log.error("[{}] Failed to delete namespace on global ZK {}/{}/{}", clientAppId(), property, cluster, namespace, e);
        throw new RestException(e);
    }
    // remove from owned namespace map and ephemeral node from ZK
    try {
        NamespaceBundles bundles = pulsar().getNamespaceService().getNamespaceBundleFactory().getBundles(nsName);
        for (NamespaceBundle bundle : bundles.getBundles()) {
            // check if the bundle is owned by any broker, if not then we do not need to delete the bundle
            if (pulsar().getNamespaceService().getOwner(bundle).isPresent()) {
                pulsar().getAdminClient().namespaces().deleteNamespaceBundle(nsName.toString(), bundle.getBundleRange());
            }
        }
        // we have successfully removed all the ownership for the namespace, the policies znode can be deleted now
        globalZk().delete(path("policies", property, cluster, namespace), -1);
        policiesCache().invalidate(path("policies", property, cluster, namespace));
    } catch (PulsarAdminException cae) {
        throw new RestException(cae);
    } catch (Exception e) {
        log.error(String.format("[%s] Failed to remove owned namespace %s/%s/%s", clientAppId(), property, cluster, namespace), e);
    // avoid throwing exception in case of the second failure
    }
}
Also used : NamespaceBundle(com.yahoo.pulsar.common.naming.NamespaceBundle) Policies(com.yahoo.pulsar.common.policies.data.Policies) PersistencePolicies(com.yahoo.pulsar.common.policies.data.PersistencePolicies) RetentionPolicies(com.yahoo.pulsar.common.policies.data.RetentionPolicies) WebApplicationException(javax.ws.rs.WebApplicationException) NamespaceBundles(com.yahoo.pulsar.common.naming.NamespaceBundles) RestException(com.yahoo.pulsar.broker.web.RestException) URI(java.net.URI) URL(java.net.URL) RestException(com.yahoo.pulsar.broker.web.RestException) WebApplicationException(javax.ws.rs.WebApplicationException) SubscriptionBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) KeeperException(org.apache.zookeeper.KeeperException) PulsarAdminException(com.yahoo.pulsar.client.admin.PulsarAdminException) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) PulsarServerException(com.yahoo.pulsar.broker.PulsarServerException) NamespaceName(com.yahoo.pulsar.common.naming.NamespaceName) Stat(org.apache.zookeeper.data.Stat) ClusterData(com.yahoo.pulsar.common.policies.data.ClusterData) PulsarAdminException(com.yahoo.pulsar.client.admin.PulsarAdminException) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 60 with Stat

use of org.apache.flink.shaded.zookeeper3.org.apache.zookeeper.data.Stat in project pulsar by yahoo.

the class Namespaces method setPersistence.

@POST
@Path("/{property}/{cluster}/{namespace}/persistence")
@ApiOperation(value = "Set the persistence configuration for all the destinations on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace does not exist"), @ApiResponse(code = 409, message = "Concurrent modification") })
public void setPersistence(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, PersistencePolicies persistence) {
    validatePoliciesReadOnlyAccess();
    try {
        Stat nodeStat = new Stat();
        final String path = path("policies", property, cluster, namespace);
        byte[] content = globalZk().getData(path, null, nodeStat);
        Policies policies = jsonMapper().readValue(content, Policies.class);
        policies.persistence = persistence;
        globalZk().setData(path, jsonMapper().writeValueAsBytes(policies), nodeStat.getVersion());
        policiesCache().invalidate(path("policies", property, cluster, namespace));
        log.info("[{}] Successfully updated persistence configuration: namespace={}/{}/{}, map={}", clientAppId(), property, cluster, namespace, jsonMapper().writeValueAsString(policies.persistence));
    } catch (KeeperException.NoNodeException e) {
        log.warn("[{}] Failed to update persistence configuration for namespace {}/{}/{}: does not exist", clientAppId(), property, cluster, namespace);
        throw new RestException(Status.NOT_FOUND, "Namespace does not exist");
    } catch (KeeperException.BadVersionException e) {
        log.warn("[{}] Failed to update persistence configuration for namespace {}/{}/{}: concurrent modification", clientAppId(), property, cluster, namespace);
        throw new RestException(Status.CONFLICT, "Concurrent modification");
    } catch (Exception e) {
        log.error("[{}] Failed to update persistence configuration for namespace {}/{}/{}", clientAppId(), property, cluster, namespace, e);
        throw new RestException(e);
    }
}
Also used : Stat(org.apache.zookeeper.data.Stat) Policies(com.yahoo.pulsar.common.policies.data.Policies) PersistencePolicies(com.yahoo.pulsar.common.policies.data.PersistencePolicies) RetentionPolicies(com.yahoo.pulsar.common.policies.data.RetentionPolicies) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) RestException(com.yahoo.pulsar.broker.web.RestException) KeeperException(org.apache.zookeeper.KeeperException) RestException(com.yahoo.pulsar.broker.web.RestException) WebApplicationException(javax.ws.rs.WebApplicationException) SubscriptionBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) KeeperException(org.apache.zookeeper.KeeperException) PulsarAdminException(com.yahoo.pulsar.client.admin.PulsarAdminException) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) PulsarServerException(com.yahoo.pulsar.broker.PulsarServerException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Aggregations

Stat (org.apache.zookeeper.data.Stat)799 KeeperException (org.apache.zookeeper.KeeperException)266 Test (org.junit.Test)124 IOException (java.io.IOException)120 ZooKeeper (org.apache.zookeeper.ZooKeeper)88 ArrayList (java.util.ArrayList)67 Test (org.testng.annotations.Test)58 Test (org.junit.jupiter.api.Test)53 Watcher (org.apache.zookeeper.Watcher)49 AsyncCallback (org.apache.zookeeper.AsyncCallback)48 ACL (org.apache.zookeeper.data.ACL)47 List (java.util.List)43 CountDownLatch (java.util.concurrent.CountDownLatch)43 NoNodeException (org.apache.zookeeper.KeeperException.NoNodeException)39 WatchedEvent (org.apache.zookeeper.WatchedEvent)38 CuratorFramework (org.apache.curator.framework.CuratorFramework)37 Map (java.util.Map)34 HashMap (java.util.HashMap)32 WebApplicationException (javax.ws.rs.WebApplicationException)29 ExecutionException (java.util.concurrent.ExecutionException)27