blob: 5f1f9fe32dfda4a39a1d23895a4da9e4c87eead6 [file] [log] [blame]
/*
* 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.
*/
package org.apache.solr.cloud;
import java.lang.invoke.MethodHandles;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.SolrTestUtil;
import org.apache.solr.common.cloud.SecurityAwareZkACLProvider;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OutOfBoxZkACLAndCredentialsProvidersTest extends SolrTestCaseJ4 {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final Charset DATA_ENCODING = Charset.forName("UTF-8");
protected ZkTestServer zkServer;
protected Path zkDir;
@BeforeClass
public static void beforeClass() {
// this ZooKeeper thread can be in its wait loop a short bit before stopping TODO: why is this test more prone to it? Seems to be ony in solrj module?
// I bet it's ZkSolrResourceLoader in XML Configuration causing an issue being accessed from solrj to core.
interruptThreadsOnTearDown(false, "SessionTracker");
System.setProperty("solrcloud.skip.autorecovery", "true");
}
@AfterClass
public static void afterClass() throws InterruptedException {
System.clearProperty("solrcloud.skip.autorecovery");
}
@Override
public void setUp() throws Exception {
super.setUp();
if (log.isInfoEnabled()) {
log.info("####SETUP_START {}", SolrTestUtil.getTestName());
}
SolrTestUtil.createTempDir();
zkDir = SolrTestUtil.createTempDir().resolve("zookeeper/server1/data");
log.info("ZooKeeper dataDir:{}", zkDir);
zkServer = new ZkTestServer(zkDir);
zkServer.run();
System.setProperty("zkHost", zkServer.getZkAddress());
SolrZkClient zkClient = zkServer.getZkClient();
zkClient.makePath("/solr", false, true);
zkClient = new SolrZkClient(zkServer.getZkAddress(), AbstractZkTestCase.TIMEOUT);
zkClient.start();
zkClient.create("/protectedCreateNode", "content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
zkClient.makePath("/protectedMakePathNode", "content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
zkClient.create("/unprotectedCreateNode", "content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
zkClient.makePath("/unprotectedMakePathNode", "content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
zkClient.create(SecurityAwareZkACLProvider.SECURITY_ZNODE_PATH, "content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
zkClient.close();
if (log.isInfoEnabled()) {
log.info("####SETUP_END {}", SolrTestUtil.getTestName());
}
}
@Override
public void tearDown() throws Exception {
zkServer.shutdown();
super.tearDown();
}
@Test
public void testOutOfBoxSolrZkClient() throws Exception {
SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), AbstractZkTestCase.TIMEOUT);
try {
zkClient.start();
VMParamsZkACLAndCredentialsProvidersTest.doTest(zkClient,
true, true, true, true, true,
true, true, true, true, true);
} finally {
zkClient.close();
}
}
@Test
public void testOpenACLUnsafeAllover() throws Exception {
SolrZkClient zkClient = new SolrZkClient(zkServer.getZkHost(), AbstractZkTestCase.TIMEOUT);
try {
zkClient.start();
List<String> verifiedList = new ArrayList<String>();
assertOpenACLUnsafeAllover(zkClient, "/", verifiedList);
assertTrue(verifiedList.contains("/solr"));
assertTrue(verifiedList.contains("/solr/unprotectedCreateNode"));
assertTrue(verifiedList.contains("/solr/unprotectedMakePathNode"));
assertTrue(verifiedList.contains("/solr/protectedMakePathNode"));
assertTrue(verifiedList.contains("/solr/protectedCreateNode"));
assertTrue(verifiedList.contains("/solr" + SecurityAwareZkACLProvider.SECURITY_ZNODE_PATH));
} finally {
zkClient.close();
}
}
protected void assertOpenACLUnsafeAllover(SolrZkClient zkClient, String path, List<String> verifiedList) throws Exception {
List<ACL> acls = zkClient.getConnectionManager().getKeeper().getACL(path, new Stat());
if (log.isInfoEnabled()) {
log.info("Verifying {}", path);
}
if (ZooDefs.CONFIG_NODE.equals(path)) {
// Treat this node specially, from the ZK docs:
// The dynamic configuration is stored in a special znode ZooDefs.CONFIG_NODE = /zookeeper/config.
// This node by default is read only for all users, except super user and
// users that's explicitly configured for write access.
assertEquals("Path " + path + " does not have READ_ACL_UNSAFE", ZooDefs.Ids.READ_ACL_UNSAFE, acls);
} else {
assertEquals("Path " + path + " does not have OPEN_ACL_UNSAFE", ZooDefs.Ids.OPEN_ACL_UNSAFE, acls);
}
verifiedList.add(path);
List<String> children = zkClient.getChildren(path, null, false);
for (String child : children) {
assertOpenACLUnsafeAllover(zkClient, path + ((path.endsWith("/")) ? "" : "/") + child, verifiedList);
}
}
}