
com.orientechnologies.orient.server.OServer Maven / Gradle / Ivy
The newest version!
/*
*
* * Copyright 2010-2016 OrientDB LTD (http://orientdb.com)
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
* *
* * For more information: http://orientdb.com
*
*/
package com.orientechnologies.orient.server;
import com.orientechnologies.common.console.OConsoleReader;
import com.orientechnologies.common.console.ODefaultConsoleReader;
import com.orientechnologies.common.exception.OException;
import com.orientechnologies.common.io.OFileUtils;
import com.orientechnologies.common.log.OAnsiCode;
import com.orientechnologies.common.log.OLogManager;
import com.orientechnologies.common.parser.OSystemVariableResolver;
import com.orientechnologies.common.profiler.OAbstractProfiler.OProfilerHookValue;
import com.orientechnologies.common.profiler.OProfiler.METRIC_TYPE;
import com.orientechnologies.orient.core.OConstants;
import com.orientechnologies.orient.core.Orient;
import com.orientechnologies.orient.core.config.OContextConfiguration;
import com.orientechnologies.orient.core.config.OGlobalConfiguration;
import com.orientechnologies.orient.core.db.*;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTxInternal;
import com.orientechnologies.orient.core.exception.OConfigurationException;
import com.orientechnologies.orient.core.exception.ODatabaseException;
import com.orientechnologies.orient.core.exception.OStorageException;
import com.orientechnologies.orient.core.metadata.security.OSecurityUser;
import com.orientechnologies.orient.core.metadata.security.auth.OTokenAuthInfo;
import com.orientechnologies.orient.core.security.OInvalidPasswordException;
import com.orientechnologies.orient.core.security.OParsedToken;
import com.orientechnologies.orient.core.security.OSecuritySystem;
import com.orientechnologies.orient.server.config.*;
import com.orientechnologies.orient.server.distributed.ODistributedServerManager;
import com.orientechnologies.orient.server.distributed.config.ODistributedConfig;
import com.orientechnologies.orient.server.handler.OConfigurableHooksManager;
import com.orientechnologies.orient.server.network.OServerNetworkListener;
import com.orientechnologies.orient.server.network.OServerSocketFactory;
import com.orientechnologies.orient.server.network.protocol.ONetworkProtocol;
import com.orientechnologies.orient.server.network.protocol.ONetworkProtocolData;
import com.orientechnologies.orient.server.network.protocol.http.OHttpSessionManager;
import com.orientechnologies.orient.server.network.protocol.http.ONetworkProtocolHttpDb;
import com.orientechnologies.orient.server.plugin.OServerPlugin;
import com.orientechnologies.orient.server.plugin.OServerPluginInfo;
import com.orientechnologies.orient.server.plugin.OServerPluginManager;
import com.orientechnologies.orient.server.token.OTokenHandlerImpl;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
public class OServer {
private static final String ROOT_PASSWORD_VAR = "ORIENTDB_ROOT_PASSWORD";
private static ThreadGroup threadGroup;
private static final Map distributedServers =
new ConcurrentHashMap();
private CountDownLatch startupLatch;
private CountDownLatch shutdownLatch;
private final boolean shutdownEngineOnExit;
protected ReentrantLock lock = new ReentrantLock();
protected volatile boolean running = false;
protected volatile boolean rejectRequests = true;
protected OServerConfigurationManager serverCfg;
protected OContextConfiguration contextConfiguration;
protected OServerShutdownHook shutdownHook;
protected Map> networkProtocols =
new HashMap>();
protected Map networkSocketFactories =
new HashMap();
protected List networkListeners = new ArrayList();
protected List lifecycleListeners =
new ArrayList();
protected OServerPluginManager pluginManager;
protected OConfigurableHooksManager hookManager;
protected ODistributedServerManager distributedManager;
private final Map variables = new HashMap();
private String serverRootDirectory;
private String databaseDirectory;
private OClientConnectionManager clientConnectionManager;
private OHttpSessionManager httpSessionManager;
private OPushManager pushManager;
private ClassLoader extensionClassLoader;
private OTokenHandler tokenHandler;
private OrientDB context;
private OrientDBInternal databases;
protected Date startedOn = new Date();
public OServer() {
this(!Orient.instance().isInsideWebContainer());
}
public OServer(boolean shutdownEngineOnExit) {
final boolean insideWebContainer = Orient.instance().isInsideWebContainer();
if (insideWebContainer && shutdownEngineOnExit) {
OLogManager.instance()
.warnNoDb(
this,
"OrientDB instance is running inside of web application, "
+ "it is highly unrecommended to force to shutdown OrientDB engine on server shutdown");
}
this.shutdownEngineOnExit = shutdownEngineOnExit;
serverRootDirectory =
OSystemVariableResolver.resolveSystemVariables("${" + Orient.ORIENTDB_HOME + "}", ".");
OLogManager.instance().installCustomFormatter();
defaultSettings();
threadGroup = new ThreadGroup("OrientDB Server");
System.setProperty("com.sun.management.jmxremote", "true");
Orient.instance().startup();
if (OGlobalConfiguration.PROFILER_ENABLED.getValueAsBoolean()
&& !Orient.instance().getProfiler().isRecording())
Orient.instance().getProfiler().startRecording();
if (shutdownEngineOnExit) {
shutdownHook = new OServerShutdownHook(this);
}
}
public static OServer startFromFileConfig(String config)
throws ClassNotFoundException, InstantiationException, IOException, IllegalAccessException {
OServer server = new OServer(false);
server.startup(config);
server.activate();
return server;
}
public static OServer startFromClasspathConfig(String config)
throws ClassNotFoundException, InstantiationException, IOException, IllegalAccessException {
OServer server = new OServer(false);
server.startup(Thread.currentThread().getContextClassLoader().getResourceAsStream(config));
server.activate();
return server;
}
public static OServer startFromStreamConfig(InputStream config)
throws ClassNotFoundException, InstantiationException, IOException, IllegalAccessException {
OServer server = new OServer(false);
server.startup(config);
server.activate();
return server;
}
public static OServer getInstance(final String iServerId) {
return distributedServers.get(iServerId);
}
public static OServer getInstanceByPath(final String iPath) {
for (Map.Entry entry : distributedServers.entrySet()) {
if (iPath.startsWith(entry.getValue().getDatabaseDirectory())) return entry.getValue();
}
return null;
}
public static void registerServerInstance(final String iServerId, final OServer iServer) {
distributedServers.put(iServerId, iServer);
}
public static void unregisterServerInstance(final String iServerId) {
distributedServers.remove(iServerId);
}
/**
* Set the preferred {@link ClassLoader} used to load extensions.
*
* @since 2.1
*/
public void setExtensionClassLoader(/* @Nullable */ final ClassLoader extensionClassLoader) {
this.extensionClassLoader = extensionClassLoader;
}
/**
* Get the preferred {@link ClassLoader} used to load extensions.
*
* @since 2.1
*/
/* @Nullable */
public ClassLoader getExtensionClassLoader() {
return extensionClassLoader;
}
public OSecuritySystem getSecurity() {
return databases.getSecuritySystem();
}
public boolean isActive() {
return running;
}
public OClientConnectionManager getClientConnectionManager() {
return clientConnectionManager;
}
public OHttpSessionManager getHttpSessionManager() {
return httpSessionManager;
}
public OPushManager getPushManager() {
return pushManager;
}
public void saveConfiguration() throws IOException {
serverCfg.saveConfiguration();
}
public void restart()
throws ClassNotFoundException, InvocationTargetException, InstantiationException,
NoSuchMethodException, IllegalAccessException, IOException {
try {
deinit();
} finally {
Orient.instance().startup();
startup(serverCfg.getConfiguration());
activate();
}
}
public OSystemDatabase getSystemDatabase() {
return databases.getSystemDatabase();
}
public String getServerId() {
return getSystemDatabase().getServerId();
}
/** Load an extension class by name. */
private Class> loadClass(final String name) throws ClassNotFoundException {
Class> loaded = tryLoadClass(extensionClassLoader, name);
if (loaded == null) {
loaded = tryLoadClass(Thread.currentThread().getContextClassLoader(), name);
if (loaded == null) {
loaded = tryLoadClass(getClass().getClassLoader(), name);
if (loaded == null) {
loaded = Class.forName(name);
}
}
}
return loaded;
}
/** Attempt to load a class from givenstar class-loader. */
/* @Nullable */
private Class> tryLoadClass(/* @Nullable */ final ClassLoader classLoader, final String name) {
if (classLoader != null) {
try {
return classLoader.loadClass(name);
} catch (ClassNotFoundException e) {
// ignore
}
}
return null;
}
public OServer startup() throws OConfigurationException {
String config = OServerConfiguration.DEFAULT_CONFIG_FILE;
if (System.getProperty(OServerConfiguration.PROPERTY_CONFIG_FILE) != null)
config = System.getProperty(OServerConfiguration.PROPERTY_CONFIG_FILE);
Orient.instance().startup();
startup(new File(OSystemVariableResolver.resolveSystemVariables(config)));
return this;
}
public OServer startup(final File iConfigurationFile) throws OConfigurationException {
// Startup function split to allow pre-activation changes
try {
serverCfg = new OServerConfigurationManager(iConfigurationFile);
return startupFromConfiguration();
} catch (IOException e) {
final String message =
"Error on reading server configuration from file: " + iConfigurationFile;
OLogManager.instance().error(this, message, e);
throw OException.wrapException(new OConfigurationException(message), e);
}
}
public OServer startup(final String iConfiguration) throws IOException {
return startup(new ByteArrayInputStream(iConfiguration.getBytes()));
}
public OServer startup(final InputStream iInputStream) throws IOException {
if (iInputStream == null) throw new OConfigurationException("Configuration file is null");
serverCfg = new OServerConfigurationManager(iInputStream);
// Startup function split to allow pre-activation changes
return startupFromConfiguration();
}
public OServer startup(final OServerConfiguration iConfiguration)
throws IllegalArgumentException, SecurityException, IOException {
serverCfg = new OServerConfigurationManager(iConfiguration);
return startupFromConfiguration();
}
public OServer startupFromConfiguration() throws IOException {
OLogManager.instance()
.info(this, "OrientDB Server v" + OConstants.getVersion() + " is starting up...");
Orient.instance();
if (startupLatch == null) startupLatch = new CountDownLatch(1);
if (shutdownLatch == null) shutdownLatch = new CountDownLatch(1);
initFromConfiguration();
clientConnectionManager = new OClientConnectionManager(this);
httpSessionManager = new OHttpSessionManager(this);
pushManager = new OPushManager();
rejectRequests = false;
if (contextConfiguration.getValueAsBoolean(
OGlobalConfiguration.ENVIRONMENT_DUMP_CFG_AT_STARTUP)) {
System.out.println("Dumping environment after server startup...");
OGlobalConfiguration.dumpConfiguration(System.out);
}
databaseDirectory =
contextConfiguration.getValue("server.database.path", serverRootDirectory + "/databases/");
databaseDirectory =
OFileUtils.getPath(OSystemVariableResolver.resolveSystemVariables(databaseDirectory));
databaseDirectory = databaseDirectory.replace("//", "/");
// CONVERT IT TO ABSOLUTE PATH
databaseDirectory = (new File(databaseDirectory)).getCanonicalPath();
databaseDirectory = OFileUtils.getPath(databaseDirectory);
if (!databaseDirectory.endsWith("/")) databaseDirectory += "/";
OrientDBConfigBuilder builder = OrientDBConfig.builder();
for (OServerUserConfiguration user : serverCfg.getUsers()) {
builder.addGlobalUser(user.getName(), user.getPassword(), user.getResources());
}
OrientDBConfig config =
builder
.fromContext(contextConfiguration)
.setSecurityConfig(new OServerSecurityConfig(this, this.serverCfg))
.build();
if (contextConfiguration.getValueAsBoolean(
OGlobalConfiguration.SERVER_BACKWARD_COMPATIBILITY)) {
databases =
ODatabaseDocumentTxInternal.getOrCreateEmbeddedFactory(this.databaseDirectory, config);
} else {
OServerConfiguration configuration = getConfiguration();
if (configuration.distributed != null && configuration.distributed.enabled) {
try {
OrientDBConfig orientDBConfig =
ODistributedConfig.buildConfig(
contextConfiguration, ODistributedConfig.fromEnv(configuration.distributed));
databases = OrientDBInternal.distributed(this.databaseDirectory, orientDBConfig);
} catch (ODatabaseException ex) {
databases = OrientDBInternal.embedded(this.databaseDirectory, config);
}
} else {
try {
databases = OrientDBInternal.distributed(this.databaseDirectory, config);
} catch (ODatabaseException ex) {
databases = OrientDBInternal.embedded(this.databaseDirectory, config);
}
}
}
if (databases instanceof OServerAware) {
((OServerAware) databases).init(this);
}
context = databases.newOrientDB();
OLogManager.instance()
.info(this, "Databases directory: " + new File(databaseDirectory).getAbsolutePath());
Orient.instance()
.getProfiler()
.registerHookValue(
"system.databases",
"List of databases configured in Server",
METRIC_TYPE.TEXT,
new OProfilerHookValue() {
@Override
public Object getValue() {
final StringBuilder dbs = new StringBuilder(64);
for (String dbName : getAvailableStorageNames().keySet()) {
if (dbs.length() > 0) dbs.append(',');
dbs.append(dbName);
}
return dbs.toString();
}
});
return this;
}
@SuppressWarnings("unchecked")
public OServer activate()
throws ClassNotFoundException, InstantiationException, IllegalAccessException {
lock.lock();
try {
// Checks to see if the OrientDB System Database exists and creates it if not.
// Make sure this happens after setSecurity() is called.
initSystemDatabase();
for (OServerLifecycleListener l : lifecycleListeners) l.onBeforeActivate();
final OServerConfiguration configuration = serverCfg.getConfiguration();
tokenHandler =
new OTokenHandlerImpl(
this.databases.getSecuritySystem().getTokenSign(), this.getContextConfiguration());
if (configuration.network != null) {
// REGISTER/CREATE SOCKET FACTORIES
if (configuration.network.sockets != null) {
for (OServerSocketFactoryConfiguration f : configuration.network.sockets) {
Class extends OServerSocketFactory> fClass =
(Class extends OServerSocketFactory>) loadClass(f.implementation);
OServerSocketFactory factory = fClass.newInstance();
try {
factory.config(f.name, f.parameters);
networkSocketFactories.put(f.name, factory);
} catch (OConfigurationException e) {
OLogManager.instance().error(this, "Error creating socket factory", e);
}
}
}
// REGISTER PROTOCOLS
for (OServerNetworkProtocolConfiguration p : configuration.network.protocols)
networkProtocols.put(
p.name, (Class extends ONetworkProtocol>) loadClass(p.implementation));
// STARTUP LISTENERS
for (OServerNetworkListenerConfiguration l : configuration.network.listeners)
networkListeners.add(
new OServerNetworkListener(
this,
networkSocketFactories.get(l.socket),
l.ipAddress,
l.portRange,
l.protocol,
networkProtocols.get(l.protocol),
l.parameters,
l.commands));
} else OLogManager.instance().warn(this, "Network configuration was not found");
try {
loadStorages();
loadUsers();
loadDatabases();
} catch (IOException e) {
final String message = "Error on reading server configuration";
OLogManager.instance().error(this, message, e);
throw OException.wrapException(new OConfigurationException(message), e);
}
registerPlugins();
for (OServerLifecycleListener l : lifecycleListeners) l.onAfterActivate();
running = true;
String httpAddress = "localhost:2480";
boolean ssl = false;
for (OServerNetworkListener listener : getNetworkListeners()) {
if (listener.getProtocolType().getName().equals(ONetworkProtocolHttpDb.class.getName())) {
httpAddress = listener.getListeningAddress(true);
ssl = listener.getSocketFactory().isEncrypted();
}
}
String proto;
if (ssl) {
proto = "https";
} else {
proto = "http";
}
OLogManager.instance()
.info(
this,
"OrientDB Studio available at $ANSI{blue %s://%s/studio/index.html}",
proto,
httpAddress);
OLogManager.instance()
.info(
this,
"$ANSI{green:italic OrientDB Server is active} v" + OConstants.getVersion() + ".");
} catch (ClassNotFoundException
| InstantiationException
| IllegalAccessException
| RuntimeException e) {
deinit();
throw e;
} finally {
lock.unlock();
startupLatch.countDown();
}
if (distributedManager != null) {
try {
distributedManager.waitUntilNodeOnline();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
return this;
}
public void removeShutdownHook() {
if (shutdownHook != null) {
shutdownHook.cancel();
shutdownHook = null;
}
}
public boolean shutdown() {
try {
boolean res = deinit();
return res;
} finally {
startupLatch = null;
if (shutdownLatch != null) {
shutdownLatch.countDown();
shutdownLatch = null;
}
if (shutdownEngineOnExit) {
OLogManager.instance().shutdown();
}
}
}
protected boolean deinit() {
try {
running = false;
OLogManager.instance().info(this, "OrientDB Server is shutting down...");
if (shutdownHook != null) shutdownHook.cancel();
Orient.instance().getProfiler().unregisterHookValue("system.databases");
for (OServerLifecycleListener l : lifecycleListeners) l.onBeforeDeactivate();
lock.lock();
try {
if (networkListeners.size() > 0) {
// SHUTDOWN LISTENERS
OLogManager.instance().info(this, "Shutting down listeners:");
// SHUTDOWN LISTENERS
for (OServerNetworkListener l : networkListeners) {
OLogManager.instance().info(this, "- %s", l);
try {
l.shutdown();
} catch (Exception e) {
OLogManager.instance().error(this, "Error during shutdown of listener %s.", e, l);
}
}
}
if (networkProtocols.size() > 0) {
// PROTOCOL SHUTDOWN
OLogManager.instance().info(this, "Shutting down protocols");
networkProtocols.clear();
}
for (OServerLifecycleListener l : lifecycleListeners)
try {
l.onAfterDeactivate();
} catch (Exception e) {
OLogManager.instance()
.error(this, "Error during deactivation of server lifecycle listener %s", e, l);
}
rejectRequests = true;
pushManager.shutdown();
clientConnectionManager.shutdown();
httpSessionManager.shutdown();
if (pluginManager != null) pluginManager.shutdown();
networkListeners.clear();
} finally {
lock.unlock();
}
if (shutdownEngineOnExit && !Orient.isRegisterDatabaseByPath())
try {
OLogManager.instance().info(this, "Shutting down databases:");
Orient.instance().shutdown();
} catch (Exception e) {
OLogManager.instance().error(this, "Error during OrientDB shutdown", e);
}
if (!getContextConfiguration()
.getValueAsBoolean(OGlobalConfiguration.SERVER_BACKWARD_COMPATIBILITY)
&& databases != null) {
databases.close();
databases = null;
}
} finally {
OLogManager.instance().info(this, "OrientDB Server shutdown complete\n");
OLogManager.instance().flush();
}
return true;
}
public boolean rejectRequests() {
return rejectRequests;
}
public void waitForShutdown() {
try {
if (shutdownLatch != null) shutdownLatch.await();
} catch (InterruptedException e) {
OLogManager.instance().error(this, "Error during waiting for OrientDB shutdown", e);
}
}
public Map getAvailableStorageNames() {
Set dbs = listDatabases();
Map toSend = new HashMap();
for (String dbName : dbs) {
toSend.put(dbName, dbName);
}
return toSend;
}
/** Opens all the available server's databases. */
protected void loadDatabases() {
if (!getContextConfiguration()
.getValueAsBoolean(OGlobalConfiguration.SERVER_OPEN_ALL_DATABASES_AT_STARTUP)) return;
getDatabases().loadAllDatabases();
}
private boolean askForEncryptionKey(final String iDatabaseName) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
System.out.println();
System.out.println();
System.out.println(
OAnsiCode.format(
"$ANSI{yellow +--------------------------------------------------------------------------+}"));
System.out.println(
OAnsiCode.format(
String.format(
"$ANSI{yellow | INSERT THE KEY FOR THE ENCRYPTED DATABASE %-31s|}",
"'" + iDatabaseName + "'")));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow +--------------------------------------------------------------------------+}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow | To avoid this message set the environment variable or JVM setting |}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow | 'storage.encryptionKey' to the key to use. |}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow +--------------------------------------------------------------------------+}"));
System.out.print(
OAnsiCode.format("\n$ANSI{yellow Database encryption key [BLANK=to skip opening]: }"));
final OConsoleReader reader = new ODefaultConsoleReader();
try {
String key = reader.readPassword();
if (key != null) {
key = key.trim();
if (!key.isEmpty()) {
OGlobalConfiguration.STORAGE_ENCRYPTION_KEY.setValue(key);
return true;
}
}
} catch (IOException e) {
}
return false;
}
public String getDatabaseDirectory() {
return databaseDirectory;
}
public ThreadGroup getServerThreadGroup() {
return threadGroup;
}
/**
* Authenticate a server user.
*
* @param iUserName Username to authenticate
* @param iPassword Password in clear
* @return true if authentication is ok, otherwise false
*/
public boolean authenticate(
final String iUserName, final String iPassword, final String iResourceToCheck) {
// FALSE INDICATES WRONG PASSWORD OR NO AUTHORIZATION
return authenticateUser(iUserName, iPassword, iResourceToCheck) != null;
}
// Returns null if the user cannot be authenticated. Otherwise returns the
// OServerUserConfiguration user.
public OSecurityUser authenticateUser(
final String iUserName, final String iPassword, final String iResourceToCheck) {
return databases
.getSecuritySystem()
.authenticateAndAuthorize(iUserName, iPassword, iResourceToCheck);
}
public boolean existsStoragePath(final String iURL) {
return serverCfg.getConfiguration().getStoragePath(iURL) != null;
}
public OServerConfiguration getConfiguration() {
return serverCfg.getConfiguration();
}
public Map> getNetworkProtocols() {
return networkProtocols;
}
public List getNetworkListeners() {
return networkListeners;
}
@SuppressWarnings("unchecked")
public RET getListenerByProtocol(
final Class extends ONetworkProtocol> iProtocolClass) {
for (OServerNetworkListener l : networkListeners)
if (iProtocolClass.isAssignableFrom(l.getProtocolType())) return (RET) l;
return null;
}
public Collection getPlugins() {
return pluginManager != null ? pluginManager.getPlugins() : null;
}
public OContextConfiguration getContextConfiguration() {
return contextConfiguration;
}
@SuppressWarnings("unchecked")
public RET getPluginByClass(final Class iPluginClass) {
if (startupLatch == null)
throw new ODatabaseException("Error on plugin lookup: the server did not start correctly");
try {
startupLatch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (!running)
throw new ODatabaseException("Error on plugin lookup the server did not start correctly.");
for (OServerPluginInfo h : getPlugins())
if (h.getInstance() != null && h.getInstance().getClass().equals(iPluginClass))
return (RET) h.getInstance();
return null;
}
@SuppressWarnings("unchecked")
public RET getPlugin(final String iName) {
if (startupLatch == null)
throw new ODatabaseException("Error on plugin lookup: the server did not start correctly");
try {
startupLatch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (!running)
throw new ODatabaseException("Error on plugin lookup: the server did not start correctly");
final OServerPluginInfo p = pluginManager.getPluginByName(iName);
if (p != null) return (RET) p.getInstance();
return null;
}
public Object getVariable(final String iName) {
return variables.get(iName);
}
public OServer setVariable(final String iName, final Object iValue) {
if (iValue == null) variables.remove(iName);
else variables.put(iName, iValue);
return this;
}
public void addTemporaryUser(
final String iName, final String iPassword, final String iPermissions) {
databases.getSecuritySystem().addTemporaryUser(iName, iPassword, iPermissions);
}
public OServer registerLifecycleListener(final OServerLifecycleListener iListener) {
lifecycleListeners.add(iListener);
return this;
}
public OServer unregisterLifecycleListener(final OServerLifecycleListener iListener) {
lifecycleListeners.remove(iListener);
return this;
}
public ODatabaseDocumentInternal openDatabase(final String iDbUrl, final OParsedToken iToken) {
return databases.open(new OTokenAuthInfo(iToken), OrientDBConfig.defaultConfig());
}
public ODatabaseDocumentInternal openDatabase(
final String iDbUrl, final String user, final String password) {
return openDatabase(iDbUrl, user, password, null);
}
public ODatabaseDocumentInternal openDatabase(
final String iDbUrl, final String user, final String password, ONetworkProtocolData data) {
final ODatabaseDocumentInternal database;
boolean serverAuth = false;
database = databases.open(iDbUrl, user, password);
if (OSecurityUser.SERVER_USER_TYPE.equals(database.getUser().getUserType())) {
serverAuth = true;
}
if (serverAuth && data != null) {
data.serverUser = true;
data.serverUsername = user;
} else if (data != null) {
data.serverUser = false;
data.serverUsername = null;
}
return database;
}
public ODatabaseDocumentInternal openDatabase(String database) {
return getDatabases().openNoAuthorization(database);
}
public ODistributedServerManager getDistributedManager() {
return distributedManager;
}
public void setServerRootDirectory(final String rootDirectory) {
this.serverRootDirectory = rootDirectory;
}
protected void initFromConfiguration() {
final OServerConfiguration cfg = serverCfg.getConfiguration();
// FILL THE CONTEXT CONFIGURATION WITH SERVER'S PARAMETERS
contextConfiguration = new OContextConfiguration();
if (cfg.properties != null)
for (OServerEntryConfiguration prop : cfg.properties)
contextConfiguration.setValue(prop.name, prop.value);
hookManager = new OConfigurableHooksManager(cfg);
}
public OConfigurableHooksManager getHookManager() {
return hookManager;
}
protected void loadUsers() throws IOException {
final OServerConfiguration configuration = serverCfg.getConfiguration();
if (configuration.isAfterFirstTime) {
return;
}
configuration.isAfterFirstTime = true;
createDefaultServerUsers();
}
/** Load configured storages. */
protected void loadStorages() {
final OServerConfiguration configuration = serverCfg.getConfiguration();
if (configuration.storages == null) return;
for (OServerStorageConfiguration stg : configuration.storages) {
if (stg.loadOnStartup) {
String url = stg.path;
if (url.endsWith("/")) url = url.substring(0, url.length() - 1);
url = url.replace('\\', '/');
int typeIndex = url.indexOf(':');
if (typeIndex <= 0)
throw new OConfigurationException(
"Error in database URL: the engine was not specified. Syntax is: "
+ Orient.URL_SYNTAX
+ ". URL was: "
+ url);
String remoteUrl = url.substring(typeIndex + 1);
int index = remoteUrl.lastIndexOf('/');
String baseUrl;
if (index > 0) {
baseUrl = remoteUrl.substring(0, index);
} else {
baseUrl = "./";
}
databases.initCustomStorage(stg.name, baseUrl, stg.userName, stg.userPassword);
}
}
}
protected void createDefaultServerUsers() throws IOException {
// ORIENTDB_ROOT_PASSWORD ENV OR JVM SETTING
String envRootPassword = OSystemVariableResolver.resolveVariable(ROOT_PASSWORD_VAR);
if (envRootPassword != null) {
envRootPassword = envRootPassword.trim();
if (envRootPassword.isEmpty()) envRootPassword = null;
}
OSecuritySystem securitySystem = databases.getSecuritySystem();
if (securitySystem != null && !securitySystem.arePasswordsStored()) {
return;
}
boolean existServerUser = existsSystemUser(OServerConfiguration.DEFAULT_ROOT_USER);
if (existServerUser && envRootPassword != null) {
final String pwd = envRootPassword;
getSystemDatabase()
.executeWithDB(
(db) -> {
db.command(
"update OUser set password= ? WHERE name = ?",
pwd,
OServerConfiguration.DEFAULT_ROOT_USER)
.close();
return (Void) null;
});
}
boolean existsRoot =
serverCfg.existsUser(OServerConfiguration.DEFAULT_ROOT_USER) || existServerUser;
if (envRootPassword == null && !existsRoot) {
try {
// WAIT ANY LOG IS PRINTED
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println();
System.out.println();
System.out.println(
OAnsiCode.format(
"$ANSI{yellow +---------------------------------------------------------------+}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow | WARNING: FIRST RUN CONFIGURATION |}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow +---------------------------------------------------------------+}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow | This is the first time the server is running. Please type a |}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow | password of your choice for the 'root' user or leave it blank |}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow | to auto-generate it. |}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow | |}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow | To avoid this message set the environment variable or JVM |}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow | setting ORIENTDB_ROOT_PASSWORD to the root password to use. |}"));
System.out.println(
OAnsiCode.format(
"$ANSI{yellow +---------------------------------------------------------------+}"));
final OConsoleReader console = new ODefaultConsoleReader();
// ASK FOR PASSWORD + CONFIRM
do {
System.out.print(
OAnsiCode.format("\n$ANSI{yellow Root password [BLANK=auto generate it]: }"));
envRootPassword = console.readPassword();
if (envRootPassword != null) {
envRootPassword = envRootPassword.trim();
if (envRootPassword.isEmpty()) envRootPassword = null;
}
if (envRootPassword != null) {
System.out.print(OAnsiCode.format("$ANSI{yellow Please confirm the root password: }"));
String rootConfirmPassword = console.readPassword();
if (rootConfirmPassword != null) {
rootConfirmPassword = rootConfirmPassword.trim();
if (rootConfirmPassword.isEmpty()) rootConfirmPassword = null;
}
if (!envRootPassword.equals(rootConfirmPassword)) {
System.out.println(
OAnsiCode.format(
"$ANSI{red ERROR: Passwords don't match, please reinsert both of them, or press ENTER to auto generate it}"));
} else
// PASSWORDS MATCH
try {
if (getSecurity() != null) {
getSecurity().validatePassword("root", envRootPassword);
}
// PASSWORD IS STRONG ENOUGH
break;
} catch (OInvalidPasswordException ex) {
System.out.println(
OAnsiCode.format(
"$ANSI{red ERROR: Root password does not match the password policies}"));
if (ex.getMessage() != null) {
System.out.println(ex.getMessage());
}
}
}
} while (envRootPassword != null);
} else
OLogManager.instance()
.info(this, "Using ORIENTDB_ROOT_PASSWORD variable, for root's password");
if (!existsRoot) {
context.execute(
"CREATE SYSTEM USER "
+ OServerConfiguration.DEFAULT_ROOT_USER
+ " IDENTIFIED BY ? ROLE root",
envRootPassword);
}
if (!existsSystemUser(OServerConfiguration.GUEST_USER)) {
context.execute(
"CREATE SYSTEM USER " + OServerConfiguration.GUEST_USER + " IDENTIFIED BY ? ROLE guest",
OServerConfiguration.DEFAULT_GUEST_PASSWORD);
}
}
private boolean existsSystemUser(String user) {
return Boolean.TRUE.equals(
context.execute("EXISTS SYSTEM USER ?", user).next().getProperty("exists"));
}
public OServerPluginManager getPluginManager() {
return pluginManager;
}
protected void registerPlugins()
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
pluginManager = new OServerPluginManager();
pluginManager.config(this);
pluginManager.startup();
// PLUGINS CONFIGURED IN XML
final OServerConfiguration configuration = serverCfg.getConfiguration();
if (configuration.handlers != null) {
// ACTIVATE PLUGINS
final List plugins = new ArrayList();
for (OServerHandlerConfiguration h : configuration.handlers) {
if (h.parameters != null) {
// CHECK IF IT'S ENABLED
boolean enabled = true;
for (OServerParameterConfiguration p : h.parameters) {
if (p.name.equals("enabled")) {
enabled = false;
String value = OSystemVariableResolver.resolveSystemVariables(p.value);
if (value != null) {
value = value.trim();
if ("true".equalsIgnoreCase(value)) {
enabled = true;
break;
}
}
}
}
if (!enabled)
// SKIP IT
continue;
}
final OServerPlugin plugin = (OServerPlugin) loadClass(h.clazz).newInstance();
if (plugin instanceof ODistributedServerManager)
distributedManager = (ODistributedServerManager) plugin;
pluginManager.registerPlugin(
new OServerPluginInfo(plugin.getName(), null, null, null, plugin, null, 0, null));
pluginManager.callListenerBeforeConfig(plugin, h.parameters);
plugin.config(this, h.parameters);
pluginManager.callListenerAfterConfig(plugin, h.parameters);
plugins.add(plugin);
}
// START ALL THE CONFIGURED PLUGINS
for (OServerPlugin plugin : plugins) {
pluginManager.callListenerBeforeStartup(plugin);
plugin.startup();
pluginManager.callListenerAfterStartup(plugin);
}
}
}
protected void defaultSettings() {}
public OTokenHandler getTokenHandler() {
return tokenHandler;
}
public ThreadGroup getThreadGroup() {
return Orient.instance().getThreadGroup();
}
private void initSystemDatabase() {
databases.getSystemDatabase().init();
}
public OrientDBInternal getDatabases() {
return databases;
}
public OrientDB getContext() {
return context;
}
public void dropDatabase(String databaseName) {
if (databases.exists(databaseName, null, null)) {
databases.drop(databaseName, null, null);
} else {
throw new OStorageException("Database with name '" + databaseName + "' does not exist");
}
}
public boolean existsDatabase(String databaseName) {
return databases.exists(databaseName, null, null);
}
public void createDatabase(String databaseName, ODatabaseType type, OrientDBConfig config) {
databases.create(databaseName, null, null, type, config);
}
public Set listDatabases() {
Set dbs = databases.listDatabases(null, null);
dbs.remove(OSystemDatabase.SYSTEM_DB_NAME);
return dbs;
}
public void restore(String name, String path) {
databases.restore(name, null, null, null, path, OrientDBConfig.defaultConfig());
}
public Date getStartedOn() {
return startedOn;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy