Search in sources :

Example 1 with LookupData

use of com.yahoo.pulsar.common.lookup.data.LookupData in project pulsar by yahoo.

the class NamespaceService method internalGetWebServiceUrl.

private CompletableFuture<URL> internalGetWebServiceUrl(NamespaceBundle bundle, boolean authoritative, boolean isRequestHttps, boolean readOnly) {
    return findBrokerServiceUrl(bundle, authoritative, readOnly).thenApply(lookupResult -> {
        if (lookupResult != null) {
            try {
                LookupData lookupData = lookupResult.getLookupData();
                final String redirectUrl = isRequestHttps ? lookupData.getHttpUrlTls() : lookupData.getHttpUrl();
                return new URL(redirectUrl);
            } catch (Exception e) {
                LOG.warn("internalGetWebServiceUrl [{}]", e.getMessage(), e);
            }
        }
        return null;
    });
}
Also used : LookupData(com.yahoo.pulsar.common.lookup.data.LookupData) URL(java.net.URL) KeeperException(org.apache.zookeeper.KeeperException) ServiceUnitNotReadyException(com.yahoo.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) PulsarServerException(com.yahoo.pulsar.broker.PulsarServerException)

Example 2 with LookupData

use of com.yahoo.pulsar.common.lookup.data.LookupData in project pulsar by yahoo.

the class HttpLookupService method getBroker.

/**
     * Calls http-lookup api to find broker-service address which can serve a given topic. 
     * 
     * @param destination: topic-name
     * @return broker-socket-address that serves given topic 
     */
@SuppressWarnings("deprecation")
public CompletableFuture<InetSocketAddress> getBroker(DestinationName destination) {
    return httpClient.get(BasePath + destination.getLookupName(), LookupData.class).thenCompose(lookupData -> {
        URI uri = null;
        try {
            if (useTls) {
                uri = new URI(lookupData.getBrokerUrlTls());
            } else {
                String serviceUrl = lookupData.getBrokerUrl();
                if (serviceUrl == null) {
                    serviceUrl = lookupData.getNativeUrl();
                }
                uri = new URI(serviceUrl);
            }
            return CompletableFuture.completedFuture(new InetSocketAddress(uri.getHost(), uri.getPort()));
        } catch (Exception e) {
            log.warn("[{}] Lookup Failed due to invalid url {}, {}", destination, uri, e.getMessage());
            return FutureUtil.failedFuture(e);
        }
    });
}
Also used : InetSocketAddress(java.net.InetSocketAddress) LookupData(com.yahoo.pulsar.common.lookup.data.LookupData) URI(java.net.URI)

Example 3 with LookupData

use of com.yahoo.pulsar.common.lookup.data.LookupData in project pulsar by yahoo.

the class LookupDataTest method serializeToJsonTest.

@SuppressWarnings("unchecked")
@Test
void serializeToJsonTest() throws Exception {
    LookupData data = new LookupData("pulsar://localhost:8888", "pulsar://localhost:8884", "http://localhost:8080", "http://localhost:8081");
    ObjectMapper mapper = ObjectMapperFactory.getThreadLocal();
    String json = mapper.writeValueAsString(data);
    Map<String, String> jsonMap = mapper.readValue(json, Map.class);
    assertEquals(jsonMap.get("brokerUrl"), "pulsar://localhost:8888");
    assertEquals(jsonMap.get("brokerUrlTls"), "pulsar://localhost:8884");
    assertEquals(jsonMap.get("brokerUrlSsl"), "");
    assertEquals(jsonMap.get("nativeUrl"), "pulsar://localhost:8888");
    assertEquals(jsonMap.get("httpUrl"), "http://localhost:8080");
    assertEquals(jsonMap.get("httpUrlTls"), "http://localhost:8081");
}
Also used : LookupData(com.yahoo.pulsar.common.lookup.data.LookupData) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Test(org.testng.annotations.Test)

Example 4 with LookupData

use of com.yahoo.pulsar.common.lookup.data.LookupData in project pulsar by yahoo.

the class AdminApiTest method testPulsarAdminForUriAndUrlEncoding.

/**
     * This test-case verifies that broker should support both url/uri encoding for topic-name. It calls below api with
     * url-encoded and also uri-encoded topic-name in http request: a. PartitionedMetadataLookup b. TopicLookup c. Topic
     * Stats
     * 
     * @param topicName
     * @throws Exception
     */
