ConnectorManager
注释掉
if (nodeManager.getCurrentNode().isCoordinator()) {
connector.getPlanOptimizerProvider()
.ifPresent(planOptimizerProvider -> connectorPlanOptimizerManager.addPlanOptimizerProvider(connectorId, planOptimizerProvider));
}
StaticCatalogStore
catalogsLoaded.set(true);下添加
// add catalogs automatically
new Thread(() -> {
try {
log.info("-- Catalog watcher thread start --");
startCatalogWatcher(catalogConfigurationDir);
}
catch (Exception e) {
e.printStackTrace();
}
}).start();
添加以下类
private void startCatalogWatcher(File catalogConfigurationDir) throws IOException, InterruptedException
{
WatchService watchService = FileSystems.getDefault().newWatchService();
Paths.get(catalogConfigurationDir.getAbsolutePath()).register(
watchService, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
WatchKey key = watchService.take();
for (WatchEvent> event : key.pollEvents()) {
String name = event.kind().name();
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
log.info("New file in catalog directory : " + event.context());
Path newCatalog = (Path) event.context();
addCatalog(newCatalog);
}
else if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
log.info("Delete file from catalog directory : " + event.context());
Path deletedCatalog = (Path) event.context();
deleteCatalog(deletedCatalog);
}
else if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
log.info("Modify file from catalog directory : " + event.context());
Path modifiedCatalog = (Path) event.context();
modifyCatalog(modifiedCatalog);
}
}
boolean valid = key.reset();
if (!valid) {
break;
}
}
}
private void addCatalog(Path catalogPath)
{
File file = new File(catalogConfigurationDir, catalogPath.getFileName().toString());
if (file.isFile() && file.getName().endsWith(".properties")) {
try {
TimeUnit.SECONDS.sleep(1);
loadCatalog(file);
updateDatasourcesAnnouncement(Files.getNameWithoutExtension(catalogPath.getFileName().toString()), PrestoServer.DatasourceAction.ADD);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
private void deleteCatalog(Path catalogPath)
{
if (catalogPath.getFileName().toString().endsWith(".properties")) {
String catalogName = Files.getNameWithoutExtension(catalogPath.getFileName().toString());
log.info("-- Removing catalog %s", catalogName);
ConnectorId connectorId = new ConnectorId(catalogName);
connectorManager.dropConnection(catalogName);
updateDatasourcesAnnouncement(catalogName, PrestoServer.DatasourceAction.DELETE);
}
}
private void modifyCatalog(Path catalogPath)
{
deleteCatalog(catalogPath);
addCatalog(catalogPath);
}
PrestoServer
直接覆盖
public class PrestoServer
implements Runnable
{
public static void main(String[] args)
{
new PrestoServer().run();
}
private final SqlParserOptions sqlParserOptions;
private static Announcer announcer;
public PrestoServer()
{
this(new SqlParserOptions());
}
private static final Logger log = Logger.get(PrestoServer.class);
public PrestoServer(SqlParserOptions sqlParserOptions)
{
this.sqlParserOptions = requireNonNull(sqlParserOptions, "sqlParserOptions is null");
}
@Override
public void run()
{
verifyJvmRequirements();
verifySystemTimeIsReasonable();
Logger log = Logger.get(PrestoServer.class);
ImmutableList.Builder modules = ImmutableList.builder();
modules.add(
new NodeModule(),
new DiscoveryModule(),
new HttpServerModule(),
new JsonModule(),
installModuleIf(
FeaturesConfig.class,
FeaturesConfig::isJsonSerdeCodeGenerationEnabled,
binder -> jsonBinder(binder).addModuleBinding().to(AfterburnerModule.class)),
new SmileModule(),
new JaxrsModule(true),
new MBeanModule(),
new JmxModule(),
new JmxHttpModule(),
new LogJmxModule(),
new TraceTokenModule(),
new JsonEventModule(),
new HttpEventModule(),
new ServerSecurityModule(),
new AccessControlModule(),
new EventListenerModule(),
new ServerMainModule(sqlParserOptions),
new GracefulShutdownModule(),
new WarningCollectorModule());
modules.addAll(getAdditionalModules());
Bootstrap app = new Bootstrap(modules.build());
try {
Injector injector = app.strictConfig().initialize();
injector.getInstance(PluginManager.class).loadPlugins();
injector.getInstance(StaticCatalogStore.class).loadCatalogs();
announcer = injector.getInstance(Announcer.class);
// TODO: remove this huge hack
updateConnectorIds(
announcer,
injector.getInstance(CatalogManager.class),
injector.getInstance(ServerConfig.class),
injector.getInstance(NodeSchedulerConfig.class));
injector.getInstance(StaticFunctionNamespaceStore.class).loadFunctionNamespaceManagers();
injector.getInstance(SessionPropertyDefaults.class).loadConfigurationManager();
injector.getInstance(ResourceGroupManager.class).loadConfigurationManager();
injector.getInstance(AccessControlManager.class).loadSystemAccessControl();
injector.getInstance(PasswordAuthenticatorManager.class).loadPasswordAuthenticator();
injector.getInstance(EventListenerManager.class).loadConfiguredEventListener();
announcer.start();
log.info("======== SERVER STARTED ========");
}
catch (Throwable e) {
log.error(e);
System.exit(1);
}
}
protected Iterable extends Module> getAdditionalModules()
{
return ImmutableList.of();
}
private static void updateConnectorIds(Announcer announcer, CatalogManager metadata, ServerConfig serverConfig, NodeSchedulerConfig schedulerConfig)
{
// get existing announcement
ServiceAnnouncement announcement = getPrestoAnnouncement(announcer.getServiceAnnouncements());
// get existing connectorIds
String property = nullToEmpty(announcement.getProperties().get("connectorIds"));
List values = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(property);
Set connectorIds = new LinkedHashSet<>(values);
// automatically build connectorIds if not configured
if (connectorIds.isEmpty()) {
List catalogs = metadata.getCatalogs();
// if this is a dedicated coordinator, only add jmx
if (serverConfig.isCoordinator() && !schedulerConfig.isIncludeCoordinator()) {
catalogs.stream()
.map(Catalog::getConnectorId)
.filter(connectorId -> connectorId.getCatalogName().equals("jmx"))
.map(Object::toString)
.forEach(connectorIds::add);
}
else {
catalogs.stream()
.map(Catalog::getConnectorId)
.map(Object::toString)
.forEach(connectorIds::add);
}
}
// build announcement with updated sources
ServiceAnnouncementBuilder builder = serviceAnnouncement(announcement.getType());
for (Map.Entry entry : announcement.getProperties().entrySet()) {
if (!entry.getKey().equals("connectorIds")) {
builder.addProperty(entry.getKey(), entry.getValue());
}
}
builder.addProperty("connectorIds", Joiner.on(',').join(connectorIds));
// update announcement
announcer.removeServiceAnnouncement(announcement.getId());
announcer.addServiceAnnouncement(builder.build());
}
private static ServiceAnnouncement getPrestoAnnouncement(Set announcements)
{
for (ServiceAnnouncement announcement : announcements) {
if (announcement.getType().equals("presto")) {
return announcement;
}
}
throw new IllegalArgumentException("Presto announcement not found: " + announcements);
}
public static void updateDatasourcesAnnouncement(String connectorId, DatasourceAction action)
{
// get existing announcement
ServiceAnnouncement announcement = getPrestoAnnouncement(announcer.getServiceAnnouncements());
// update datasources property
Map properties = new LinkedHashMap<>(announcement.getProperties());
for(String key:properties.keySet()){
log.info("old properties -------key"+key+"---------value"+(String)properties.get(key));
}
String property = nullToEmpty((String) properties.get("connectorIds"));
Set datasources = new LinkedHashSet<>(Splitter.on(',').trimResults().omitEmptyStrings().splitToList(property));
if (action == DatasourceAction.ADD) {
datasources.add(connectorId);
}
else if (action == DatasourceAction.DELETE) {
datasources.remove(connectorId);
}
properties.put("connectorIds", Joiner.on(',').join(datasources));
// update announcement
announcer.removeServiceAnnouncement(announcement.getId());
announcer.addServiceAnnouncement(serviceAnnouncement(announcement.getType()).addProperties(properties).build());
announcer.forceAnnounce();
}
public enum DatasourceAction{
ADD,DELETE;
}
}