package org.apache.solr.rest;
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.lucene.util.LuceneTestCase.Slow;
import org.apache.solr.cloud.AbstractZkTestCase;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrResourceLoader;
import org.apache.solr.rest.ManagedResourceStorage.StorageIO;
import org.apache.solr.rest.ManagedResourceStorage.FileStorageIO;
import org.apache.solr.rest.ManagedResourceStorage.ZooKeeperStorageIO;
import org.apache.solr.rest.ManagedResourceStorage.JsonStorage;
import org.junit.Test;

/**
 * Depends on ZK for testing ZooKeeper backed storage logic.
 */
@Slow
public class TestManagedResourceStorage extends AbstractZkTestCase {

  /**
   * Runs persisted managed resource creation and update tests on Zookeeper storage.
   */
  @Test
  public void testZkBasedJsonStorage() throws Exception {
    
    // test using ZooKeeper
    assertTrue("Not using ZooKeeper", h.getCoreContainer().isZooKeeperAware());    
    SolrZkClient zkClient = h.getCoreContainer().getZkController().getZkClient();    
    SolrResourceLoader loader = new SolrResourceLoader("./");    
    // Solr unit tests can only write to their working directory due to
    // a custom Java Security Manager installed in the test environment
    NamedList<String> initArgs = new NamedList<>();
    try {
      ZooKeeperStorageIO zkStorageIO = new ZooKeeperStorageIO(zkClient, "/test");
      zkStorageIO.configure(loader, initArgs);
      doStorageTests(loader, zkStorageIO);
    } finally {
      zkClient.close();
    }
  }


  /**
   * Runs persisted managed resource creation and update tests on JSON storage.
   */
  @Test
  public void testFileBasedJsonStorage() throws Exception {
    File instanceDir = createTempDir("json-storage");
    SolrResourceLoader loader = new SolrResourceLoader(instanceDir.getAbsolutePath());
    NamedList<String> initArgs = new NamedList<>();
    String managedDir = instanceDir.getAbsolutePath() + File.separator + "managed";
    initArgs.add(ManagedResourceStorage.STORAGE_DIR_INIT_ARG, managedDir);
    FileStorageIO fileStorageIO = new FileStorageIO();
    fileStorageIO.configure(loader, initArgs);
    doStorageTests(loader, fileStorageIO);
  }

  /**
   * Called from tests for each storage type to run creation and update tests
   * on a persisted managed resource.
   */
  @SuppressWarnings("unchecked")
  private void doStorageTests(SolrResourceLoader loader, StorageIO storageIO) throws Exception {
    String resourceId = "/test/foo";
    
    JsonStorage jsonStorage = new JsonStorage(storageIO, loader);
    
    Map<String,String> managedInitArgs = new HashMap<>();
    managedInitArgs.put("ignoreCase","true");
    managedInitArgs.put("dontIgnoreCase", "false");
    
    List<String> managedList = new ArrayList<>(); // we need a mutable List for this test
    managedList.addAll(Arrays.asList("a","b","c","d","e"));
    
    Map<String,Object> toStore = new HashMap<>();
    toStore.put(ManagedResource.INIT_ARGS_JSON_FIELD, managedInitArgs);
    toStore.put(ManagedResource.MANAGED_JSON_LIST_FIELD, managedList);
    
    jsonStorage.store(resourceId, toStore);
    
    String storedResourceId = jsonStorage.getStoredResourceId(resourceId);
    assertTrue(storedResourceId+" file not found!", storageIO.exists(storedResourceId));
    
    Object fromStorage = jsonStorage.load(resourceId);
    assertNotNull(fromStorage);    
    
    Map<String,Object> storedMap = (Map<String,Object>)fromStorage;
    Map<String,Object> storedArgs = (Map<String,Object>)storedMap.get(ManagedResource.INIT_ARGS_JSON_FIELD);
    assertNotNull(storedArgs);
    assertEquals("true", storedArgs.get("ignoreCase"));
    List<String> storedList = (List<String>)storedMap.get(ManagedResource.MANAGED_JSON_LIST_FIELD);
    assertNotNull(storedList);
    assertTrue(storedList.size() == managedList.size());
    assertTrue(storedList.contains("a"));    
    
    // now verify you can update existing data
    managedInitArgs.put("anotherArg", "someValue");
    managedList.add("f");
    jsonStorage.store(resourceId, toStore);    
    fromStorage = jsonStorage.load(resourceId);
    assertNotNull(fromStorage);    
    
    storedMap = (Map<String,Object>)fromStorage;
    storedArgs = (Map<String,Object>)storedMap.get(ManagedResource.INIT_ARGS_JSON_FIELD);
    assertNotNull(storedArgs);
    assertEquals("someValue", storedArgs.get("anotherArg"));
    storedList = (List<String>)storedMap.get(ManagedResource.MANAGED_JSON_LIST_FIELD);
    assertNotNull(storedList);
    assertTrue(storedList.size() == managedList.size());
    assertTrue(storedList.contains("e"));        
  }
}

@@ -1023,16 +1023,72 @@
 e.Slow;%0A
+import org.apache.lucene.util.LuceneTestCase.AwaitsFix;%0A
 import o
@@ -1128,16 +1128,16 @@
 stCase;%0A
-
 import o
@@ -1634,16 +1634,87 @@
 /%0A@Slow%0A
+@AwaitsFix(bugUrl = %22https://issues.apache.org/jira/browse/SOLR-6444%22)%0A
 public c
@@ -2050,20 +2050,16 @@
 ware());
-    
 %0A    Sol
@@ -2132,20 +2132,16 @@
 lient();
-    
 %0A    Sol
@@ -2599,24 +2599,22 @@
 %7B%0A      
-zkClient
+loader
 .close()
@@ -2924,24 +2924,36 @@
 utePath());%0A
+    try %7B%0A  
     NamedLis
@@ -2992,24 +2992,26 @@
 st%3C%3E();%0A    
+ 
+ 
 String manag
@@ -3082,16 +3082,18 @@
 d%22;%0A    
+  
 initArgs
@@ -3155,24 +3155,26 @@
 edDir);%0A    
+ 
+ 
 FileStorageI
@@ -3216,16 +3216,18 @@
 ();%0A    
+  
 fileStor
@@ -3261,24 +3261,26 @@
 tArgs);%0A    
+ 
+ 
 doStorageTes
@@ -3306,16 +3306,60 @@
 ageIO);%0A
+    %7D finally %7B%0A      loader.close();%0A    %7D%0A
   %7D%0A%0A  /

Disable test in 4x branch until the leaking cores can be resolved in trunk.