@Test(dataProvider = "topicName")
public void testPulsarAdminForUriAndUrlEncoding(String topicName) throws Exception {
    final String ns1 = "prop-xyz/use/ns1";
    final String dn1 = "persistent://" + ns1 + "/" + topicName;
    final String urlEncodedTopic = Codec.encode(topicName);
    final String uriEncodedTopic = urlEncodedTopic.replaceAll("\\+", "%20");
    final int numOfPartitions = 4;
    admin.persistentTopics().createPartitionedTopic(dn1, numOfPartitions);
    // Create a consumer to get stats on this topic
    Consumer consumer1 = pulsarClient.subscribe(dn1, "my-subscriber-name", new ConsumerConfiguration());
    PersistentTopicsImpl persistent = (PersistentTopicsImpl) admin.persistentTopics();
    Field field = PersistentTopicsImpl.class.getDeclaredField("persistentTopics");
    field.setAccessible(true);
    WebTarget persistentTopics = (WebTarget) field.get(persistent);
    // (1) Get PartitionedMetadata : with Url and Uri encoding
    final CompletableFuture<PartitionedTopicMetadata> urlEncodedPartitionedMetadata = new CompletableFuture<>();
    // (a) Url encoding
    persistent.asyncGetRequest(persistentTopics.path(ns1).path(urlEncodedTopic).path("partitions"), new InvocationCallback<PartitionedTopicMetadata>() {

        @Override
        public void completed(PartitionedTopicMetadata response) {
            urlEncodedPartitionedMetadata.complete(response);
        }

        @Override
        public void failed(Throwable e) {
            Assert.fail(e.getMessage());
        }
    });
    final CompletableFuture<PartitionedTopicMetadata> uriEncodedPartitionedMetadata = new CompletableFuture<>();
    // (b) Uri encoding
    persistent.asyncGetRequest(persistentTopics.path(ns1).path(uriEncodedTopic).path("partitions"), new InvocationCallback<PartitionedTopicMetadata>() {

        @Override
        public void completed(PartitionedTopicMetadata response) {
            uriEncodedPartitionedMetadata.complete(response);
        }

        @Override
        public void failed(Throwable e) {
            uriEncodedPartitionedMetadata.completeExceptionally(e);
        }
    });
    assertEquals(urlEncodedPartitionedMetadata.get().partitions, numOfPartitions);
    assertEquals(urlEncodedPartitionedMetadata.get().partitions, (uriEncodedPartitionedMetadata.get().partitions));
    // (2) Get Topic Lookup
    LookupImpl lookup = (LookupImpl) admin.lookups();
    Field field2 = LookupImpl.class.getDeclaredField("v2lookup");
    field2.setAccessible(true);
    WebTarget target2 = (WebTarget) field2.get(lookup);
    // (a) Url encoding
    LookupData urlEncodedLookupData = lookup.request(target2.path("/destination/persistent").path(ns1 + "/" + urlEncodedTopic)).get(LookupData.class);
    // (b) Uri encoding
    LookupData uriEncodedLookupData = lookup.request(target2.path("/destination/persistent").path(ns1 + "/" + uriEncodedTopic)).get(LookupData.class);
    Assert.assertNotNull(urlEncodedLookupData.getBrokerUrl());
    assertEquals(urlEncodedLookupData.getBrokerUrl(), uriEncodedLookupData.getBrokerUrl());
    // (3) Get Topic Stats
    final CompletableFuture<PersistentTopicStats> urlStats = new CompletableFuture<>();
    // (a) Url encoding
    persistent.asyncGetRequest(persistentTopics.path(ns1).path(urlEncodedTopic + "-partition-1").path("stats"), new InvocationCallback<PersistentTopicStats>() {

        @Override
        public void completed(PersistentTopicStats response) {
            urlStats.complete(response);
        }

        @Override
        public void failed(Throwable e) {
            urlStats.completeExceptionally(e);
        }
    });
    // (b) Uri encoding
    final CompletableFuture<PersistentTopicStats> uriStats = new CompletableFuture<>();
    persistent.asyncGetRequest(persistentTopics.path(ns1).path(uriEncodedTopic + "-partition-1").path("stats"), new InvocationCallback<PersistentTopicStats>() {

        @Override
        public void completed(PersistentTopicStats response) {
            uriStats.complete(response);
        }

        @Override
        public void failed(Throwable e) {
            uriStats.completeExceptionally(e);
        }
    });
    assertEquals(urlStats.get().subscriptions.size(), 1);
    assertEquals(uriStats.get().subscriptions.size(), 1);
}
Also used : PersistentTopicsImpl(com.yahoo.pulsar.client.admin.internal.PersistentTopicsImpl) LookupData(com.yahoo.pulsar.common.lookup.data.LookupData) PersistentTopicStats(com.yahoo.pulsar.common.policies.data.PersistentTopicStats) Field(java.lang.reflect.Field) LookupImpl(com.yahoo.pulsar.client.admin.internal.LookupImpl) CompletableFuture(java.util.concurrent.CompletableFuture) Consumer(com.yahoo.pulsar.client.api.Consumer) ConsumerConfiguration(com.yahoo.pulsar.client.api.ConsumerConfiguration) WebTarget(javax.ws.rs.client.WebTarget) PartitionedTopicMetadata(com.yahoo.pulsar.common.partition.PartitionedTopicMetadata) Test(org.testng.annotations.Test) MockedPulsarServiceBaseTest(com.yahoo.pulsar.broker.auth.MockedPulsarServiceBaseTest)

