| /* |
| * 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.slider.funtest.accumulo |
| |
| import groovy.util.logging.Slf4j |
| import org.apache.accumulo.core.conf.Property |
| import org.apache.hadoop.conf.Configuration |
| import org.apache.hadoop.fs.FileSystem |
| import org.apache.hadoop.fs.Path |
| import org.apache.hadoop.security.ProviderUtils |
| import org.apache.hadoop.security.UserGroupInformation |
| import org.apache.hadoop.security.alias.CredentialProvider |
| import org.apache.hadoop.security.alias.CredentialProviderFactory |
| import org.apache.hadoop.registry.client.types.ServiceRecord |
| import org.apache.slider.api.ClusterDescription |
| import org.apache.slider.client.SliderClient |
| import org.apache.slider.common.SliderKeys |
| import org.apache.slider.core.conf.ConfTree |
| import org.apache.slider.core.persist.ConfTreeSerDeser |
| import org.apache.slider.core.registry.docstore.PublishedConfiguration |
| import org.apache.slider.core.registry.retrieve.RegistryRetriever |
| import org.apache.slider.funtest.framework.SliderShell |
| |
| import org.junit.Before |
| import org.junit.Test |
| |
| import java.util.regex.Pattern |
| |
| import static org.apache.hadoop.registry.client.binding.RegistryUtils.currentUser |
| import static org.apache.hadoop.registry.client.binding.RegistryUtils.servicePath |
| |
| @Slf4j |
| class AccumuloBasicIT extends AccumuloAgentCommandTestBase { |
| protected static final String PROVIDER_PROPERTY = "site.accumulo-site." + |
| Property.GENERAL_SECURITY_CREDENTIAL_PROVIDER_PATHS |
| protected static final String KEY_PASS = "keypass" |
| protected static final String TRUST_PASS = "trustpass" |
| protected ConfTree tree |
| |
| protected String getAppResource() { |
| return sysprop("test.app.resources.dir") + "/resources.json" |
| } |
| |
| protected String getDefaultTemplate() { |
| return sysprop("test.app.resources.dir") + "/appConfig-default.json" |
| } |
| |
| protected String getAppTemplate() { |
| String appTemplateFile = templateName() |
| Configuration conf = new Configuration() |
| FileSystem fs = FileSystem.getLocal(conf) |
| InputStream stream = new FileInputStream(getDefaultTemplate()) |
| assert stream!=null, "Couldn't pull appConfig.json from app pkg" |
| ConfTreeSerDeser c = new ConfTreeSerDeser() |
| ConfTree t = c.fromStream(stream) |
| t = modifyTemplate(t) |
| c.save(fs, new Path(appTemplateFile), t, true) |
| return appTemplateFile |
| } |
| |
| protected String templateName() { |
| return sysprop("test.app.resources.dir") + "/appConfig.json" |
| } |
| |
| protected ConfTree modifyTemplate(ConfTree original) { |
| return original |
| } |
| |
| @Before |
| public void createKeyStore() { |
| ConfTreeSerDeser c = new ConfTreeSerDeser() |
| tree = c.fromFile(new File(APP_TEMPLATE)) |
| assume tree.credentials.size() > 0, "No credentials requested, " + |
| "skipping creation of credentials" |
| SliderClient.replaceTokens(tree, UserGroupInformation.getCurrentUser() |
| .getShortUserName(), getClusterName()) |
| String jks = tree.global.get(PROVIDER_PROPERTY) |
| def keys = tree.credentials.get(jks) |
| assert keys!=null, "jks specified in $PROVIDER_PROPERTY wasn't requested " + |
| "in credentials" |
| jks = jks.replaceAll(Pattern.quote('${CLUSTER_NAME}'), clusterName) |
| Path jksPath = ProviderUtils.unnestUri(new URI(jks)) |
| if (clusterFS.exists(jksPath)) { |
| clusterFS.delete(jksPath, false) |
| } |
| Configuration conf = loadSliderConf() |
| conf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, jks) |
| CredentialProvider provider = |
| CredentialProviderFactory.getProviders(conf).get(0) |
| // root initial password and trace password will be initialized at runtime |
| provider.createCredentialEntry(Property.INSTANCE_SECRET.toString(), |
| INSTANCE_SECRET.toCharArray()) |
| provider.createCredentialEntry(Property.RPC_SSL_KEYSTORE_PASSWORD |
| .toString(), KEY_PASS.toCharArray()) |
| provider.createCredentialEntry(Property.RPC_SSL_TRUSTSTORE_PASSWORD |
| .toString(), TRUST_PASS.toCharArray()) |
| provider.createCredentialEntry(Property.MONITOR_SSL_KEYSTOREPASS |
| .toString(), KEY_PASS.toCharArray()) |
| provider.createCredentialEntry(Property.MONITOR_SSL_TRUSTSTOREPASS |
| .toString(), TRUST_PASS.toCharArray()) |
| provider.flush() |
| assert clusterFS.exists(jksPath), "jks $jks not created" |
| log.info("Created credential provider $jks for test") |
| } |
| |
| @Override |
| public String getClusterName() { |
| return "test_accumulo_basic" |
| } |
| |
| protected Map<String, Integer> getRoleMap() { |
| // must match the values in src/test/resources/resources.json |
| return [ |
| "ACCUMULO_MASTER" : 1, |
| "ACCUMULO_TSERVER" : 2, |
| "ACCUMULO_MONITOR": 1, |
| "ACCUMULO_GC": 0, |
| "ACCUMULO_TRACER" : 0, |
| "ACCUMULO_PROXY" : 0 |
| ]; |
| } |
| |
| @Test |
| public void testAccumuloClusterCreate() throws Throwable { |
| |
| describe getDescription() |
| |
| def path = buildClusterPath(getClusterName()) |
| assert !clusterFS.exists(path) |
| |
| SliderShell shell = createTemplatedSliderApplication(getClusterName(), |
| APP_TEMPLATE, APP_RESOURCE, |
| ["<", sysprop("test.app.resources.dir") + "/test_password_file"]) |
| |
| logShell(shell) |
| |
| ensureApplicationIsUp(getClusterName()) |
| |
| //get a slider client against the cluster |
| SliderClient sliderClient = bondToCluster(SLIDER_CONFIG, getClusterName()) |
| ClusterDescription cd = sliderClient.clusterDescription |
| assert getClusterName() == cd.name |
| |
| log.info("Connected via Client {}", sliderClient.toString()) |
| |
| //wait for the role counts to be reached |
| waitForRoleCount(sliderClient, getRoleMap(), ACCUMULO_LAUNCH_WAIT_TIME) |
| |
| sleep(ACCUMULO_GO_LIVE_TIME) |
| |
| clusterLoadOperations(cd, sliderClient) |
| } |
| |
| |
| public String getDescription() { |
| return "Create a working Accumulo cluster $clusterName" |
| } |
| |
| public static PublishedConfiguration getExport(SliderClient sliderClient, |
| String clusterName, |
| String exportName) { |
| String path = servicePath(currentUser(), |
| SliderKeys.APP_TYPE, |
| clusterName); |
| ServiceRecord instance = sliderClient.resolve(path) |
| RegistryRetriever retriever = new RegistryRetriever( |
| sliderClient.config, |
| instance) |
| PublishedConfiguration configuration = retriever.retrieveConfiguration( |
| retriever.getConfigurations(true), exportName, true) |
| return configuration |
| } |
| |
| public static String getMonitorUrl(SliderClient sliderClient, String clusterName) { |
| int tries = 5 |
| Exception caught; |
| while (true) { |
| try { |
| PublishedConfiguration configuration = getExport(sliderClient, |
| clusterName, "quicklinks") |
| |
| // must match name set in metainfo.xml |
| String monitorUrl = configuration.entries.get("org.apache.slider.monitor") |
| assertNotNull monitorUrl |
| return monitorUrl |
| } catch (Exception e) { |
| caught = e; |
| log.info("Got exception trying to read quicklinks") |
| if (tries-- == 0) { |
| break |
| } |
| sleep(20000) |
| } |
| } |
| throw caught; |
| } |
| |
| public static void checkMonitorPage(String monitorUrl) { |
| String monitor = fetchWebPageRaisedErrorCodes(monitorUrl); |
| assert monitor != null, "Monitor page null" |
| assert monitor.length() > 100, "Monitor page too short" |
| assert monitor.contains("Accumulo Overview"), "Monitor page didn't contain expected text" |
| } |
| |
| /** |
| * Override point for any cluster load operations |
| */ |
| public void clusterLoadOperations(ClusterDescription cd, SliderClient sliderClient) { |
| String monitorUrl = getMonitorUrl(sliderClient, getClusterName()) |
| assert monitorUrl.startsWith("http://"), "Monitor URL didn't have expected protocol" |
| checkMonitorPage(monitorUrl) |
| } |
| } |