diff --git a/build.xml b/build.xml index 6aa46723806..2c5ac95e753 100644 --- a/build.xml +++ b/build.xml @@ -5,7 +5,7 @@ - + diff --git a/client/pom.xml b/client/pom.xml index f7288d2841e..8a5d05107af 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -24,7 +24,7 @@ com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 ../ diff --git a/client/src/main/java/com/orientechnologies/orient/client/remote/OEngineRemote.java b/client/src/main/java/com/orientechnologies/orient/client/remote/OEngineRemote.java index c1f7300194d..14dabaa8122 100644 --- a/client/src/main/java/com/orientechnologies/orient/client/remote/OEngineRemote.java +++ b/client/src/main/java/com/orientechnologies/orient/client/remote/OEngineRemote.java @@ -36,9 +36,6 @@ public OEngineRemote() { } public OStorage createStorage(final String iURL, final Map iConfiguration) { - OGlobalConfiguration.SECURITY_MAX_CACHED_ROLES.setValue(0); - OGlobalConfiguration.SECURITY_MAX_CACHED_USERS.setValue(0); - try { synchronized (sharedStorages) { OStorageRemote sharedStorage = sharedStorages.get(iURL); diff --git a/client/src/main/java/com/orientechnologies/orient/client/remote/OSBTreeBonsaiRemote.java b/client/src/main/java/com/orientechnologies/orient/client/remote/OSBTreeBonsaiRemote.java index 74d3ef74bae..786f8063c52 100644 --- a/client/src/main/java/com/orientechnologies/orient/client/remote/OSBTreeBonsaiRemote.java +++ b/client/src/main/java/com/orientechnologies/orient/client/remote/OSBTreeBonsaiRemote.java @@ -152,6 +152,9 @@ private List> fetchEntriesMajor(K key, boolean inclusive) { client.writeBytes(keyStream); client.writeBoolean(inclusive); + if (client.getSrvProtocolVersion() >= 21) + client.writeInt(128); + storage.endRequest(client); storage.beginResponse(client); @@ -253,27 +256,27 @@ public OBinarySerializer getValueSerializer() { return valueSerializer; } - class TreeEntry implements Map.Entry { - private final K key; - private final V value; + class TreeEntry implements Map.Entry { + private final EK key; + private final EV value; - TreeEntry(K key, V value) { + TreeEntry(EK key, EV value) { this.key = key; this.value = value; } @Override - public K getKey() { + public EK getKey() { return key; } @Override - public V getValue() { + public EV getValue() { return value; } @Override - public V setValue(V value) { + public EV setValue(EV value) { throw new UnsupportedOperationException(); } } diff --git a/client/src/main/java/com/orientechnologies/orient/client/remote/OStorageRemote.java b/client/src/main/java/com/orientechnologies/orient/client/remote/OStorageRemote.java index 4f24c592666..15df878405e 100755 --- a/client/src/main/java/com/orientechnologies/orient/client/remote/OStorageRemote.java +++ b/client/src/main/java/com/orientechnologies/orient/client/remote/OStorageRemote.java @@ -58,6 +58,7 @@ import com.orientechnologies.orient.core.storage.OStorageAbstract; import com.orientechnologies.orient.core.storage.OStorageOperationResult; import com.orientechnologies.orient.core.storage.OStorageProxy; +import com.orientechnologies.orient.core.storage.impl.local.OStorageConfigurationSegment; import com.orientechnologies.orient.core.storage.impl.local.paginated.ORecordSerializationContext; import com.orientechnologies.orient.core.tx.OTransaction; import com.orientechnologies.orient.core.tx.OTransactionAbstract; @@ -176,8 +177,10 @@ public void open(final String iUserName, final String iUserPassword, final Map com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 ../ diff --git a/core/pom.xml b/core/pom.xml index 8a1d9bd71fd..db98b72540e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -17,7 +17,7 @@ com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 ../ diff --git a/core/src/main/java/com/orientechnologies/orient/core/OConstants.java b/core/src/main/java/com/orientechnologies/orient/core/OConstants.java index 66e39a56975..45c23d03559 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/OConstants.java +++ b/core/src/main/java/com/orientechnologies/orient/core/OConstants.java @@ -16,7 +16,7 @@ package com.orientechnologies.orient.core; public class OConstants { - public static final String ORIENT_VERSION = "1.7.1"; + public static final String ORIENT_VERSION = "1.7.2"; public static final String ORIENT_URL = "www.orientechnologies.com"; diff --git a/core/src/main/java/com/orientechnologies/orient/core/cache/OLevel2RecordCache.java b/core/src/main/java/com/orientechnologies/orient/core/cache/OLevel2RecordCache.java index 1dfa40be456..88dea08feaa 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/cache/OLevel2RecordCache.java +++ b/core/src/main/java/com/orientechnologies/orient/core/cache/OLevel2RecordCache.java @@ -24,6 +24,10 @@ import com.orientechnologies.orient.core.record.ORecordInternal; import com.orientechnologies.orient.core.storage.OStorage; +import java.util.Collections; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + /** * Second level cache. It's shared among database instances with the same URL. * @@ -31,9 +35,11 @@ * @author Sylvain Spinelli */ public class OLevel2RecordCache extends OAbstractRecordCache { - private final String CACHE_HIT; - private final String CACHE_MISS; - private STRATEGY strategy; + private final String CACHE_HIT; + private final String CACHE_MISS; + private STRATEGY strategy; + + private final Set pinnedClusters = Collections.newSetFromMap(new ConcurrentHashMap()); public enum STRATEGY { POP_RECORD, COPY_RECORD @@ -57,6 +63,14 @@ public void startup() { setEnable(OGlobalConfiguration.CACHE_LEVEL2_ENABLED.getValueAsBoolean()); } + public void addPinnedCluster(int clusterId) { + pinnedClusters.add(clusterId); + } + + public void removePinnedCluster(int clusterId) { + pinnedClusters.remove(clusterId); + } + /** * Push record to cache. Identifier of record used as access key * @@ -68,6 +82,9 @@ public void updateRecord(final ORecordInternal fresh) { || fresh.getIdentity().getClusterId() == excludedCluster || fresh.getRecordVersion().isTombstone()) return; + if (pinnedClusters.contains(fresh.getIdentity().getClusterId())) + fresh.pin(); + if (fresh.isPinned() == null || fresh.isPinned()) { underlying.lock(fresh.getIdentity()); try { diff --git a/core/src/main/java/com/orientechnologies/orient/core/config/OGlobalConfiguration.java b/core/src/main/java/com/orientechnologies/orient/core/config/OGlobalConfiguration.java index 73443036279..11db56a5622 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/config/OGlobalConfiguration.java +++ b/core/src/main/java/com/orientechnologies/orient/core/config/OGlobalConfiguration.java @@ -132,7 +132,8 @@ public enum OGlobalConfiguration { STORAGE_MAKE_FULL_CHECKPOINT_AFTER_CLUSTER_CREATE("storage.makeFullCheckpointAfterClusterCreate", "Indicates whether full checkpoint should be performed if storage was opened.", Boolean.class, true), - DISK_CACHE_PAGE_SIZE("storage.diskCache.pageSize", "Size of page of disk buffer in kilobytes", Integer.class, 64), + DISK_CACHE_PAGE_SIZE("storage.diskCache.pageSize", "Size of page of disk buffer in kilobytes,!!! NEVER CHANGE THIS VALUE !!!", + Integer.class, 64), PAGINATED_STORAGE_LOWEST_FREELIST_BOUNDARY("storage.lowestFreeListBound", "The minimal amount of free space (in kb)" + " in page which is tracked in paginated storage", Integer.class, 16), @@ -447,13 +448,6 @@ public void change(final Object iCurrentValue, final Object iNewValue) { NETWORK_HTTP_SESSION_EXPIRE_TIMEOUT("network.http.sessionExpireTimeout", "Timeout after which an http session is considered tp have expired (seconds)", Integer.class, 300), - // SECURITY - SECURITY_MAX_CACHED_USERS("security.maxCachedUsers", - "Maximum users cached in RAM. This speeds up authentication for the most used users", Integer.class, 100), - - SECURITY_MAX_CACHED_ROLES("security.maxCachedRoles", - "Maximum roles cached in RAM. This speeds up authentication for the most used roles", Integer.class, 100), - // PROFILER PROFILER_ENABLED("profiler.enabled", "Enable the recording of statistics and counters", Boolean.class, false, new OConfigurationChangeCallback() { @@ -728,4 +722,3 @@ public String getDescription() { return description; } } - diff --git a/core/src/main/java/com/orientechnologies/orient/core/config/OStorageConfiguration.java b/core/src/main/java/com/orientechnologies/orient/core/config/OStorageConfiguration.java index f518446020e..4d85717b7a5 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/config/OStorageConfiguration.java +++ b/core/src/main/java/com/orientechnologies/orient/core/config/OStorageConfiguration.java @@ -31,10 +31,7 @@ import java.io.IOException; import java.text.DecimalFormatSymbols; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.TimeZone; +import java.util.*; /** * Versions: @@ -53,34 +50,40 @@ */ @SuppressWarnings("serial") public class OStorageConfiguration implements OSerializableStream { - public static final ORecordId CONFIG_RID = new OImmutableRecordId(0, - OClusterPositionFactory.INSTANCE.valueOf(0)); - - public static final String DEFAULT_CHARSET = "UTF-8"; - private String charset = DEFAULT_CHARSET; - public static final int CURRENT_VERSION = 9; - public static final int CURRENT_BINARY_FORMAT_VERSION = 11; - public int version = -1; - public String name; - public String schemaRecordId; - public String dictionaryRecordId; - public String indexMgrRecordId; - public String dateFormat = "yyyy-MM-dd"; - public String dateTimeFormat = "yyyy-MM-dd HH:mm:ss"; - public int binaryFormatVersion; - public OStorageSegmentConfiguration fileTemplate; - public List clusters = new ArrayList(); - public List dataSegments = new ArrayList(); - public OStorageTxConfiguration txSegment = new OStorageTxConfiguration(); - public List properties = new ArrayList(); - protected transient OStorage storage; - private String localeLanguage = Locale.getDefault().getLanguage(); - private String localeCountry = Locale.getDefault().getCountry(); - private TimeZone timeZone = TimeZone.getDefault(); - private transient Locale localeInstance; - private transient DecimalFormatSymbols unusualSymbols; - private String clusterSelection; - private int minimumClusters = 1; + public static final ORecordId CONFIG_RID = new OImmutableRecordId(0, + OClusterPositionFactory.INSTANCE.valueOf(0)); + + public static final String DEFAULT_CHARSET = "UTF-8"; + private String charset = DEFAULT_CHARSET; + public static final int CURRENT_VERSION = 9; + public static final int CURRENT_BINARY_FORMAT_VERSION = 11; + public volatile int version = -1; + + public volatile String name; + public volatile String schemaRecordId; + public volatile String dictionaryRecordId; + public volatile String indexMgrRecordId; + public volatile String dateFormat = "yyyy-MM-dd"; + public volatile String dateTimeFormat = "yyyy-MM-dd HH:mm:ss"; + public volatile int binaryFormatVersion; + public volatile OStorageSegmentConfiguration fileTemplate; + + public volatile List clusters = Collections + .synchronizedList(new ArrayList()); + public final List dataSegments = Collections + .synchronizedList(new ArrayList()); + public volatile OStorageTxConfiguration txSegment = new OStorageTxConfiguration(); + public final List properties = Collections + .synchronizedList(new ArrayList()); + + protected final transient OStorage storage; + private volatile String localeLanguage = Locale.getDefault().getLanguage(); + private volatile String localeCountry = Locale.getDefault().getCountry(); + private volatile TimeZone timeZone = TimeZone.getDefault(); + private transient volatile Locale localeInstance; + private transient volatile DecimalFormatSymbols unusualSymbols; + private volatile String clusterSelection; + private volatile int minimumClusters = 1; public OStorageConfiguration(final OStorage iStorage) { storage = iStorage; @@ -186,7 +189,7 @@ public OSerializableStream fromStream(final byte[] iStream) throws OSerializatio int size = Integer.parseInt(read(values[index++])); // PREPARE THE LIST OF CLUSTERS - clusters = new ArrayList(size); + clusters.clear(); for (int i = 0; i < size; ++i) { final int clusterId = Integer.parseInt(read(values[index++])); @@ -237,7 +240,7 @@ else if (clusterType.equals("d")) { // PREPARE THE LIST OF DATA SEGS size = Integer.parseInt(read(values[index++])); - dataSegments = new ArrayList(size); + dataSegments.clear(); for (int i = 0; i < size; ++i) dataSegments.add(null); @@ -260,7 +263,7 @@ else if (clusterType.equals("d")) { read(values[index++]), read(values[index++])); size = Integer.parseInt(read(values[index++])); - properties = new ArrayList(size); + properties.clear(); for (int i = 0; i < size; ++i) { properties.add(new OStorageEntryConfiguration(read(values[index++]), read(values[index++]))); } diff --git a/core/src/main/java/com/orientechnologies/orient/core/config/OStorageEntryConfiguration.java b/core/src/main/java/com/orientechnologies/orient/core/config/OStorageEntryConfiguration.java index 4e278e1406b..5102b45ea77 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/config/OStorageEntryConfiguration.java +++ b/core/src/main/java/com/orientechnologies/orient/core/config/OStorageEntryConfiguration.java @@ -19,14 +19,14 @@ @SuppressWarnings("serial") public class OStorageEntryConfiguration implements Serializable { - public String name; - public String value; + public volatile String name; + public volatile String value; - public OStorageEntryConfiguration() { - } + public OStorageEntryConfiguration() { + } - public OStorageEntryConfiguration(final String iName, final String iValue) { - name = iName; - value = iValue; - } + public OStorageEntryConfiguration(final String iName, final String iValue) { + name = iName; + value = iValue; + } } diff --git a/core/src/main/java/com/orientechnologies/orient/core/config/OStorageSegmentConfiguration.java b/core/src/main/java/com/orientechnologies/orient/core/config/OStorageSegmentConfiguration.java index 068d5a444e6..7401d76c1e9 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/config/OStorageSegmentConfiguration.java +++ b/core/src/main/java/com/orientechnologies/orient/core/config/OStorageSegmentConfiguration.java @@ -21,14 +21,14 @@ public class OStorageSegmentConfiguration implements Serializable { public transient OStorageConfiguration root; - public int id; - public String name; - public String maxSize = "0"; - public String fileType = "mmap"; - public String fileStartSize = "500Kb"; - public String fileMaxSize = "500Mb"; - public String fileIncrementSize = "50%"; - public String defrag = "auto"; + public volatile int id; + public volatile String name; + public volatile String maxSize = "0"; + public volatile String fileType = "mmap"; + public volatile String fileStartSize = "500Kb"; + public volatile String fileMaxSize = "500Mb"; + public volatile String fileIncrementSize = "50%"; + public volatile String defrag = "auto"; public OStorageFileConfiguration[] infoFiles; String location; diff --git a/core/src/main/java/com/orientechnologies/orient/core/db/raw/ODatabaseRaw.java b/core/src/main/java/com/orientechnologies/orient/core/db/raw/ODatabaseRaw.java index 080e7a410a7..94dc19aa52b 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/db/raw/ODatabaseRaw.java +++ b/core/src/main/java/com/orientechnologies/orient/core/db/raw/ODatabaseRaw.java @@ -694,9 +694,6 @@ public DB set(final ATTRIBUTES iAttribute, final Object i } public String getCustom(final String iName) { - if (storage.getConfiguration().properties == null) - return null; - for (OStorageEntryConfiguration e : storage.getConfiguration().properties) { if (e.name.equals(iName)) return e.value; @@ -707,21 +704,16 @@ public String getCustom(final String iName) { public void setCustomInternal(final String iName, final String iValue) { if (iValue == null || "null".equalsIgnoreCase(iValue)) { // REMOVE - if (storage.getConfiguration().properties != null) { - for (Iterator it = storage.getConfiguration().properties.iterator(); it.hasNext();) { - final OStorageEntryConfiguration e = it.next(); - if (e.name.equals(iName)) { - it.remove(); - break; - } + for (Iterator it = storage.getConfiguration().properties.iterator(); it.hasNext();) { + final OStorageEntryConfiguration e = it.next(); + if (e.name.equals(iName)) { + it.remove(); + break; } } } else { // SET - if (storage.getConfiguration().properties == null) - storage.getConfiguration().properties = new ArrayList(); - boolean found = false; for (OStorageEntryConfiguration e : storage.getConfiguration().properties) { if (e.name.equals(iName)) { @@ -740,7 +732,7 @@ public void setCustomInternal(final String iName, final String iValue) { } public void clearCustomInternal() { - storage.getConfiguration().properties = null; + storage.getConfiguration().properties.clear(); } public V callInLock(final Callable iCallable, final boolean iExclusiveLock) { diff --git a/core/src/main/java/com/orientechnologies/orient/core/db/record/ODatabaseRecordAbstract.java b/core/src/main/java/com/orientechnologies/orient/core/db/record/ODatabaseRecordAbstract.java index 498caf2a287..1e855ac4662 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/db/record/ODatabaseRecordAbstract.java +++ b/core/src/main/java/com/orientechnologies/orient/core/db/record/ODatabaseRecordAbstract.java @@ -296,8 +296,6 @@ public OSBTreeCollectionManager call() throws Exception { if (metadata.getIndexManager().autoRecreateIndexesAfterCrash()) { metadata.getIndexManager().recreateIndexes(); - // REMOVE CACHED USES AND ROLES AND RE-SET THE CURRENT DB (AFTER INDEX REBUILD) - metadata.getSecurity().uncacheUsersAndRoles(); setCurrentDatabaseinThreadLocal(); user = null; } diff --git a/core/src/main/java/com/orientechnologies/orient/core/db/record/ridbag/embedded/OEmbeddedRidBag.java b/core/src/main/java/com/orientechnologies/orient/core/db/record/ridbag/embedded/OEmbeddedRidBag.java index daaabee4745..d966bd6c602 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/db/record/ridbag/embedded/OEmbeddedRidBag.java +++ b/core/src/main/java/com/orientechnologies/orient/core/db/record/ridbag/embedded/OEmbeddedRidBag.java @@ -206,9 +206,22 @@ public String toString() { if (!deserialized) return "[size=" + size + "]"; - if (size < 10) - return OMultiValue.toString(this); - else + if (size < 10) { + final StringBuilder sb = new StringBuilder(); + sb.append('['); + for (final Iterator it = this.iterator(); it.hasNext();) { + try { + OIdentifiable e = it.next(); + sb.append(e.getIdentity()); + if (it.hasNext()) + sb.append(", "); + } catch (NoSuchElementException ex) { + // IGNORE THIS + } + } + return sb.append(']').toString(); + + } else return "[size=" + size + "]"; } diff --git a/core/src/main/java/com/orientechnologies/orient/core/db/tool/ODatabaseExport.java b/core/src/main/java/com/orientechnologies/orient/core/db/tool/ODatabaseExport.java index cb07bf1b27c..bfc8eb6b922 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/db/tool/ODatabaseExport.java +++ b/core/src/main/java/com/orientechnologies/orient/core/db/tool/ODatabaseExport.java @@ -71,7 +71,8 @@ public ODatabaseExport(final ODatabaseRecord iDatabase, final String iFileName, fileName += ".gz"; } final File f = new File(fileName); - f.getParentFile().mkdirs(); + if (f.getParentFile() != null) + f.getParentFile().mkdirs(); if (f.exists()) f.delete(); diff --git a/core/src/main/java/com/orientechnologies/orient/core/metadata/schema/OClassAbstractDelegate.java b/core/src/main/java/com/orientechnologies/orient/core/metadata/schema/OClassAbstractDelegate.java index 39be477eebd..eb6145ab154 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/metadata/schema/OClassAbstractDelegate.java +++ b/core/src/main/java/com/orientechnologies/orient/core/metadata/schema/OClassAbstractDelegate.java @@ -16,22 +16,22 @@ package com.orientechnologies.orient.core.metadata.schema; -import java.io.IOException; -import java.util.Collection; -import java.util.Set; - import com.orientechnologies.common.listener.OProgressListener; import com.orientechnologies.orient.core.index.OIndex; import com.orientechnologies.orient.core.metadata.schema.clusterselection.OClusterSelectionStrategy; import com.orientechnologies.orient.core.record.impl.ODocument; import com.orientechnologies.orient.core.storage.OStorage; +import java.io.IOException; +import java.util.Collection; +import java.util.Set; + /** * Abstract Delegate for OClass interface. * * @author Luca Garulli (http://www.orientechnologies.com) */ -public class OClassAbstractDelegate implements OClass { +public abstract class OClassAbstractDelegate implements OClass { protected final OClass delegate; diff --git a/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurity.java b/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurity.java index 6d7835c3c3d..2078414d6e6 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurity.java +++ b/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurity.java @@ -48,8 +48,6 @@ public interface OSecurity { public OUser authenticate(String iUsername, String iUserPassword); - public OSecurity uncacheUsersAndRoles(); - public OUser getUser(String iUserName); public OUser createUser(String iUserName, String iUserPassword, String... iRoles); diff --git a/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityNull.java b/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityNull.java index ed472da8598..6ebebb68ad8 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityNull.java +++ b/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityNull.java @@ -82,11 +82,6 @@ public OUser authenticate(String iUsername, String iUserPassword) { return null; } - @Override - public OSecurity uncacheUsersAndRoles() { - return this; - } - public void close(boolean onDelete) { } diff --git a/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityProxy.java b/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityProxy.java index 9123183d1dd..b0bb974056c 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityProxy.java +++ b/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityProxy.java @@ -83,11 +83,6 @@ public OUser authenticate(final String iUsername, final String iUserPassword) { return delegate.authenticate(iUsername, iUserPassword); } - @Override - public OSecurity uncacheUsersAndRoles() { - return delegate.uncacheUsersAndRoles(); - } - public OUser getUser(final String iUserName) { return delegate.getUser(iUserName); } diff --git a/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityShared.java b/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityShared.java index a583aacbb09..9100a9dd1bc 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityShared.java +++ b/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OSecurityShared.java @@ -18,6 +18,7 @@ import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; import com.orientechnologies.common.concur.resource.OCloseable; import com.orientechnologies.common.log.OLogManager; +import com.orientechnologies.orient.core.cache.OLevel2RecordCache; import com.orientechnologies.orient.core.command.OCommandRequest; import com.orientechnologies.orient.core.config.OGlobalConfiguration; import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; @@ -51,30 +52,16 @@ * */ public class OSecurityShared implements OSecurity, OCloseable { - public static final String RESTRICTED_CLASSNAME = "ORestricted"; - public static final String IDENTITY_CLASSNAME = "OIdentity"; - public static final String ALLOW_ALL_FIELD = "_allow"; - public static final String ALLOW_READ_FIELD = "_allowRead"; - public static final String ALLOW_UPDATE_FIELD = "_allowUpdate"; - public static final String ALLOW_DELETE_FIELD = "_allowDelete"; - public static final String ONCREATE_IDENTITY_TYPE = "onCreate.identityType"; - public static final String ONCREATE_FIELD = "onCreate.fields"; - - protected final ConcurrentLinkedHashMap cachedUsers; - protected final ConcurrentLinkedHashMap cachedRoles; + public static final String RESTRICTED_CLASSNAME = "ORestricted"; + public static final String IDENTITY_CLASSNAME = "OIdentity"; + public static final String ALLOW_ALL_FIELD = "_allow"; + public static final String ALLOW_READ_FIELD = "_allowRead"; + public static final String ALLOW_UPDATE_FIELD = "_allowUpdate"; + public static final String ALLOW_DELETE_FIELD = "_allowDelete"; + public static final String ONCREATE_IDENTITY_TYPE = "onCreate.identityType"; + public static final String ONCREATE_FIELD = "onCreate.fields"; public OSecurityShared() { - final int maxCachedUsers = OGlobalConfiguration.SECURITY_MAX_CACHED_USERS.getValueAsInteger(); - if (maxCachedUsers > 0) - cachedUsers = new ConcurrentLinkedHashMap.Builder().maximumWeightedCapacity(maxCachedUsers).build(); - else - cachedUsers = null; - - final int maxCachedRoles = OGlobalConfiguration.SECURITY_MAX_CACHED_ROLES.getValueAsInteger(); - if (maxCachedRoles > 0) - cachedRoles = new ConcurrentLinkedHashMap.Builder().maximumWeightedCapacity(maxCachedRoles).build(); - else - cachedRoles = null; } public OIdentifiable allowUser(final ODocument iDocument, final String iAllowFieldName, final String iUserName) { @@ -190,16 +177,6 @@ public OUser authenticate(final String iUserName, final String iUserPassword) { return user; } - @Override - public OSecurity uncacheUsersAndRoles() { - if (cachedRoles != null) - cachedRoles.clear(); - - if (cachedUsers != null) - cachedUsers.clear(); - return this; - } - public OUser getUser(final String iUserName) { return getUser(iUserName, true); } @@ -212,27 +189,21 @@ public OUser createUser(final String iUserName, final String iUserPassword, fina user.addRole(r); } - cacheUser(user); - return user.save(); } - public OUser createUser(final String iUserName, final String iUserPassword, final ORole... iRoles) { - final OUser user = new OUser(iUserName, iUserPassword); + public OUser createUser(final String userName, final String userPassword, final ORole... roles) { + final OUser user = new OUser(userName, userPassword); - if (iRoles != null) - for (ORole r : iRoles) { + if (roles != null) + for (ORole r : roles) { user.addRole(r); } - cacheUser(user); - return user.save(); } public boolean dropUser(final String iUserName) { - uncacheUser(iUserName); - final Number removed = getDatabase(). command( new OCommandSQL("delete from OUser where name = '" + iUserName + "'")).execute(); @@ -247,39 +218,33 @@ public ORole getRole(final OIdentifiable iRole) { return null; } - public ORole getRole(final String iRoleName) { - return getRole(iRoleName, true); + public ORole getRole(final String roleName) { + return getRole(roleName, true); } - public ORole getRole(final String iRoleName, final boolean iAllowRepair) { - if (cachedRoles != null) { - final ORole role = cachedRoles.get(iRoleName); - if (role != null) - return role; - } - + public ORole getRole(final String roleName, final boolean allowRepair) { List result; try { result = getDatabase(). command( - new OSQLSynchQuery("select from ORole where name = '" + iRoleName + "' limit 1")).execute(); + new OSQLSynchQuery("select from ORole where name = '" + roleName + "' limit 1")).execute(); - if (iRoleName.equalsIgnoreCase("admin") && result.isEmpty()) { - if (iAllowRepair) + if (roleName.equalsIgnoreCase("admin") && result.isEmpty()) { + if (allowRepair) repair(); result = getDatabase(). command( - new OSQLSynchQuery("select from ORole where name = '" + iRoleName + "' limit 1")).execute(); + new OSQLSynchQuery("select from ORole where name = '" + roleName + "' limit 1")).execute(); } } catch (Exception e) { - if (iAllowRepair) + if (allowRepair) repair(); result = getDatabase(). command( - new OSQLSynchQuery("select from ORole where name = '" + iRoleName + "' limit 1").setFetchPlan("roles:1")) + new OSQLSynchQuery("select from ORole where name = '" + roleName + "' limit 1").setFetchPlan("roles:1")) .execute(); } if (result != null && !result.isEmpty()) - return cacheRole(new ORole(result.get(0))); + return new ORole(result.get(0)); return null; @@ -291,13 +256,10 @@ public ORole createRole(final String iRoleName, final ORole.ALLOW_MODES iAllowMo public ORole createRole(final String iRoleName, final ORole iParent, final ORole.ALLOW_MODES iAllowMode) { final ORole role = new ORole(iRoleName, iParent, iAllowMode); - cacheRole(role); return role.save(); } public boolean dropRole(final String iRoleName) { - uncacheRole(iRoleName); - final Number removed = getDatabase(). command( new OCommandSQL("delete from ORole where name = '" + iRoleName + "'")).execute(); @@ -364,12 +326,7 @@ public OUser repair() { OLogManager.instance().warn(this, "Repairing security structures..."); try { - if (cachedUsers != null) - cachedUsers.clear(); getDatabase().getMetadata().getIndexManager().dropIndex("OUser.name"); - - if (cachedRoles != null) - cachedRoles.clear(); getDatabase().getMetadata().getIndexManager().dropIndex("ORole.name"); return createMetadata(); @@ -455,6 +412,13 @@ else if (userClass.getSuperClass() == null) restrictedClass.createProperty(ALLOW_DELETE_FIELD, OType.LINKSET, database.getMetadata().getSchema().getClass(IDENTITY_CLASSNAME)); + final OLevel2RecordCache cache = getDatabase().getLevel2Cache(); + for (final int clusterId : userClass.getPolymorphicClusterIds()) + cache.addPinnedCluster(clusterId); + + for (final int clusterId : roleClass.getPolymorphicClusterIds()) + cache.addPinnedCluster(clusterId); + return adminUser; } @@ -462,8 +426,13 @@ public void close(boolean onDelete) { } public void load() { + final OLevel2RecordCache cache = getDatabase().getLevel2Cache(); + final OClass userClass = getDatabase().getMetadata().getSchema().getClass("OUser"); if (userClass != null) { + for (final int clusterId : userClass.getPolymorphicClusterIds()) + cache.addPinnedCluster(clusterId); + // @COMPATIBILITY <1.3.0 if (!userClass.existsProperty("status")) { userClass.createProperty("status", OType.STRING).setMandatory(true).setNotNull(true); @@ -477,6 +446,9 @@ public void load() { // ROLE final OClass roleClass = getDatabase().getMetadata().getSchema().getClass("ORole"); + for (final int clusterId : roleClass.getPolymorphicClusterIds()) + cache.addPinnedCluster(clusterId); + if (!roleClass.existsProperty("inheritedRole")) { roleClass.createProperty("inheritedRole", OType.LINK, roleClass); } @@ -488,6 +460,7 @@ public void load() { if (roleClass.getInvolvedIndexes("name") == null) p.createIndex(INDEX_TYPE.UNIQUE); } + } public void createClassTrigger() { @@ -503,13 +476,6 @@ public OSecurity getUnderlying() { } protected OUser getUser(final String iUserName, final boolean iAllowRepair) { - - if (cachedUsers != null) { - final OUser user = cachedUsers.get(iUserName); - if (user != null) - return user; - } - List result; try { result = getDatabase(). command( @@ -532,43 +498,9 @@ protected OUser getUser(final String iUserName, final boolean iAllowRepair) { } if (result != null && !result.isEmpty()) - return cacheUser(new OUser(result.get(0))); + return new OUser(result.get(0)); return null; - - } - - protected OUser cacheUser(final OUser user) { - if (cachedUsers != null) - cachedUsers.put(user.getName(), user); - return user; - } - - protected void uncacheUser(final String iName) { - if (cachedUsers != null) - cachedUsers.remove(iName); - } - - protected void uncacheUsersOfRole(final String iName) { - if (cachedUsers != null) { - for (final Iterator> it = cachedUsers.entrySet().iterator(); it.hasNext();) { - if (it.next().getValue().hasRole(iName, true)) - it.remove(); - } - } - } - - protected ORole cacheRole(final ORole iRole) { - if (cachedRoles != null) - cachedRoles.put(iRole.getName(), iRole); - return iRole; - } - - protected void uncacheRole(final String iName) { - if (cachedRoles != null) { - cachedRoles.remove(iName); - uncacheUsersOfRole(iName); - } } private ODatabaseRecord getDatabase() { diff --git a/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OUserTrigger.java b/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OUserTrigger.java index 24f92c9bc68..78ac8ae3881 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OUserTrigger.java +++ b/core/src/main/java/com/orientechnologies/orient/core/metadata/security/OUserTrigger.java @@ -48,15 +48,7 @@ public RESULT onRecordBeforeUpdate(final ODocument iDocument) { if ("OUser".equalsIgnoreCase(iDocument.getClassName())) { // REMOVE THE USER FROM THE CACHE final OSecurity sec = ODatabaseRecordThreadLocal.INSTANCE.get().getMetadata().getSecurity().getUnderlying(); - if (sec instanceof OSecurityShared) - ((OSecurityShared) sec).uncacheUser((String) iDocument.field("name")); - return encodePassword(iDocument); - - } else if ("ORole".equalsIgnoreCase(iDocument.getClassName())) { - final OSecurity sec = ODatabaseRecordThreadLocal.INSTANCE.get().getMetadata().getSecurity().getUnderlying(); - if (sec instanceof OSecurityShared) - ((OSecurityShared) sec).uncacheRole((String) iDocument.field("name")); } return RESULT.RECORD_NOT_CHANGED; diff --git a/core/src/main/java/com/orientechnologies/orient/core/record/impl/ODocument.java b/core/src/main/java/com/orientechnologies/orient/core/record/impl/ODocument.java index c2d18198f1a..f2095f5511a 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/record/impl/ODocument.java +++ b/core/src/main/java/com/orientechnologies/orient/core/record/impl/ODocument.java @@ -323,6 +323,8 @@ public ODocument flatCopy() { throw new IllegalStateException("Cannot execute a flat copy of a dirty record"); final ODocument cloned = new ODocument(); + + cloned._pinned = _pinned; cloned.setOrdered(_ordered); cloned.fill(_recordId, _recordVersion, _source, false); return cloned; diff --git a/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/OStorageConfigurationSegment.java b/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/OStorageConfigurationSegment.java index 84994eba877..9a2a78400bc 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/OStorageConfigurationSegment.java +++ b/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/OStorageConfigurationSegment.java @@ -31,8 +31,8 @@ */ @SuppressWarnings("serial") public class OStorageConfigurationSegment extends OStorageConfiguration { - private static final int START_SIZE = 10000; - private OSingleFileSegment segment; + private static final int START_SIZE = 10000; + private final OSingleFileSegment segment; public OStorageConfigurationSegment(final OStorageLocalAbstract iStorage) throws IOException { super(iStorage); diff --git a/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/OStorageLocal.java b/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/OStorageLocal.java index 97af094df6a..9572a6db96a 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/OStorageLocal.java +++ b/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/OStorageLocal.java @@ -1484,11 +1484,6 @@ public String getPhysicalClusterNameById(final int iClusterId) { } } - @Override - public OStorageConfiguration getConfiguration() { - return configuration; - } - public int getDefaultClusterId() { return defaultClusterId; } diff --git a/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/paginated/OLocalPaginatedStorage.java b/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/paginated/OLocalPaginatedStorage.java index c23560adaff..edc26474560 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/paginated/OLocalPaginatedStorage.java +++ b/core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/paginated/OLocalPaginatedStorage.java @@ -268,7 +268,7 @@ public void open(final String iUserName, final String iUserPassword, final Map com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 orientdb-distributed diff --git a/distributed/src/main/java/com/orientechnologies/orient/server/hazelcast/OHazelcastDistributedDatabase.java b/distributed/src/main/java/com/orientechnologies/orient/server/hazelcast/OHazelcastDistributedDatabase.java index 760ea57a49a..b30db0af8f4 100644 --- a/distributed/src/main/java/com/orientechnologies/orient/server/hazelcast/OHazelcastDistributedDatabase.java +++ b/distributed/src/main/java/com/orientechnologies/orient/server/hazelcast/OHazelcastDistributedDatabase.java @@ -233,21 +233,21 @@ public void run() { try { message = readRequest(requestQueue); - // DECIDE TO USE THE HZ MAP ONLY IF THE COMMAND IS NOT IDEMPOTENT (ALL BUT READ-RECORD/SQL SELECT/SQL TRAVERSE - final boolean saveAsPending = !message.getTask().isIdempotent(); + if (message != null) { + // DECIDE TO USE THE HZ MAP ONLY IF THE COMMAND IS NOT IDEMPOTENT (ALL BUT READ-RECORD/SQL SELECT/SQL TRAVERSE + final boolean saveAsPending = !message.getTask().isIdempotent(); - if (saveAsPending) - // SAVE THE MESSAGE IN TO THE UNDO MAP IN CASE OF FAILURE - lastPendingMessagesMap.put(databaseName, message); + if (saveAsPending) + // SAVE THE MESSAGE IN TO THE UNDO MAP IN CASE OF FAILURE + lastPendingMessagesMap.put(databaseName, message); - if (message != null) { senderNode = message.getSenderNodeName(); onMessage(message); - } - if (saveAsPending) - // OK: REMOVE THE UNDO BUFFER - lastPendingMessagesMap.remove(databaseName); + if (saveAsPending) + // OK: REMOVE THE UNDO BUFFER + lastPendingMessagesMap.remove(databaseName); + } } catch (InterruptedException e) { // EXIT CURRENT THREAD diff --git a/distributed/src/main/java/com/orientechnologies/orient/server/hazelcast/OHazelcastPlugin.java b/distributed/src/main/java/com/orientechnologies/orient/server/hazelcast/OHazelcastPlugin.java index 7a5dbd9f27d..72635d082ae 100755 --- a/distributed/src/main/java/com/orientechnologies/orient/server/hazelcast/OHazelcastPlugin.java +++ b/distributed/src/main/java/com/orientechnologies/orient/server/hazelcast/OHazelcastPlugin.java @@ -153,7 +153,9 @@ public void startup() { status = NODE_STATUS.STARTING; - OLogManager.instance().info(this, "Starting distributed server '%s'...", getLocalNodeName()); + final String localNodeName = getLocalNodeName(); + + OLogManager.instance().info(this, "Starting distributed server '%s'...", localNodeName); activeNodes.clear(); @@ -162,22 +164,24 @@ public void startup() { nodeId = hazelcastInstance.getCluster().getLocalMember().getUuid(); timeOffset = System.currentTimeMillis() - hazelcastInstance.getCluster().getClusterTime(); - activeNodes.put(getLocalNodeName(), hazelcastInstance.getCluster().getLocalMember()); + activeNodes.put(localNodeName, hazelcastInstance.getCluster().getLocalMember()); membershipListenerRegistration = hazelcastInstance.getCluster().addMembershipListener(this); - OServer.registerServerInstance(getLocalNodeName(), serverInstance); + OServer.registerServerInstance(localNodeName, serverInstance); final IMap configurationMap = (IMap) getConfigurationMap(); configurationMap.addEntryListener(this, true); // REGISTER CURRENT NODES for (Member m : hazelcastInstance.getCluster().getMembers()) { - final String memberName = getNodeName(m); - if (memberName != null) - activeNodes.put(memberName, m); - else if (!m.equals(hazelcastInstance.getCluster().getLocalMember())) - ODistributedServerLog.warn(this, getLocalNodeName(), null, DIRECTION.NONE, "Cannot find configuration for member: %s", m); + if (!m.getUuid().equals(getLocalNodeId())) { + final String memberName = getNodeName(m); + if (memberName != null) + activeNodes.put(memberName, m); + else if (!m.equals(hazelcastInstance.getCluster().getLocalMember())) + ODistributedServerLog.warn(this, localNodeName, null, DIRECTION.NONE, "Cannot find configuration for member: %s", m); + } } messageService = new OHazelcastDistributedMessageService(this); @@ -842,10 +846,10 @@ protected void installNewDatabases(final boolean iStartup) { if (result instanceof Boolean) continue; - else if (value instanceof Exception) { + else if (result instanceof Exception) { ODistributedServerLog.error(this, getLocalNodeName(), r.getKey(), DIRECTION.IN, - "error on installing database %s in %s (chunk #%d)", (Exception) value, databaseName, dbPath, chunkNum); - } else if (value instanceof ODistributedDatabaseChunk) { + "error on installing database %s in %s (chunk #%d)", (Exception) result, databaseName, dbPath, chunkNum); + } else if (result instanceof ODistributedDatabaseChunk) { chunk = (ODistributedDatabaseChunk) result; fileSize += writeDatabaseChunk(chunkNum, chunk, out); } diff --git a/distribution/pom.xml b/distribution/pom.xml index cfc5d0cb107..8f0465d2df5 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -24,7 +24,7 @@ com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 ../ diff --git a/enterprise/pom.xml b/enterprise/pom.xml index 69221eb85fb..37fc9ebcf65 100644 --- a/enterprise/pom.xml +++ b/enterprise/pom.xml @@ -24,7 +24,7 @@ com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 orientdb-enterprise diff --git a/enterprise/src/main/java/com/orientechnologies/orient/enterprise/channel/binary/OChannelBinaryAsynchClient.java b/enterprise/src/main/java/com/orientechnologies/orient/enterprise/channel/binary/OChannelBinaryAsynchClient.java index 3958596e925..dd3559acc28 100755 --- a/enterprise/src/main/java/com/orientechnologies/orient/enterprise/channel/binary/OChannelBinaryAsynchClient.java +++ b/enterprise/src/main/java/com/orientechnologies/orient/enterprise/channel/binary/OChannelBinaryAsynchClient.java @@ -15,17 +15,6 @@ */ package com.orientechnologies.orient.enterprise.channel.binary; -import com.orientechnologies.common.concur.OTimeoutException; -import com.orientechnologies.common.concur.lock.OLockException; -import com.orientechnologies.common.exception.OException; -import com.orientechnologies.common.log.OLogManager; -import com.orientechnologies.common.util.OPair; -import com.orientechnologies.orient.core.config.OContextConfiguration; -import com.orientechnologies.orient.core.config.OGlobalConfiguration; -import com.orientechnologies.orient.core.exception.OStorageException; -import com.orientechnologies.orient.core.serialization.OMemoryInputStream; -import com.orientechnologies.orient.enterprise.channel.OSocketFactory; - import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; @@ -41,16 +30,27 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; +import com.orientechnologies.common.concur.OTimeoutException; +import com.orientechnologies.common.concur.lock.OLockException; +import com.orientechnologies.common.exception.OException; +import com.orientechnologies.common.log.OLogManager; +import com.orientechnologies.common.util.OPair; +import com.orientechnologies.orient.core.config.OContextConfiguration; +import com.orientechnologies.orient.core.config.OGlobalConfiguration; +import com.orientechnologies.orient.core.exception.OStorageException; +import com.orientechnologies.orient.core.serialization.OMemoryInputStream; +import com.orientechnologies.orient.enterprise.channel.OSocketFactory; + public class OChannelBinaryAsynchClient extends OChannelBinary { - protected final int socketTimeout; // IN MS - protected final short srvProtocolVersion; - private final Condition readCondition = getLockRead().getUnderlying().newCondition(); - private final int maxUnreadResponses; - private String serverURL; - private volatile boolean channelRead = false; - private byte currentStatus; - private int currentSessionId; - private OAsynchChannelServiceThread serviceThread; + protected final int socketTimeout; // IN MS + protected final short srvProtocolVersion; + private final Condition readCondition = getLockRead().getUnderlying().newCondition(); + private final int maxUnreadResponses; + private String serverURL; + private volatile boolean channelRead = false; + private byte currentStatus; + private int currentSessionId; + private volatile OAsynchChannelServiceThread serviceThread; public OChannelBinaryAsynchClient(final String remoteHost, final int remotePort, final String iDatabaseName, final OContextConfiguration iConfig, final int iProtocolVersion) throws IOException { @@ -139,9 +139,9 @@ private static RuntimeException createException(final String iClassName, final S rootException = (RuntimeException) e; else rootException = new OException(e); - } catch (InstantiationException e) { - } catch (IllegalAccessException e) { - } catch (InvocationTargetException e) { + } catch (InstantiationException ignored) { + } catch (IllegalAccessException ignored) { + } catch (InvocationTargetException ignored) { } return rootException; @@ -313,9 +313,7 @@ public void clearInput() throws IOException { */ public boolean isConnected() { final Socket s = socket; - if (s != null && s.isConnected() && !s.isInputShutdown() && !s.isOutputShutdown()) - return true; - return false; + return s != null && s.isConnected() && !s.isInputShutdown() && !s.isOutputShutdown(); } /** @@ -331,10 +329,7 @@ public String getServerURL() { } public boolean tryLock() { - if (getLockWrite().tryAcquireLock()) { - return true; - } - return false; + return getLockWrite().tryAcquireLock(); } public void unlock() { @@ -343,8 +338,8 @@ public void unlock() { protected int handleStatus(final byte iResult, final int iClientTxId) throws IOException { if (iResult == OChannelBinaryProtocol.RESPONSE_STATUS_OK || iResult == OChannelBinaryProtocol.PUSH_DATA) { + return iClientTxId; } else if (iResult == OChannelBinaryProtocol.RESPONSE_STATUS_ERROR) { - StringBuilder buffer = new StringBuilder(); final List> exceptions = new ArrayList>(); @@ -371,14 +366,13 @@ protected int handleStatus(final byte iResult, final int iClientTxId) throws IOE if (previous != null) { throw new RuntimeException(previous); } else - throw new ONetworkProtocolException("Network response error: " + buffer.toString()); + throw new ONetworkProtocolException("Network response error"); } else { // PROTOCOL ERROR // close(); throw new ONetworkProtocolException("Error on reading response from the server"); } - return iClientTxId; } private void throwSerializedException(final byte[] serializedException) throws IOException { diff --git a/graphdb/pom.xml b/graphdb/pom.xml index 4e97fd24a07..0ee33487414 100644 --- a/graphdb/pom.xml +++ b/graphdb/pom.xml @@ -24,7 +24,7 @@ com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 ../ diff --git a/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientBaseGraph.java b/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientBaseGraph.java index cb2b4c90f1a..01ee86e48ec 100755 --- a/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientBaseGraph.java +++ b/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientBaseGraph.java @@ -1,5 +1,17 @@ package com.tinkerpop.blueprints.impls.orient; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.configuration.Configuration; + import com.orientechnologies.common.exception.OException; import com.orientechnologies.common.io.OFileUtils; import com.orientechnologies.common.log.OLogManager; @@ -37,17 +49,6 @@ import com.tinkerpop.blueprints.util.ExceptionFactory; import com.tinkerpop.blueprints.util.StringFactory; import com.tinkerpop.blueprints.util.wrappers.partition.PartitionVertex; -import org.apache.commons.configuration.Configuration; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; /** * A Blueprints implementation of the graph database OrientDB (http://www.orientechnologies.com) @@ -861,6 +862,8 @@ public void removeEdge(final Edge edge) { * Underlying database object */ public OrientBaseGraph reuse(final ODatabaseDocumentTx iDatabase) { + ODatabaseRecordThreadLocal.INSTANCE.set(iDatabase); + this.url = iDatabase.getURL(); this.username = iDatabase.getUser() != null ? iDatabase.getUser().getName() : null; synchronized (this) { diff --git a/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientEdgeType.java b/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientEdgeType.java index cdd98202587..4d098746277 100644 --- a/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientEdgeType.java +++ b/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientEdgeType.java @@ -17,7 +17,6 @@ package com.tinkerpop.blueprints.impls.orient; import com.orientechnologies.orient.core.metadata.schema.OClass; -import com.orientechnologies.orient.core.metadata.schema.OClassAbstractDelegate; import com.orientechnologies.orient.core.storage.OStorage; /** @@ -25,18 +24,15 @@ * * @author Luca Garulli (http://www.orientechnologies.com) */ -public class OrientEdgeType extends OClassAbstractDelegate { - public static final String CLASS_NAME = "E"; - protected final OrientBaseGraph graph; +public class OrientEdgeType extends OrientElementType { + public static final String CLASS_NAME = "E"; public OrientEdgeType(final OrientBaseGraph graph, final OClass delegate) { - super(delegate); - this.graph = graph; + super(graph, delegate); } public OrientEdgeType(final OrientBaseGraph graph) { - super(graph.getRawGraph().getMetadata().getSchema().getClass(CLASS_NAME)); - this.graph = graph; + super(graph, graph.getRawGraph().getMetadata().getSchema().getClass(CLASS_NAME)); } protected static final void checkType(final OClass iType) { @@ -65,4 +61,8 @@ public OrientEdgeType addCluster(final String iClusterName, final OStorage.CLUST return this; } + @Override + protected String getTypeName() { + return "edge"; + } } diff --git a/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientElementType.java b/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientElementType.java new file mode 100644 index 00000000000..05561805436 --- /dev/null +++ b/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientElementType.java @@ -0,0 +1,129 @@ +/* + * Copyright 2010-2014 Orient Technologies LTD (info--at--orientechnologies.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. + */ + +package com.tinkerpop.blueprints.impls.orient; + +import com.orientechnologies.common.listener.OProgressListener; +import com.orientechnologies.common.util.OCallable; +import com.orientechnologies.orient.core.index.OIndex; +import com.orientechnologies.orient.core.metadata.schema.OClass; +import com.orientechnologies.orient.core.metadata.schema.OClassAbstractDelegate; +import com.orientechnologies.orient.core.metadata.schema.OProperty; +import com.orientechnologies.orient.core.metadata.schema.OType; +import com.orientechnologies.orient.core.record.impl.ODocument; + +import java.util.Arrays; + +/** + * Represents a generic element class + * + * @author Luca Garulli (http://www.orientechnologies.com) + */ +public abstract class OrientElementType extends OClassAbstractDelegate { + protected final OrientBaseGraph graph; + + public OrientElementType(final OrientBaseGraph graph, final OClass delegate) { + super(delegate); + this.graph = graph; + } + + @Override + public OProperty createProperty(final String iPropertyName, final OType iType, final OClass iLinkedClass) { + return graph.executeOutsideTx(new OCallable() { + @Override + public OProperty call(final OrientBaseGraph g) { + return OrientElementType.super.createProperty(iPropertyName, iType, iLinkedClass); + } + }, "create ", getTypeName(), " property '", iPropertyName, "' as type '", iType.toString(), "' linked class '", + iLinkedClass.getName(), "'"); + } + + @Override + public OProperty createProperty(final String iPropertyName, final OType iType, final OType iLinkedType) { + return graph.executeOutsideTx(new OCallable() { + @Override + public OProperty call(final OrientBaseGraph g) { + return OrientElementType.super.createProperty(iPropertyName, iType, iLinkedType); + } + }, "create ", getTypeName(), " property '", iPropertyName, "' as type '", iType.toString(), "' linked type '", + iLinkedType.toString(), "'"); + } + + @Override + public OProperty createProperty(final String iPropertyName, final OType iType) { + return graph.executeOutsideTx(new OCallable() { + @Override + public OProperty call(final OrientBaseGraph g) { + return OrientElementType.super.createProperty(iPropertyName, iType); + } + }, "create ", getTypeName(), " property '", iPropertyName, "' as type '", iType.toString(), "'"); + } + + @Override + public OIndex createIndex(final String iName, final INDEX_TYPE iType, final String... fields) { + return graph.executeOutsideTx(new OCallable, OrientBaseGraph>() { + @Override + public OIndex call(final OrientBaseGraph g) { + return OrientElementType.super.createIndex(iName, iType, fields); + } + }, "create index '", iName, "' as type '", iType.toString(), "' on fields: " + Arrays.toString(fields)); + } + + @Override + public OIndex createIndex(final String iName, final String iType, final String... fields) { + return graph.executeOutsideTx(new OCallable, OrientBaseGraph>() { + @Override + public OIndex call(final OrientBaseGraph g) { + return OrientElementType.super.createIndex(iName, iType, fields); + } + }, "create index '", iName, "' as type '", iType.toString(), "' on fields: " + Arrays.toString(fields)); + } + + @Override + public OIndex createIndex(final String iName, final INDEX_TYPE iType, final OProgressListener iProgressListener, + final String... fields) { + return graph.executeOutsideTx(new OCallable, OrientBaseGraph>() { + @Override + public OIndex call(final OrientBaseGraph g) { + return OrientElementType.super.createIndex(iName, iType, iProgressListener, fields); + } + }, "create index '", iName, "' as type '", iType.toString(), "' on fields: " + Arrays.toString(fields)); + } + + @Override + public OIndex createIndex(final String iName, final String iType, final OProgressListener iProgressListener, + final ODocument metadata, final String algorithm, final String... fields) { + return graph.executeOutsideTx(new OCallable, OrientBaseGraph>() { + @Override + public OIndex call(final OrientBaseGraph g) { + return OrientElementType.super.createIndex(iName, iType, iProgressListener, metadata, algorithm, fields); + } + }, "create index '", iName, "' as type '", iType.toString(), "' on fields: " + Arrays.toString(fields)); + } + + @Override + public OIndex createIndex(final String iName, final String iType, final OProgressListener iProgressListener, + final ODocument metadata, final String... fields) { + return graph.executeOutsideTx(new OCallable, OrientBaseGraph>() { + @Override + public OIndex call(final OrientBaseGraph g) { + return OrientElementType.super.createIndex(iName, iType, iProgressListener, metadata, fields); + } + }, "create index '", iName, "' as type '", iType.toString(), "' on fields: " + Arrays.toString(fields)); + } + + protected abstract String getTypeName(); +} diff --git a/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientVertex.java b/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientVertex.java index 00f9322ff10..35d9a5c0d9d 100755 --- a/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientVertex.java +++ b/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientVertex.java @@ -1,12 +1,5 @@ package com.tinkerpop.blueprints.impls.orient; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - import com.orientechnologies.common.collection.OMultiCollectionIterator; import com.orientechnologies.common.log.OLogManager; import com.orientechnologies.common.util.OPair; @@ -29,6 +22,13 @@ import com.tinkerpop.blueprints.util.StringFactory; import com.tinkerpop.blueprints.util.wrappers.partition.PartitionVertex; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * OrientDB Vertex implementation of TinkerPop Blueprints standard. * @@ -1026,7 +1026,7 @@ private boolean canCreateDynamicEdge(final ODocument iFromVertex, final ODocumen final OClass cls = graph.getEdgeType(label); if (cls != null) for (OProperty p : cls.properties()) { - if (p.isMandatory() || p.isNotNull()) + if (p.isMandatory() || p.isNotNull() || !p.getOwnerClass().getInvolvedIndexes(p.getName()).isEmpty()) return false; } } diff --git a/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientVertexType.java b/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientVertexType.java index 4999fe31d66..77126968e2b 100644 --- a/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientVertexType.java +++ b/graphdb/src/main/java/com/tinkerpop/blueprints/impls/orient/OrientVertexType.java @@ -17,7 +17,6 @@ package com.tinkerpop.blueprints.impls.orient; import com.orientechnologies.orient.core.metadata.schema.OClass; -import com.orientechnologies.orient.core.metadata.schema.OClassAbstractDelegate; import com.orientechnologies.orient.core.metadata.schema.OProperty; import com.orientechnologies.orient.core.metadata.schema.OPropertyAbstractDelegate; import com.orientechnologies.orient.core.metadata.schema.OType; @@ -29,9 +28,8 @@ * * @author Luca Garulli (http://www.orientechnologies.com) */ -public class OrientVertexType extends OClassAbstractDelegate { - public static final String CLASS_NAME = "V"; - protected final OrientBaseGraph graph; +public class OrientVertexType extends OrientElementType { + public static final String CLASS_NAME = "V"; public class OrientVertexProperty extends OPropertyAbstractDelegate { protected final OrientBaseGraph graph; @@ -53,8 +51,7 @@ public OrientVertexProperty setOrdered(final boolean iOrdered) { } public OrientVertexType(final OrientBaseGraph graph, final OClass delegate) { - super(delegate); - this.graph = graph; + super(graph, delegate); } protected static final void checkType(final OClass iType) { @@ -66,21 +63,6 @@ protected static final void checkType(final OClass iType) { + "' and therefore cannot be considered a Vertex"); } - @Override - public OrientVertexProperty createProperty(final String iPropertyName, final OType iType) { - return new OrientVertexProperty(graph, delegate.createProperty(iPropertyName, iType)); - } - - @Override - public OrientVertexProperty createProperty(final String iPropertyName, final OType iType, final OClass iLinkedClass) { - return new OrientVertexProperty(graph, delegate.createProperty(iPropertyName, iType, iLinkedClass)); - } - - @Override - public OrientVertexProperty createProperty(final String iPropertyName, final OType iType, final OType iLinkedType) { - return new OrientVertexProperty(graph, delegate.createProperty(iPropertyName, iType, iLinkedType)); - } - public OrientVertexProperty createEdgeProperty(final Direction iDirection, String iEdgeClassName) { iEdgeClassName = OrientBaseGraph.encodeClassName(iEdgeClassName); @@ -108,4 +90,23 @@ public OrientVertexType addCluster(final String iClusterName, final OStorage.CLU return this; } + @Override + public OrientVertexProperty createProperty(final String iPropertyName, final OType iType, final OClass iLinkedClass) { + return new OrientVertexProperty(graph, super.createProperty(iPropertyName, iType, iLinkedClass)); + } + + @Override + public OrientVertexProperty createProperty(final String iPropertyName, final OType iType, final OType iLinkedType) { + return new OrientVertexProperty(graph, super.createProperty(iPropertyName, iType, iLinkedType)); + } + + @Override + public OrientVertexProperty createProperty(final String iPropertyName, final OType iType) { + return new OrientVertexProperty(graph, super.createProperty(iPropertyName, iType)); + } + + @Override + protected String getTypeName() { + return "vertex"; + } } diff --git a/graphdb/src/test/java/com/orientechnologies/orient/graph/blueprints/GraphTests.java b/graphdb/src/test/java/com/orientechnologies/orient/graph/blueprints/GraphTests.java index d6b9fb3646c..c994503c389 100644 --- a/graphdb/src/test/java/com/orientechnologies/orient/graph/blueprints/GraphTests.java +++ b/graphdb/src/test/java/com/orientechnologies/orient/graph/blueprints/GraphTests.java @@ -18,20 +18,19 @@ package com.orientechnologies.orient.graph.blueprints; -import static org.junit.Assert.fail; - -import org.junit.Test; - import com.orientechnologies.orient.core.index.OIndexException; import com.orientechnologies.orient.core.metadata.schema.OType; import com.orientechnologies.orient.core.storage.ORecordDuplicatedException; import com.tinkerpop.blueprints.Parameter; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.blueprints.impls.orient.OrientGraph; +import org.junit.Test; + +import static org.junit.Assert.fail; public class GraphTests { - public static final String URL = "plocal:/target/databases/testExceptionOnCommit"; + public static final String URL = "plocal:target/databases/testExceptionOnCommit"; @Test public void indexes() { diff --git a/graphdb/src/test/java/com/orientechnologies/orient/graph/blueprints/IndexAgainstEdges.java b/graphdb/src/test/java/com/orientechnologies/orient/graph/blueprints/IndexAgainstEdges.java new file mode 100644 index 00000000000..7f714bc49d1 --- /dev/null +++ b/graphdb/src/test/java/com/orientechnologies/orient/graph/blueprints/IndexAgainstEdges.java @@ -0,0 +1,59 @@ +/* + * + * * Copyright 2010-2014 Orient Technologies LTD (info(at)orientechnologies.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. + * + */ + +package com.orientechnologies.orient.graph.blueprints; + +import com.orientechnologies.orient.core.metadata.schema.OClass; +import com.orientechnologies.orient.core.metadata.schema.OType; +import com.tinkerpop.blueprints.impls.orient.OrientEdge; +import com.tinkerpop.blueprints.impls.orient.OrientEdgeType; +import com.tinkerpop.blueprints.impls.orient.OrientGraph; +import com.tinkerpop.blueprints.impls.orient.OrientVertex; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; + +public class IndexAgainstEdges { + + public static final String URL = "plocal:target/databases/indexAgainstEdges"; + + @Test + public void indexes() { + OrientGraph g = new OrientGraph(URL, "admin", "admin"); + try { + if (g.getVertexType("Profile") == null) + g.createVertexType("Profile"); + if (g.getEdgeType("Friend") == null) { + final OrientEdgeType f = g.createEdgeType("Friend"); + f.createProperty("in", OType.LINK); + f.createProperty("out", OType.LINK); + f.createIndex("Friend.in_out", OClass.INDEX_TYPE.UNIQUE, "in", "out"); + + } + + OrientVertex luca = g.addVertex("class:Profile", "name", "Luca"); + OrientVertex jay = g.addVertex("class:Profile", "name", "Jay"); + OrientEdge friend = (OrientEdge) luca.addEdge("Friend", jay); + + assertFalse(friend.isLightweight()); + + } finally { + g.shutdown(); + } + } +} diff --git a/nativeos/pom.xml b/nativeos/pom.xml index 037dd16e4cc..03a08e4c947 100644 --- a/nativeos/pom.xml +++ b/nativeos/pom.xml @@ -20,7 +20,7 @@ orientdb-parent com.orientechnologies - 1.7.1 + 1.7.2 ../ 4.0.0 diff --git a/object/pom.xml b/object/pom.xml index 683e605a396..297928bfabd 100644 --- a/object/pom.xml +++ b/object/pom.xml @@ -22,7 +22,7 @@ com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 orientdb-object diff --git a/pom.xml b/pom.xml index 332a28c1ba9..0f78b1eaff8 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 pom OrientDB diff --git a/server/pom.xml b/server/pom.xml index c0adc10247d..321a39bbcad 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -24,7 +24,7 @@ com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 orientdb-server diff --git a/server/src/main/java/com/orientechnologies/orient/server/OClientConnection.java b/server/src/main/java/com/orientechnologies/orient/server/OClientConnection.java index 6074e815999..f6da57314bd 100644 --- a/server/src/main/java/com/orientechnologies/orient/server/OClientConnection.java +++ b/server/src/main/java/com/orientechnologies/orient/server/OClientConnection.java @@ -23,11 +23,13 @@ import com.orientechnologies.orient.server.network.protocol.ONetworkProtocolData; import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; import java.net.InetSocketAddress; public class OClientConnection { public final int id; - public final ONetworkProtocol protocol; + public volatile ONetworkProtocol protocol; public final long since; public volatile ODatabaseDocumentTx database; public volatile ODatabaseRaw rawDatabase; @@ -35,15 +37,17 @@ public class OClientConnection { public ONetworkProtocolData data = new ONetworkProtocolData(); - public OClientConnection(final int iId, final ONetworkProtocol iProtocol) throws IOException { - this.id = iId; - this.protocol = iProtocol; + public OClientConnection(final int id, final ONetworkProtocol protocol) throws IOException { + this.id = id; + this.protocol = protocol; this.since = System.currentTimeMillis(); } public void close() { if (database != null) { - database.close(); + if (!database.isClosed()) + database.close(); + database = null; } } diff --git a/server/src/main/java/com/orientechnologies/orient/server/OClientConnectionManager.java b/server/src/main/java/com/orientechnologies/orient/server/OClientConnectionManager.java index 01d3741d2d5..2031d8414f4 100755 --- a/server/src/main/java/com/orientechnologies/orient/server/OClientConnectionManager.java +++ b/server/src/main/java/com/orientechnologies/orient/server/OClientConnectionManager.java @@ -71,6 +71,7 @@ public void run() { try { entry.getValue().close(); } catch (Exception e) { + OLogManager.instance().error(this, "Error during close of connection for close channel", e); } iterator.remove(); } @@ -117,14 +118,13 @@ public OClientConnection connect(final ONetworkProtocol iProtocol) throws IOExce * id of connection * @return The connection if any, otherwise null */ - public OClientConnection getConnection(final int iChannelId) { + public OClientConnection getConnection(final int iChannelId, ONetworkProtocol protocol) { // SEARCH THE CONNECTION BY ID - return connections.get(iChannelId); + OClientConnection connection = connections.get(iChannelId); + if (connection != null) + connection.protocol = protocol; - // COMMENTED TO USE SOCKET POOL: THINK TO ANOTHER WAY TO IMPROVE SECURITY - // if (conn != null && conn.getChannel().socket != socket) - // throw new IllegalStateException("Requested sessionId " + iChannelId + " by connection " + socket - // + " while it's tied to connection " + conn.getChannel().socket); + return connection; } /** diff --git a/server/src/main/java/com/orientechnologies/orient/server/network/protocol/binary/ONetworkProtocolBinary.java b/server/src/main/java/com/orientechnologies/orient/server/network/protocol/binary/ONetworkProtocolBinary.java index f608da9149c..f9acfb9cb72 100755 --- a/server/src/main/java/com/orientechnologies/orient/server/network/protocol/binary/ONetworkProtocolBinary.java +++ b/server/src/main/java/com/orientechnologies/orient/server/network/protocol/binary/ONetworkProtocolBinary.java @@ -151,7 +151,7 @@ public void shutdown() { protected void onBeforeRequest() throws IOException { waitNodeIsOnline(); - connection = OClientConnectionManager.instance().getConnection(clientTxId); + connection = OClientConnectionManager.instance().getConnection(clientTxId, this); if (clientTxId < 0) { short protocolId = 0; @@ -539,14 +539,11 @@ protected void addCluster() throws IOException { if (connection.data.protocolVersion >= 18) clusterId = channel.readShort(); - Object[] params = null; - final int num; - if (clusterId < 0) - num = connection.database.addCluster(type, name, location, dataSegmentName, params); + num = connection.database.addCluster(type, name, location, dataSegmentName); else - num = connection.database.addCluster(type, name, clusterId, location, dataSegmentName, params); + num = connection.database.addCluster(type, name, clusterId, location, dataSegmentName); beginResponse(); try { @@ -685,36 +682,17 @@ protected void sendError(final int iClientTxId, final Throwable t) throws IOExce channel.writeByte(OChannelBinaryProtocol.RESPONSE_STATUS_ERROR); channel.writeInt(iClientTxId); - Throwable current; + final Throwable current; if (t instanceof OLockException && t.getCause() instanceof ODatabaseException) // BYPASS THE DB POOL EXCEPTION TO PROPAGATE THE RIGHT SECURITY ONE current = t.getCause(); else current = t; - final Throwable original = current; - while (current != null) { - // MORE DETAILS ARE COMING AS EXCEPTION - channel.writeByte((byte) 1); - - channel.writeString(current.getClass().getName()); - channel.writeString(current.getMessage()); - - current = current.getCause(); - } - channel.writeByte((byte) 0); + sendErrorDetails(current); if (connection != null && connection.data.protocolVersion >= 19) { - final OMemoryStream memoryStream = new OMemoryStream(); - final ObjectOutputStream objectOutputStream = new ObjectOutputStream(memoryStream); - - objectOutputStream.writeObject(original); - objectOutputStream.flush(); - - final byte[] result = memoryStream.toByteArray(); - objectOutputStream.close(); - - channel.writeBytes(result); + serializeExceptionObject(current); } channel.flush(); @@ -730,6 +708,8 @@ protected void sendError(final int iClientTxId, final Throwable t) throws IOExce } catch (Exception e) { if (e instanceof SocketException) shutdown(); + else + OLogManager.instance().error(this, "Error during sending an error to client", e); } finally { if (channel.getLockWrite().isHeldByCurrentThread()) // NO EXCEPTION SO FAR: UNLOCK IT @@ -737,6 +717,39 @@ protected void sendError(final int iClientTxId, final Throwable t) throws IOExce } } + private void sendErrorDetails(Throwable current) throws IOException { + while (current != null) { + // MORE DETAILS ARE COMING AS EXCEPTION + channel.writeByte((byte) 1); + + channel.writeString(current.getClass().getName()); + channel.writeString(current.getMessage()); + + current = current.getCause(); + } + channel.writeByte((byte) 0); + } + + private void serializeExceptionObject(Throwable original) throws IOException { + try { + final OMemoryStream memoryStream = new OMemoryStream(); + final ObjectOutputStream objectOutputStream = new ObjectOutputStream(memoryStream); + + objectOutputStream.writeObject(original); + objectOutputStream.flush(); + + final byte[] result = memoryStream.toByteArray(); + objectOutputStream.close(); + + channel.writeBytes(result); + } catch (Exception e) { + OLogManager.instance().warn(this, "Can't serialize an exception object", e); + + // Write empty stream for binary compatibility + channel.writeBytes(new byte[0]); + } + } + protected void shutdownConnection() throws IOException { setDataCommandInfo("Shutdowning"); diff --git a/tests/pom.xml b/tests/pom.xml index 18dc17fba21..4c7fbcfc4f6 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -24,7 +24,7 @@ com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 ../ diff --git a/tests/src/test/java/com/orientechnologies/orient/test/database/auto/CRUDObjectPhysicalTest.java b/tests/src/test/java/com/orientechnologies/orient/test/database/auto/CRUDObjectPhysicalTest.java index ba0c4125b2c..5e1f85511c8 100755 --- a/tests/src/test/java/com/orientechnologies/orient/test/database/auto/CRUDObjectPhysicalTest.java +++ b/tests/src/test/java/com/orientechnologies/orient/test/database/auto/CRUDObjectPhysicalTest.java @@ -20,6 +20,8 @@ import java.util.*; import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Parameters; import org.testng.annotations.Test; @@ -59,6 +61,16 @@ public CRUDObjectPhysicalTest(String iURL) { url = iURL; } + @BeforeClass + public void beforeClass() { + + } + + @AfterClass + public void afterClass() { + + } + @Test public void create() { database = OObjectDatabasePool.global().acquire(url, "admin", "admin"); diff --git a/tests/src/test/java/com/orientechnologies/orient/test/database/auto/CRUDObjectPhysicalTestSchemaFull.java b/tests/src/test/java/com/orientechnologies/orient/test/database/auto/CRUDObjectPhysicalTestSchemaFull.java index 15c57f1b2f8..bfc35b5f243 100755 --- a/tests/src/test/java/com/orientechnologies/orient/test/database/auto/CRUDObjectPhysicalTestSchemaFull.java +++ b/tests/src/test/java/com/orientechnologies/orient/test/database/auto/CRUDObjectPhysicalTestSchemaFull.java @@ -2826,12 +2826,6 @@ public void testEmbeddedBinary() { for (int i = 0; i < 10; ++i) Assert.assertEquals(b[i], i); - // TO REFACTOR OR DELETE SINCE SERIALIZATION AND DESERIALIZATION DON'T APPLY ANYMORE - // Assert.assertNotNull(aa.getPhoto()); - // b = aa.getPhoto(); - // for (int i = 0; i < 10; ++i) - // Assert.assertEquals(b[i], i); - } finally { database.close(); } diff --git a/tests/src/test/java/com/orientechnologies/orient/test/database/auto/ORidBagTest.java b/tests/src/test/java/com/orientechnologies/orient/test/database/auto/ORidBagTest.java index 602e56fec56..1d07c83e8c1 100755 --- a/tests/src/test/java/com/orientechnologies/orient/test/database/auto/ORidBagTest.java +++ b/tests/src/test/java/com/orientechnologies/orient/test/database/auto/ORidBagTest.java @@ -33,6 +33,8 @@ import com.orientechnologies.orient.core.record.impl.ODocumentHelper; import com.orientechnologies.orient.core.storage.OStorage; import com.orientechnologies.orient.core.storage.OStorageProxy; +import com.tinkerpop.blueprints.impls.orient.OrientGraph; +import com.tinkerpop.blueprints.impls.orient.OrientVertex; @Test public abstract class ORidBagTest extends BaseTest { @@ -1435,5 +1437,26 @@ public void testJsonSerialization() { Assert.assertTrue(ODocumentHelper.hasSameContentOf(doc, database, testDocument, database, null)); } + public void stackOverflowDuringToString() { + final OrientGraph graph = new OrientGraph(database); + + OrientVertex a = graph.addVertex("A"); + OrientVertex b = graph.addVertex("B"); + OrientVertex c = graph.addVertex("C"); + + a.addEdge("link", b); + a.addEdge("link", c); + b.addEdge("link", a); + b.addEdge("link", c); + c.addEdge("link", a); + c.addEdge("link", b); + + System.out.println("A: " + a.getRecord()); + System.out.println("B: " + b.getRecord()); + System.out.println("C: " + c.getRecord()); + + database.commit(); + } + protected abstract void assertEmbedded(boolean isEmbedded); } diff --git a/tests/src/test/java/com/orientechnologies/orient/test/database/auto/OpenCloseMTTest.java b/tests/src/test/java/com/orientechnologies/orient/test/database/auto/OpenCloseMTTest.java index 6874987ac85..3fc44edf713 100644 --- a/tests/src/test/java/com/orientechnologies/orient/test/database/auto/OpenCloseMTTest.java +++ b/tests/src/test/java/com/orientechnologies/orient/test/database/auto/OpenCloseMTTest.java @@ -27,10 +27,33 @@ public class OpenCloseMTTest { private volatile boolean stop = false; + public class OpenCloser implements Callable { + @Override + public Void call() throws Exception { + while (!stop) { + try { + ODatabaseDocumentTx databaseDocumentTx = new ODatabaseDocumentTx(URL); + databaseDocumentTx.open("admin", "admin"); + + List result = databaseDocumentTx.query(new OSQLSynchQuery("select from OUser")); + Assert.assertTrue(!result.isEmpty()); + + Thread.sleep(500); + + databaseDocumentTx.close(); + + Thread.sleep(500); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + return null; + } + } + public void openCloseMTTest() throws Exception { OGlobalConfiguration.STORAGE_KEEP_OPEN.setValue(false); - OGlobalConfiguration.SECURITY_MAX_CACHED_USERS.setValue(0); - OGlobalConfiguration.SECURITY_MAX_CACHED_ROLES.setValue(0); ODatabaseDocumentTx databaseDocumentTx = new ODatabaseDocumentTx(URL); databaseDocumentTx.create(); @@ -54,29 +77,4 @@ public void openCloseMTTest() throws Exception { databaseDocumentTx.open("admin", "admin"); databaseDocumentTx.drop(); } - - public class OpenCloser implements Callable { - @Override - public Void call() throws Exception { - while (!stop) { - try { - ODatabaseDocumentTx databaseDocumentTx = new ODatabaseDocumentTx(URL); - databaseDocumentTx.open("admin", "admin"); - - List result = databaseDocumentTx.query(new OSQLSynchQuery("select from OUser")); - Assert.assertTrue(!result.isEmpty()); - - Thread.sleep(500); - - databaseDocumentTx.close(); - - Thread.sleep(500); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - return null; - } - } -} \ No newline at end of file +} diff --git a/tests/src/test/java/com/orientechnologies/orient/test/database/auto/remote-test-db-from-scratch.xml b/tests/src/test/java/com/orientechnologies/orient/test/database/auto/remote-test-db-from-scratch.xml index ed497c453c1..a2caadf6168 100755 --- a/tests/src/test/java/com/orientechnologies/orient/test/database/auto/remote-test-db-from-scratch.xml +++ b/tests/src/test/java/com/orientechnologies/orient/test/database/auto/remote-test-db-from-scratch.xml @@ -155,6 +155,8 @@ + + diff --git a/tools/pom.xml b/tools/pom.xml index d8376048dbc..eceddc3b6ab 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -22,7 +22,7 @@ com.orientechnologies orientdb-parent - 1.7.1 + 1.7.2 ../