Example 5 with LookupData

use of com.yahoo.pulsar.common.lookup.data.LookupData in project pulsar by yahoo.

the class DestinationLookup method lookupDestinationAsync.

/**
     * 
     * Lookup broker-service address for a given namespace-bundle which contains given topic.
     * 
     * a. Returns broker-address if namespace-bundle is already owned by any broker
     * b. If current-broker receives lookup-request and if it's not a leader
     * then current broker redirects request to leader by returning leader-service address. 
     * c. If current-broker is leader then it finds out least-loaded broker to own namespace bundle and 
     * redirects request by returning least-loaded broker.
     * d. If current-broker receives request to own the namespace-bundle then it owns a bundle and returns 
     * success(connect) response to client.
     * 
     * @param pulsarService
     * @param fqdn
     * @param authoritative
     * @param clientAppId
     * @param requestId
     * @return
     */
public static CompletableFuture<ByteBuf> lookupDestinationAsync(PulsarService pulsarService, DestinationName fqdn, boolean authoritative, String clientAppId, long requestId) {
    final CompletableFuture<ByteBuf> validationFuture = new CompletableFuture<>();
    final CompletableFuture<ByteBuf> lookupfuture = new CompletableFuture<>();
    final String cluster = fqdn.getCluster();
    // (1) validate cluster
    getClusterDataIfDifferentCluster(pulsarService, cluster, clientAppId).thenAccept(differentClusterData -> {
        if (differentClusterData != null) {
            if (log.isDebugEnabled()) {
                log.debug("[{}] Redirecting the lookup call to {}/{} cluster={}", clientAppId, differentClusterData.getBrokerServiceUrl(), differentClusterData.getBrokerServiceUrlTls(), cluster);
            }
            validationFuture.complete(newLookupResponse(differentClusterData.getBrokerServiceUrl(), differentClusterData.getBrokerServiceUrlTls(), true, LookupType.Redirect, requestId));
        } else {
            try {
                checkAuthorization(pulsarService, fqdn, clientAppId);
            } catch (RestException authException) {
                log.warn("Failed to authorized {} on cluster {}", clientAppId, fqdn.toString());
                validationFuture.complete(newLookupResponse(ServerError.AuthorizationError, authException.getMessage(), requestId));
                return;
            } catch (Exception e) {
                log.warn("Unknown error while authorizing {} on cluster {}", clientAppId, fqdn.toString());
                validationFuture.completeExceptionally(e);
                return;
            }
            validateReplicationSettingsOnNamespaceAsync(pulsarService, fqdn.getNamespaceObject()).thenAccept(success -> {
                validationFuture.complete(null);
            }).exceptionally(ex -> {
                validationFuture.complete(newLookupResponse(ServerError.MetadataError, ex.getMessage(), requestId));
                return null;
            });
        }
    }).exceptionally(ex -> {
        validationFuture.completeExceptionally(ex);
        return null;
    });
    // Initiate lookup once validation completes
    validationFuture.thenAccept(validaitonFailureResponse -> {
        if (validaitonFailureResponse != null) {
            lookupfuture.complete(validaitonFailureResponse);
        } else {
            pulsarService.getNamespaceService().getBrokerServiceUrlAsync(fqdn, authoritative).thenAccept(lookupResult -> {
                if (log.isDebugEnabled()) {
                    log.debug("[{}] Lookup result {}", fqdn.toString(), lookupResult);
                }
                LookupData lookupData = lookupResult.getLookupData();
                if (lookupResult.isRedirect()) {
                    boolean newAuthoritative = isLeaderBroker(pulsarService);
                    lookupfuture.complete(newLookupResponse(lookupData.getBrokerUrl(), lookupData.getBrokerUrlTls(), newAuthoritative, LookupType.Redirect, requestId));
                } else {
                    lookupfuture.complete(newLookupResponse(lookupData.getBrokerUrl(), lookupData.getBrokerUrlTls(), true, LookupType.Connect, requestId));
                }
            }).exceptionally(e -> {
                log.warn("Failed to lookup {} for topic {} with error {}", clientAppId, fqdn.toString(), e.getMessage(), e);
                lookupfuture.complete(newLookupResponse(ServerError.ServiceNotReady, e.getMessage(), requestId));
                return null;
            });
        }
    }).exceptionally(ex -> {
        log.warn("Failed to lookup {} for topic {} with error {}", clientAppId, fqdn.toString(), ex.getMessage(), ex);
        lookupfuture.complete(newLookupResponse(ServerError.ServiceNotReady, ex.getMessage(), requestId));
        return null;
    });
    return lookupfuture;
}
Also used : PathParam(javax.ws.rs.PathParam) RestException(com.yahoo.pulsar.broker.web.RestException) ServerError(com.yahoo.pulsar.common.api.proto.PulsarApi.ServerError) Encoded(javax.ws.rs.Encoded) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) URISyntaxException(java.net.URISyntaxException) Path(javax.ws.rs.Path) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) LookupData(com.yahoo.pulsar.common.lookup.data.LookupData) MediaType(javax.ws.rs.core.MediaType) QueryParam(javax.ws.rs.QueryParam) ClusterData(com.yahoo.pulsar.common.policies.data.ClusterData) ByteBuf(io.netty.buffer.ByteBuf) DefaultValue(javax.ws.rs.DefaultValue) PulsarService(com.yahoo.pulsar.broker.PulsarService) URI(java.net.URI) Codec(com.yahoo.pulsar.common.util.Codec) LookupType(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandLookupTopicResponse.LookupType) Status(javax.ws.rs.core.Response.Status) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) Logger(org.slf4j.Logger) AsyncResponse(javax.ws.rs.container.AsyncResponse) NoSwaggerDocumentation(com.yahoo.pulsar.broker.web.NoSwaggerDocumentation) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Commands.newLookupResponse(com.yahoo.pulsar.common.api.Commands.newLookupResponse) Suspended(javax.ws.rs.container.Suspended) PulsarWebResource(com.yahoo.pulsar.broker.web.PulsarWebResource) Response(javax.ws.rs.core.Response) WebApplicationException(javax.ws.rs.WebApplicationException) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException) CompletableFuture(java.util.concurrent.CompletableFuture) RestException(com.yahoo.pulsar.broker.web.RestException) ByteBuf(io.netty.buffer.ByteBuf) LookupData(com.yahoo.pulsar.common.lookup.data.LookupData) RestException(com.yahoo.pulsar.broker.web.RestException) URISyntaxException(java.net.URISyntaxException) WebApplicationException(javax.ws.rs.WebApplicationException) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException)

