blob: 89a945c2d31dc6f20c571bf87e0c60c1df2659da [file] [log] [blame]
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/client_config/resolver_registry.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#define MAX_RESOLVERS 10
static grpc_resolver_factory *g_all_of_the_resolvers[MAX_RESOLVERS];
static int g_number_of_resolvers = 0;
static char *g_default_resolver_prefix;
void grpc_resolver_registry_init(const char *default_resolver_prefix) {
g_number_of_resolvers = 0;
g_default_resolver_prefix = gpr_strdup(default_resolver_prefix);
}
void grpc_resolver_registry_shutdown(void) {
int i;
for (i = 0; i < g_number_of_resolvers; i++) {
grpc_resolver_factory_unref(g_all_of_the_resolvers[i]);
}
gpr_free(g_default_resolver_prefix);
}
void grpc_register_resolver_type(grpc_resolver_factory *factory) {
int i;
for (i = 0; i < g_number_of_resolvers; i++) {
GPR_ASSERT(0 != strcmp(factory->vtable->scheme,
g_all_of_the_resolvers[i]->vtable->scheme));
}
GPR_ASSERT(g_number_of_resolvers != MAX_RESOLVERS);
grpc_resolver_factory_ref(factory);
g_all_of_the_resolvers[g_number_of_resolvers++] = factory;
}
static grpc_resolver_factory *lookup_factory(grpc_uri *uri) {
int i;
/* handling NULL uri's here simplifies grpc_resolver_create */
if (!uri) return NULL;
for (i = 0; i < g_number_of_resolvers; i++) {
if (0 == strcmp(uri->scheme, g_all_of_the_resolvers[i]->vtable->scheme)) {
return g_all_of_the_resolvers[i];
}
}
return NULL;
}
static grpc_resolver_factory *resolve_factory(const char *target,
grpc_uri **uri) {
char *tmp;
grpc_resolver_factory *factory = NULL;
GPR_ASSERT(uri != NULL);
*uri = grpc_uri_parse(target, 1);
factory = lookup_factory(*uri);
if (factory == NULL) {
if (g_default_resolver_prefix != NULL) {
grpc_uri_destroy(*uri);
gpr_asprintf(&tmp, "%s%s", g_default_resolver_prefix, target);
*uri = grpc_uri_parse(tmp, 1);
factory = lookup_factory(*uri);
if (factory == NULL) {
grpc_uri_destroy(grpc_uri_parse(target, 0));
grpc_uri_destroy(grpc_uri_parse(tmp, 0));
gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target,
tmp);
}
gpr_free(tmp);
} else {
grpc_uri_destroy(grpc_uri_parse(target, 0));
gpr_log(GPR_ERROR, "don't know how to resolve '%s'", target);
}
}
return factory;
}
grpc_resolver *grpc_resolver_create(
const char *target, grpc_subchannel_factory *subchannel_factory) {
grpc_uri *uri = NULL;
grpc_resolver_factory *factory = resolve_factory(target, &uri);
grpc_resolver *resolver;
grpc_resolver_args args;
memset(&args, 0, sizeof(args));
args.uri = uri;
args.subchannel_factory = subchannel_factory;
resolver = grpc_resolver_factory_create_resolver(factory, &args);
grpc_uri_destroy(uri);
return resolver;
}
char *grpc_get_default_authority(const char *target) {
grpc_uri *uri = NULL;
grpc_resolver_factory *factory = resolve_factory(target, &uri);
char *authority = grpc_resolver_factory_get_default_authority(factory, uri);
grpc_uri_destroy(uri);
return authority;
}