org.apache.solr.common.cloud.TestZkConfigManager.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.solr.common.cloud.TestZkConfigManager.java

Source

/*
 * 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.common.cloud;

import com.google.common.base.Charsets;
import com.google.common.base.Throwables;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.cloud.ZkTestServer;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class TestZkConfigManager extends SolrTestCaseJ4 {

    private static ZkTestServer zkServer;

    @BeforeClass
    public static void startZkServer() throws InterruptedException {
        zkServer = new ZkTestServer(createTempDir("zkData").toString());
        zkServer.run();
    }

    @AfterClass
    public static void shutdownZkServer() throws IOException, InterruptedException {
        zkServer.shutdown();
    }

    @Test
    public void testUploadConfig() throws IOException {

        zkServer.ensurePathExists("/solr");

        try (SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress("/solr"), 10000)) {

            ZkConfigManager configManager = new ZkConfigManager(zkClient);
            assertEquals(0, configManager.listConfigs().size());

            byte[] testdata = "test data".getBytes(Charsets.UTF_8);

            Path tempConfig = createTempDir("config");
            Files.createFile(tempConfig.resolve("file1"));
            Files.write(tempConfig.resolve("file1"), testdata);
            Files.createFile(tempConfig.resolve("file2"));
            Files.createDirectory(tempConfig.resolve("subdir"));
            Files.createFile(tempConfig.resolve("subdir").resolve("file3"));
            Files.createFile(tempConfig.resolve(".ignored"));
            Files.createDirectory(tempConfig.resolve(".ignoreddir"));
            Files.createFile(tempConfig.resolve(".ignoreddir").resolve("ignored"));

            configManager.uploadConfigDir(tempConfig, "testconfig");

            // uploading a directory creates a new config
            List<String> configs = configManager.listConfigs();
            assertEquals(1, configs.size());
            assertEquals("testconfig", configs.get(0));

            // check downloading
            Path downloadPath = createTempDir("download");
            configManager.downloadConfigDir("testconfig", downloadPath);
            assertTrue(Files.exists(downloadPath.resolve("file1")));
            assertTrue(Files.exists(downloadPath.resolve("file2")));
            assertTrue(Files.isDirectory(downloadPath.resolve("subdir")));
            assertTrue(Files.exists(downloadPath.resolve("subdir/file3")));
            // dotfiles should be ignored
            assertFalse(Files.exists(downloadPath.resolve(".ignored")));
            assertFalse(Files.exists(downloadPath.resolve(".ignoreddir/ignored")));
            byte[] checkdata = Files.readAllBytes(downloadPath.resolve("file1"));
            assertArrayEquals(testdata, checkdata);

            // uploading to the same config overwrites
            byte[] overwritten = "new test data".getBytes(Charsets.UTF_8);
            Files.write(tempConfig.resolve("file1"), overwritten);
            configManager.uploadConfigDir(tempConfig, "testconfig");

            assertEquals(1, configManager.listConfigs().size());
            Path download2 = createTempDir("download2");
            configManager.downloadConfigDir("testconfig", download2);
            byte[] checkdata2 = Files.readAllBytes(download2.resolve("file1"));
            assertArrayEquals(overwritten, checkdata2);

            // uploading same files to a new name creates a new config
            configManager.uploadConfigDir(tempConfig, "config2");
            assertEquals(2, configManager.listConfigs().size());
        }
    }

    @Test
    public void testUploadWithACL() throws IOException {

        zkServer.ensurePathExists("/acl");

        final String readOnlyUsername = "readonly";
        final String readOnlyPassword = "readonly";
        final String writeableUsername = "writeable";
        final String writeablePassword = "writeable";

        ZkACLProvider aclProvider = new DefaultZkACLProvider() {
            @Override
            protected List<ACL> createGlobalACLsToAdd() {
                try {
                    List<ACL> result = new ArrayList<>();
                    result.add(new ACL(ZooDefs.Perms.ALL, new Id("digest", DigestAuthenticationProvider
                            .generateDigest(writeableUsername + ":" + writeablePassword))));
                    result.add(new ACL(ZooDefs.Perms.READ, new Id("digest", DigestAuthenticationProvider
                            .generateDigest(readOnlyUsername + ":" + readOnlyPassword))));
                    return result;
                } catch (NoSuchAlgorithmException e) {
                    throw new RuntimeException(e);
                }
            }
        };

        ZkCredentialsProvider readonly = new DefaultZkCredentialsProvider() {
            @Override
            protected Collection<ZkCredentials> createCredentials() {
                List<ZkCredentials> credentials = new ArrayList<>();
                credentials.add(new ZkCredentials("digest",
                        (readOnlyUsername + ":" + readOnlyPassword).getBytes(Charsets.UTF_8)));
                return credentials;
            }
        };

        ZkCredentialsProvider writeable = new DefaultZkCredentialsProvider() {
            @Override
            protected Collection<ZkCredentials> createCredentials() {
                List<ZkCredentials> credentials = new ArrayList<>();
                credentials.add(new ZkCredentials("digest",
                        (writeableUsername + ":" + writeablePassword).getBytes(Charsets.UTF_8)));
                return credentials;
            }
        };

        Path configPath = createTempDir("acl-config");
        Files.createFile(configPath.resolve("file1"));

        // Start with all-access client
        try (SolrZkClient client = buildZkClient(zkServer.getZkAddress("/acl"), aclProvider, writeable)) {
            ZkConfigManager configManager = new ZkConfigManager(client);
            configManager.uploadConfigDir(configPath, "acltest");
            assertEquals(1, configManager.listConfigs().size());
        }

        // Readonly access client can get the list of configs, but can't upload
        try (SolrZkClient client = buildZkClient(zkServer.getZkAddress("/acl"), aclProvider, readonly)) {
            ZkConfigManager configManager = new ZkConfigManager(client);
            assertEquals(1, configManager.listConfigs().size());
            configManager.uploadConfigDir(configPath, "acltest2");
            fail("Should have thrown an ACL exception");
        } catch (IOException e) {
            assertEquals(KeeperException.NoAuthException.class, Throwables.getRootCause(e).getClass());
        }

        // Client with no auth whatsoever can't even get the list of configs
        try (SolrZkClient client = new SolrZkClient(zkServer.getZkAddress("/acl"), 10000)) {
            ZkConfigManager configManager = new ZkConfigManager(client);
            configManager.listConfigs();
            fail("Should have thrown an ACL exception");
        } catch (IOException e) {
            assertEquals(KeeperException.NoAuthException.class, Throwables.getRootCause(e).getClass());
        }

    }

    static SolrZkClient buildZkClient(String zkAddress, final ZkACLProvider aclProvider,
            final ZkCredentialsProvider credentialsProvider) {
        return new SolrZkClient(zkAddress, 10000) {
            @Override
            protected ZkCredentialsProvider createZkCredentialsToAddAutomatically() {
                return credentialsProvider;
            }

            @Override
            protected ZkACLProvider createZkACLProvider() {
                return aclProvider;
            }
        };
    }

}