Aggregations

LookupData (com.yahoo.pulsar.common.lookup.data.LookupData)6 Test (org.testng.annotations.Test)3 URI (java.net.URI)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1 PulsarServerException (com.yahoo.pulsar.broker.PulsarServerException)1 PulsarService (com.yahoo.pulsar.broker.PulsarService)1 MockedPulsarServiceBaseTest (com.yahoo.pulsar.broker.auth.MockedPulsarServiceBaseTest)1 ServiceUnitNotReadyException (com.yahoo.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException)1 NoSwaggerDocumentation (com.yahoo.pulsar.broker.web.NoSwaggerDocumentation)1 PulsarWebResource (com.yahoo.pulsar.broker.web.PulsarWebResource)1 RestException (com.yahoo.pulsar.broker.web.RestException)1 LookupImpl (com.yahoo.pulsar.client.admin.internal.LookupImpl)1 PersistentTopicsImpl (com.yahoo.pulsar.client.admin.internal.PersistentTopicsImpl)1 Consumer (com.yahoo.pulsar.client.api.Consumer)1 ConsumerConfiguration (com.yahoo.pulsar.client.api.ConsumerConfiguration)1 PulsarClientException (com.yahoo.pulsar.client.api.PulsarClientException)1 Commands.newLookupResponse (com.yahoo.pulsar.common.api.Commands.newLookupResponse)1 LookupType (com.yahoo.pulsar.common.api.proto.PulsarApi.CommandLookupTopicResponse.LookupType)1