Merge branch 'gerrit/neo' into 'gerrit/trinity'

Change-Id: I7d75e967b4641fd54c8c76882d3aff3d5c5c4898
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java
index 4d32967..61656b7 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java
@@ -22,6 +22,7 @@
 import java.rmi.RemoteException;
 import java.rmi.server.UnicastRemoteObject;
 import java.util.Collection;
+import java.util.OptionalInt;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -160,6 +161,7 @@
     private ICacheManager cacheManager;
     private IConfigValidator configValidator;
     private IDiskWriteRateLimiterProvider diskWriteRateLimiterProvider;
+    private Integer metadataPartitionId;
 
     public NCAppRuntimeContext(INCServiceContext ncServiceContext, NCExtensionManager extensionManager,
             IPropertiesFactory propertiesFactory) {
@@ -443,6 +445,7 @@
     @Override
     public void initializeMetadata(boolean newUniverse, int partitionId) throws Exception {
         LOGGER.info("Bootstrapping metadata");
+        metadataPartitionId = partitionId;
         MetadataNode.INSTANCE.initialize(this, ncExtensionManager.getMetadataTupleTranslatorProvider(),
                 ncExtensionManager.getMetadataExtensions(), partitionId);
 
@@ -636,4 +639,9 @@
     public IDiskWriteRateLimiterProvider getDiskWriteRateLimiterProvider() {
         return diskWriteRateLimiterProvider;
     }
+
+    @Override
+    public OptionalInt getMetadataPartitionId() {
+        return metadataPartitionId == null ? OptionalInt.empty() : OptionalInt.of(metadataPartitionId);
+    }
 }
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INcApplicationContext.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INcApplicationContext.java
index 5475b97..a5ae099 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INcApplicationContext.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INcApplicationContext.java
@@ -20,6 +20,7 @@
 
 import java.io.IOException;
 import java.rmi.RemoteException;
+import java.util.OptionalInt;
 import java.util.concurrent.Executor;
 
 import org.apache.asterix.common.context.IStorageComponentProvider;
@@ -147,4 +148,6 @@
      * @return the disk write rate limiter provider
      */
     IDiskWriteRateLimiterProvider getDiskWriteRateLimiterProvider();
+
+    OptionalInt getMetadataPartitionId();
 }
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/GlobalVirtualBufferCache.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/GlobalVirtualBufferCache.java
index a7210bc..63b6284 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/GlobalVirtualBufferCache.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/GlobalVirtualBufferCache.java
@@ -173,13 +173,16 @@
             // 2. there are still some active readers and memory cannot be reclaimed.
             // But for both cases, we will notify all primary index op trackers to let their writers retry,
             // if they have been blocked. Moreover, we will check whether more flushes are needed.
+            List<ILSMOperationTracker> opTrackers = new ArrayList<>();
             synchronized (this) {
                 final int size = primaryIndexes.size();
                 for (int i = 0; i < size; i++) {
-                    ILSMOperationTracker opTracker = primaryIndexes.get(i).getOperationTracker();
-                    synchronized (opTracker) {
-                        opTracker.notifyAll();
-                    }
+                    opTrackers.add(primaryIndexes.get(i).getOperationTracker());
+                }
+            }
+            for (ILSMOperationTracker opTracker : opTrackers) {
+                synchronized (opTracker) {
+                    opTracker.notifyAll();
                 }
             }
             checkAndNotifyFlushThread();
diff --git a/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/messaging/PartitionResourcesListTask.java b/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/messaging/PartitionResourcesListTask.java
index 0f5949e..97d03e6 100644
--- a/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/messaging/PartitionResourcesListTask.java
+++ b/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/messaging/PartitionResourcesListTask.java
@@ -51,6 +51,11 @@
     @Override
     public void perform(INcApplicationContext appCtx, IReplicationWorker worker) throws HyracksDataException {
         LOGGER.debug("processing {}", this);
+        if (appCtx.getMetadataPartitionId().isPresent() && appCtx.getMetadataPartitionId().getAsInt() == partition
+                && appCtx.getReplicaManager().getPartitions().contains(partition)) {
+            LOGGER.warn("received request to get metadata files from non-master {}", worker.getRemoteAddress());
+            throw new IllegalStateException();
+        }
         final PersistentLocalResourceRepository localResourceRepository =
                 (PersistentLocalResourceRepository) appCtx.getLocalResourceRepository();
         localResourceRepository.cleanup(partition);