public String readString() throws IOException { if (debug) { OLogManager.instance() .info(this, "%s - Reading string (4+N bytes)...", socket.getRemoteSocketAddress()); final int len = in.readInt(); if (len < 0) return null; // REUSE STATIC BUFFER? final byte[] tmp = new byte[len]; in.readFully(tmp); updateMetricReceivedBytes(OBinaryProtocol.SIZE_INT + len); final String value = new String(tmp); OLogManager.instance() .info(this, "%s - Read string: %s", socket.getRemoteSocketAddress(), value); return value; } final int len = in.readInt(); if (len < 0) return null; final byte[] tmp = new byte[len]; in.readFully(tmp); updateMetricReceivedBytes(OBinaryProtocol.SIZE_INT + len); return new String(tmp); }
protected static boolean commitBuffer(final OMMapBufferEntry iEntry) { final long timer = OProfiler.getInstance().startChrono(); // FORCE THE WRITE OF THE BUFFER boolean forceSucceed = false; for (int i = 0; i < FORCE_RETRY; ++i) { try { iEntry.buffer.force(); forceSucceed = true; break; } catch (Exception e) { OLogManager.instance() .debug( iEntry, "Can't write memory buffer to disk. Retrying (" + (i + 1) + "/" + FORCE_RETRY + ")..."); OMemoryWatchDog.freeMemory(FORCE_DELAY); } } if (!forceSucceed) OLogManager.instance() .debug(iEntry, "Can't commit memory buffer to disk after %d retries", FORCE_RETRY); else OProfiler.getInstance().updateCounter("OMMapManager.pagesCommitted", 1); OProfiler.getInstance().stopChrono("OMMapManager.commitPages", timer); return forceSucceed; }
private static void freeResources() { final long memoryThreshold = (long) (maxMemory * 0.75); if (OLogManager.instance().isDebugEnabled()) OLogManager.instance() .debug( null, "Free mmmap blocks, at least %d MB...", (totalMemory - memoryThreshold) / 1000000); // SORT AS LRU, FIRST = MOST USED Collections.sort( bufferPoolLRU, new Comparator<OMMapBufferEntry>() { public int compare(final OMMapBufferEntry o1, final OMMapBufferEntry o2) { return (int) (o1.counter - o2.counter); } }); // REMOVE THE LESS USED ENTRY AND UPDATE THE TOTAL MEMORY for (Iterator<OMMapBufferEntry> it = bufferPoolLRU.iterator(); it.hasNext(); ) { final OMMapBufferEntry entry = it.next(); if (!entry.pin) { // REMOVE FROM COLLECTIONS removeEntry(it, entry); if (totalMemory < memoryThreshold) break; } } }
@Override public Integer call() throws Exception { final ODistributedServerManager dManager = getDistributedServerManager(); if (aligned == -1) { // ALIGNMENT POSTPONED OLogManager.instance() .warn(this, "DISTRIBUTED <-[%s/%s] alignment postponed", nodeSource, databaseName); dManager.postponeAlignment(nodeSource, databaseName); } else { // ALIGNMENT DONE OLogManager.instance() .warn( this, "DISTRIBUTED <-[%s/%s] alignment ended: %d operation(s)", nodeSource, databaseName, aligned); dManager.endAlignment(nodeSource, databaseName); } return null; }
// Returns a section of the JSON document configuration as an ODocument if section is present. private ODocument getSection(final String section) { ODocument sectionDoc = null; try { if (configDoc != null) { if (configDoc.containsField(section)) { sectionDoc = configDoc.field(section); } } else { OLogManager.instance() .error( this, "ODefaultServerSecurity.getSection(%s) Configuration document is null", section); } } catch (Exception ex) { OLogManager.instance() .error( this, "ODefaultServerSecurity.getSection(%s) Exception: %s", section, ex.getMessage()); } return sectionDoc; }
// OSecuritySystem (via OServerSecurity) public String authenticate(final String username, final String password) { try { // It's possible for the username to be null or an empty string in the case of SPNEGO Kerberos // tickets. if (username != null && !username.isEmpty()) { if (debug) OLogManager.instance() .info( this, "ODefaultServerSecurity.authenticate() ** Authenticating username: %s", username); // This means it originates from us (used by openDatabase). if (username.equals(superUser) && password.equals(superUserPassword)) return superUser; } synchronized (authenticatorsList) { // Walk through the list of OSecurityAuthenticators. for (OSecurityAuthenticator sa : authenticatorsList) { if (sa.isEnabled()) { String principal = sa.authenticate(username, password); if (principal != null) return principal; } } } } catch (Exception ex) { OLogManager.instance() .error(this, "ODefaultServerSecurity.authenticate() Exception: %s", ex.getMessage()); } return null; // Indicates authentication failed. }
@Override public void close() { if (debug) OLogManager.instance() .info( this, "%s - Closing socket...", socket != null ? " null possible previous close" : socket.getRemoteSocketAddress()); try { if (in != null) { in.close(); // in = null; } } catch (IOException e) { OLogManager.instance().debug(this, "Error during closing of input stream", e); } try { if (out != null) { out.close(); // out = null; } } catch (IOException e) { OLogManager.instance().debug(this, "Error during closing of output stream", e); } super.close(); }
private void reloadImportLDAP() { try { synchronized (importLDAPSynch) { if (importLDAP != null) { importLDAP.dispose(); importLDAP = null; } if (ldapImportDoc != null && isEnabled(ldapImportDoc)) { Class<?> cls = getClass(ldapImportDoc); if (cls != null) { if (OSecurityComponent.class.isAssignableFrom(cls)) { importLDAP = (OSecurityComponent) cls.newInstance(); importLDAP.config(server, serverConfig, ldapImportDoc); importLDAP.active(); } else { OLogManager.instance() .error( this, "ODefaultServerSecurity.reloadImportLDAP() class is not an OSecurityComponent"); } } else { OLogManager.instance() .error( this, "ODefaultServerSecurity.reloadImportLDAP() ImportLDAP class property is missing"); } } } } catch (Exception ex) { OLogManager.instance() .error(this, "ODefaultServerSecurity.reloadImportLDAP() Exception: %s", ex.getMessage()); } }
/** Avoid to close it but rather release itself to the owner pool. */ @Override public void close() { if (isClosed()) return; checkOpeness(); if (ownerPool.getConnectionsInCurrentThread(getURL(), userName) > 1) { ownerPool.release(this); return; } objects2Records.clear(); records2Objects.clear(); rid2Records.clear(); try { commit(true); } catch (Exception e) { OLogManager.instance().error(this, "Error on releasing database '%s' in pool", e, getName()); } try { underlying.callOnCloseListeners(); } catch (Exception e) { OLogManager.instance().error(this, "Error on releasing database '%s' in pool", e, getName()); } getLocalCache().clear(); if (ownerPool != null) { final OObjectDatabasePool localCopy = ownerPool; ownerPool = null; localCopy.release(this); } }
@Override public Object call() throws Exception { if (OLogManager.instance().isDebugEnabled()) OLogManager.instance().debug(this, "DISTRIBUTED <- command: %s", text.toString()); if (status != STATUS.ALIGN && !getDistributedServerManager().checkStatus("online")) // NODE NOT ONLINE, REFUSE THE OEPRATION throw new OServerOfflineException(); final ODatabaseDocumentTx db = openDatabase(); ODistributedThreadLocal.INSTANCE.distributedExecution = true; try { Object result = openDatabase().command(new OCommandSQL(text)); if (mode != EXECUTION_MODE.FIRE_AND_FORGET) return result; // FIRE AND FORGET MODE: AVOID THE PAYLOAD AS RESULT return null; } finally { ODistributedThreadLocal.INSTANCE.distributedExecution = false; closeDatabase(db); } }
/** Execute the DROP CLASS. */ public Object execute(final Map<Object, Object> iArgs) { if (className == null) { throw new OCommandExecutionException( "Cannot execute the command because it has not been parsed yet"); } final ODatabaseDocument database = getDatabase(); if (ifExists && !database.getMetadata().getSchema().existsClass(className)) { return true; } final OClass cls = database.getMetadata().getSchema().getClass(className); if (cls == null) { return null; } final long records = cls.count(true); if (records > 0 && !unsafe) { // NOT EMPTY, CHECK IF CLASS IS OF VERTEX OR EDGES if (cls.isSubClassOf("V")) { // FOUND VERTEX CLASS throw new OCommandExecutionException( "'DROP CLASS' command cannot drop class '" + className + "' because it contains Vertices. Use 'DELETE VERTEX' command first to avoid broken edges in a database, or apply the 'UNSAFE' keyword to force it"); } else if (cls.isSubClassOf("E")) { // FOUND EDGE CLASS throw new OCommandExecutionException( "'DROP CLASS' command cannot drop class '" + className + "' because it contains Edges. Use 'DELETE EDGE' command first to avoid broken vertices in a database, or apply the 'UNSAFE' keyword to force it"); } } database.getMetadata().getSchema().dropClass(className); if (records > 0 && unsafe) { // NOT EMPTY, CHECK IF CLASS IS OF VERTEX OR EDGES if (cls.isSubClassOf("V")) { // FOUND VERTICES if (unsafe) OLogManager.instance() .warn( this, "Dropped class '%s' containing %d vertices using UNSAFE mode. Database could contain broken edges", className, records); } else if (cls.isSubClassOf("E")) { // FOUND EDGES OLogManager.instance() .warn( this, "Dropped class '%s' containing %d edges using UNSAFE mode. Database could contain broken vertices", className, records); } } return true; }
public OClusterPosition readClusterPosition() throws IOException { final int serializedSize = OClusterPositionFactory.INSTANCE.getSerializedSize(); if (debug) OLogManager.instance() .info( this, "%s - Reading cluster position (%d bytes)....", socket.getRemoteSocketAddress(), serializedSize); final OClusterPosition clusterPosition = OClusterPositionFactory.INSTANCE.fromStream((InputStream) in); updateMetricReceivedBytes(serializedSize); if (debug) OLogManager.instance() .info( this, "%s - Read cluster position: %s", socket.getRemoteSocketAddress(), clusterPosition); return clusterPosition; }
public Set<String> readStringSet() throws IOException { if (debug) OLogManager.instance() .info( this, "%s - Reading string set. Reading string set items as int (4 bytes)...", socket.getRemoteSocketAddress()); int items = in.readInt(); updateMetricReceivedBytes(OBinaryProtocol.SIZE_INT); if (debug) OLogManager.instance() .info(this, "%s - Read string set items: %d", socket.getRemoteSocketAddress(), items); if (items < 0) return null; Set<String> result = new HashSet<String>(); for (int i = 0; i < items; ++i) result.add(readString()); if (debug) OLogManager.instance() .info( this, "%s - Read string set with %d items: %d", socket.getRemoteSocketAddress(), items, result); return result; }
public <DB extends ODatabaseRecord> DB checkSecurity( final String iResourceGeneric, final int iOperation, final Object... iResourcesSpecific) { if (user != null) { try { final StringBuilder keyBuffer = new StringBuilder(); boolean ruleFound = false; for (Object target : iResourcesSpecific) { if (target != null) { keyBuffer.setLength(0); keyBuffer.append(iResourceGeneric); keyBuffer.append('.'); keyBuffer.append(target.toString()); final String key = keyBuffer.toString(); if (user.isRuleDefined(key)) { ruleFound = true; // RULE DEFINED: CHECK AGAINST IT user.allow(key, iOperation); } } } if (!ruleFound) { // CHECK AGAINST GENERIC RULE keyBuffer.setLength(0); keyBuffer.append(iResourceGeneric); keyBuffer.append('.'); keyBuffer.append(ODatabaseSecurityResources.ALL); user.allow(keyBuffer.toString(), iOperation); } } catch (OSecurityAccessException e) { if (OLogManager.instance().isDebugEnabled()) OLogManager.instance() .debug( this, "[checkSecurity] User '%s' tried to access to the reserved resource '%s', target(s) '%s', operation '%s'", getUser(), iResourceGeneric, Arrays.toString(iResourcesSpecific), iOperation); throw e; } } return (DB) this; }
public void updateClusterConfiguration(final byte[] iContent) { if (iContent == null) return; synchronized (clusterConfiguration) { clusterConfiguration.reset(); // UPDATE IT clusterConfiguration.fromStream(iContent); if (OLogManager.instance().isDebugEnabled()) OLogManager.instance() .debug(this, "Received new cluster configuration: %s", clusterConfiguration.toJSON("")); } }
public int readInt() throws IOException { updateMetricReceivedBytes(OBinaryProtocol.SIZE_INT); if (debug) { OLogManager.instance() .info(this, "%s - Reading int (4 bytes)...", socket.getRemoteSocketAddress()); final int value = in.readInt(); OLogManager.instance() .info(this, "%s - Read int: %d", socket.getRemoteSocketAddress(), value); return value; } return in.readInt(); }
public long readLong() throws IOException { updateMetricReceivedBytes(OBinaryProtocol.SIZE_LONG); if (debug) { OLogManager.instance() .info(this, "%s - Reading long (8 bytes)...", socket.getRemoteSocketAddress()); final long value = in.readLong(); OLogManager.instance() .info(this, "%s - Read long: %d", socket.getRemoteSocketAddress(), value); return value; } return in.readLong(); }
public boolean readBoolean() throws IOException { updateMetricReceivedBytes(OBinaryProtocol.SIZE_BYTE); if (debug) { OLogManager.instance() .info(this, "%s - Reading boolean (1 byte)...", socket.getRemoteSocketAddress()); final boolean value = in.readBoolean(); OLogManager.instance() .info(this, "%s - Read boolean: %b", socket.getRemoteSocketAddress(), value); return value; } return in.readBoolean(); }
public void shutdown() { acquireExclusiveLock(); try { if (!active) return; active = false; if (shutdownHook != null) shutdownHook.cancel(); if (profiler != null) profiler.shutdown(); OLogManager.instance().debug(this, "Orient Engine is shutting down..."); if (listeners != null) // CALL THE SHUTDOWN ON ALL THE LISTENERS for (OOrientListener l : listeners) { if (l != null) l.onShutdown(); } // SHUTDOWN ENGINES for (OEngine engine : engines.values()) { engine.shutdown(); } if (databaseFactory != null) // CLOSE ALL DATABASES databaseFactory.shutdown(); if (storages != null) { // CLOSE ALL THE STORAGES final List<OStorage> storagesCopy = new ArrayList<OStorage>(storages.values()); for (OStorage stg : storagesCopy) { OLogManager.instance().info(this, "Shutting down storage: " + stg.getName() + "..."); stg.close(true); } } if (OMMapManagerLocator.getInstance() != null) OMMapManagerLocator.getInstance().shutdown(); if (threadGroup != null) // STOP ALL THE PENDING THREADS threadGroup.interrupt(); if (listeners != null) listeners.clear(); OLogManager.instance().info(this, "Orient Engine shutdown complete\n"); } finally { releaseExclusiveLock(); } }
@Override public void run() { try { if (writeGroups.isEmpty()) return; int writeGroupsToFlush; boolean useForceSync = false; double threshold = ((double) cacheSize.get()) / cacheMaxSize; if (threshold > 0.8) { writeGroupsToFlush = (int) (0.2 * writeGroups.size()); useForceSync = true; } else if (threshold > 0.9) { writeGroupsToFlush = (int) (0.4 * writeGroups.size()); useForceSync = true; } else writeGroupsToFlush = 1; if (writeGroupsToFlush < 1) writeGroupsToFlush = 1; int flushedGroups = 0; flushedGroups = flushRing(writeGroupsToFlush, flushedGroups, false); if (flushedGroups < writeGroupsToFlush && useForceSync) flushedGroups = flushRing(writeGroupsToFlush, flushedGroups, true); if (flushedGroups < writeGroupsToFlush && cacheSize.get() > cacheMaxSize) { if (OGlobalConfiguration.SERVER_CACHE_INCREASE_ON_DEMAND.getValueAsBoolean()) { final long oldCacheMaxSize = cacheMaxSize; cacheMaxSize = (int) Math.ceil( cacheMaxSize * (1 + OGlobalConfiguration.SERVER_CACHE_INCREASE_STEP .getValueAsFloat())); OLogManager.instance() .warn( this, "Write cache size is increased from %d to %d", oldCacheMaxSize, cacheMaxSize); } else { throw new OAllCacheEntriesAreUsedException("All records in write cache are used!"); } } } catch (Exception e) { OLogManager.instance().error(this, "Exception during data flush.", e); } }
public void checkEntryStructure() { if (!tree.isRuntimeCheckEnabled()) return; if (dataProvider.getParent() == null) OLogManager.instance() .error(this, "checkEntryStructure: Node %s has parentRid null!\n", this); if (dataProvider.getLeft() == null) OLogManager.instance().error(this, "checkEntryStructure: Node %s has leftRid null!\n", this); if (dataProvider.getRight() == null) OLogManager.instance().error(this, "checkEntryStructure: Node %s has rightRid null!\n", this); if (this == left || dataProvider.getIdentity().isValid() && dataProvider.getIdentity().equals(dataProvider.getLeft())) OLogManager.instance() .error(this, "checkEntryStructure: Node %s has left that points to itself!\n", this); if (this == right || dataProvider.getIdentity().isValid() && dataProvider.getIdentity().equals(dataProvider.getRight())) OLogManager.instance() .error(this, "checkEntryStructure: Node %s has right that points to itself!\n", this); if (left != null && left == right) OLogManager.instance() .error(this, "checkEntryStructure: Node %s has left and right equals!\n", this); if (left != null) { if (!left.dataProvider.getIdentity().equals(dataProvider.getLeft())) OLogManager.instance() .error(this, "checkEntryStructure: Wrong left node loaded: " + dataProvider.getLeft()); if (left.parent != this) OLogManager.instance() .error( this, "checkEntryStructure: Left node is not correctly connected to the parent" + dataProvider.getLeft()); } if (right != null) { if (!right.dataProvider.getIdentity().equals(dataProvider.getRight())) OLogManager.instance() .error( this, "checkEntryStructure: Wrong right node loaded: " + dataProvider.getRight()); if (right.parent != this) OLogManager.instance() .error( this, "checkEntryStructure: Right node is not correctly connected to the parent" + dataProvider.getRight()); } }
public void fromStream() { name = document.field("name"); if (document.field("type") != null) type = OType.getById(((Long) document.field("type")).byteValue()); offset = ((Long) document.field("offset")).intValue(); mandatory = (Boolean) document.field("mandatory"); notNull = (Boolean) document.field("notNull"); min = document.field("min"); max = document.field("max"); linkedClassName = (String) document.field("linkedClass"); if (document.field("linkedType") != null) linkedType = OType.getById(((Long) document.field("linkedType")).byteValue()); if (document.field("index") != null) { setIndex( INDEX_TYPE.valueOf((String) document.field("index-type")), ((ODocument) document.field("index")).getIdentity()); try { index.load(); } catch (IOException e) { OLogManager.instance() .error( this, "Can't load index for property %s", e, ODatabaseException.class, toString()); } } }
@Before public void prepareDatabase() throws Exception { String dbUrl = "memory:test"; ODatabaseDocumentTx db = new ODatabaseDocumentTx(dbUrl); String username = "******"; String password = "******"; if (db.exists()) { db.activateOnCurrentThread(); db.open(username, password); db.drop(); } db.create(); createSchemaDB(db); if (!new File("./src/test/resources/file.pdf").exists()) OLogManager.instance() .warn( this, "TEST IS NOT RUNNING UNDER distributed folder, attachment will be not loaded!"); loadDB(db, 20); Properties info = new Properties(); info.put("user", username); info.put("password", password); conn = (OrientJdbcConnection) DriverManager.getConnection("jdbc:orient:" + dbUrl, info); }
public void clearInput() throws IOException { if (in == null) return; final StringBuilder dirtyBuffer = new StringBuilder(MAX_LENGTH_DEBUG); int i = 0; while (in.available() > 0) { char c = (char) in.read(); ++i; if (dirtyBuffer.length() < MAX_LENGTH_DEBUG) dirtyBuffer.append(c); } updateMetricReceivedBytes(i); final String message = "Received unread response from " + socket.getRemoteSocketAddress() + " probably corrupted data from the network connection. Cleared dirty data in the buffer (" + i + " bytes): [" + dirtyBuffer + (i > dirtyBuffer.length() ? "..." : "") + "]"; OLogManager.instance().error(this, message); throw new OIOException(message); }
public OChannelBinary writeBytes(final byte[] iContent, final int iLength) throws IOException { if (debug) OLogManager.instance() .info( this, "%s - Writing bytes (4+%d=%d bytes): %s", socket.getRemoteSocketAddress(), iLength, iLength + 4, Arrays.toString(iContent)); if (iContent == null) { out.writeInt(-1); updateMetricTransmittedBytes(OBinaryProtocol.SIZE_INT); } else { if (iLength > maxChunkSize) { throw OException.wrapException( new OIOException( "Impossible to write a chunk of length:" + iLength + " max allowed chunk length:" + maxChunkSize + " see NETWORK_BINARY_MAX_CONTENT_LENGTH settings "), null); } out.writeInt(iLength); out.write(iContent, 0, iLength); updateMetricTransmittedBytes(OBinaryProtocol.SIZE_INT + iLength); } return this; }
// OSecuritySystem (via OServerSecurity) public ODocument getConfig() { ODocument jsonConfig = new ODocument(); try { jsonConfig.field("enabled", enabled); jsonConfig.field("debug", debug); if (serverDoc != null) { jsonConfig.field("server", serverDoc, OType.EMBEDDED); } if (authDoc != null) { jsonConfig.field("authentication", authDoc, OType.EMBEDDED); } if (passwdValDoc != null) { jsonConfig.field("passwordValidator", passwdValDoc, OType.EMBEDDED); } if (ldapImportDoc != null) { jsonConfig.field("ldapImporter", ldapImportDoc, OType.EMBEDDED); } if (auditingDoc != null) { jsonConfig.field("auditing", auditingDoc, OType.EMBEDDED); } } catch (Exception ex) { OLogManager.instance().error(this, "ODefaultServerSecurity.getConfig() Exception: %s", ex); } return jsonConfig; }
// Change the component section and save it to disk private void setSection(final String section, ODocument sectionDoc) { ODocument oldSection = getSection(section); try { if (configDoc != null) { configDoc.field(section, sectionDoc); String configFile = OSystemVariableResolver.resolveSystemVariables("${ORIENTDB_HOME}/config/security.json"); // The default "security.json" file can be overridden in the server config file. String securityFile = getConfigProperty("server.security.file"); if (securityFile != null) configFile = securityFile; String ssf = OGlobalConfiguration.SERVER_SECURITY_FILE.getValueAsString(); if (ssf != null) configFile = ssf; File f = new File(configFile); OIOUtils.writeFile(f, configDoc.toJSON("prettyPrint")); } } catch (Exception ex) { configDoc.field(section, oldSection); OLogManager.instance() .error( this, "ODefaultServerSecurity.setSection(%s) Exception: %s", section, ex.getMessage()); } }
public void delete() throws IOException { synchronized (syncObject) { for (long fileId : files.keySet()) doDeleteFile(fileId); if (nameIdMapHolderFile != null) { nameIdMapHolder.close(); if (!nameIdMapHolderFile.delete()) throw new OStorageException( "Can not delete disk cache file which contains name-id mapping."); } } if (!commitExecutor.isShutdown()) { commitExecutor.shutdown(); try { if (!commitExecutor.awaitTermination(5, TimeUnit.MINUTES)) throw new OException("Background data flush task can not be stopped."); } catch (InterruptedException e) { OLogManager.instance().error(this, "Data flush thread was interrupted"); Thread.interrupted(); throw new OException("Data flush thread was interrupted", e); } } }
public void close() throws IOException { flush(); if (!commitExecutor.isShutdown()) { commitExecutor.shutdown(); try { if (!commitExecutor.awaitTermination(5, TimeUnit.MINUTES)) throw new OException("Background data flush task can not be stopped."); } catch (InterruptedException e) { OLogManager.instance().error(this, "Data flush thread was interrupted"); Thread.interrupted(); throw new OException("Data flush thread was interrupted", e); } } synchronized (syncObject) { for (OFileClassic fileClassic : files.values()) { if (fileClassic.isOpen()) fileClassic.close(); } if (nameIdMapHolder != null) { nameIdMapHolder.setLength(0); for (Map.Entry<String, Long> entry : nameIdMap.entrySet()) { writeNameIdEntry(new NameFileIdEntry(entry.getKey(), entry.getValue()), false); } nameIdMapHolder.getFD().sync(); nameIdMapHolder.close(); } } }
@Override public OMVRBTreeEntry<K, V> getParent() { if (dataProvider == null) return null; if (parent == null && dataProvider.getParent().isValid()) { // LAZY LOADING OF THE PARENT NODE parent = pTree.loadEntry(null, dataProvider.getParent()); checkEntryStructure(); if (parent != null) { // TRY TO ASSIGN IT FOLLOWING THE RID if (parent.dataProvider.getLeft().isValid() && parent.dataProvider.getLeft().equals(dataProvider.getIdentity())) parent.left = this; else if (parent.dataProvider.getRight().isValid() && parent.dataProvider.getRight().equals(dataProvider.getIdentity())) parent.right = this; else { OLogManager.instance() .error( this, "getParent: Cannot assign node %s to parent. Nodes parent-left=%s, parent-right=%s", dataProvider.getParent(), parent.dataProvider.getLeft(), parent.dataProvider.getRight()); } } } return parent; }