blob: 369c96f9342785d96f3a7e6914b78d4760459037 [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.slider.funtest.tomcat
import groovy.util.logging.Slf4j
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.FileSystem
import org.apache.hadoop.fs.FileUtil
import org.apache.hadoop.fs.FileStatus
import org.apache.hadoop.fs.Path
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.apache.slider.providers.agent.AgentKeys
import org.junit.Before
import org.junit.Test
import static org.apache.hadoop.registry.client.binding.RegistryUtils.currentUser
import static org.apache.hadoop.registry.client.binding.RegistryUtils.servicePath
@Slf4j
class TomcatBasicIT extends TomcatAgentCommandTestBase {
protected ConfTree tree
protected String getAppResource() {
return sysprop("test.app.resources.dir") + "/resources.json"
}
protected String templateName() {
return sysprop("test.app.resources.dir") + "/appConfig.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)
log.info("Writing new template to {}", appTemplateFile)
c.save(fs, new Path(appTemplateFile), t, true)
return appTemplateFile
}
protected ConfTree modifyTemplate(ConfTree original) {
// Set our custom WAR file in the appConfig and load it to the "cluster" filesystem
Configuration conf = new Configuration()
FileSystem fs = FileSystem.getLocal(conf)
// The path from the local filesystem of the war (copied to target/test-classes from src/test/resources)
Path sourcePath = fs.makeQualified(new Path(sysprop("project.build.directory"), "slider-test.war"))
// Path in HDFS we'll put the WAR
Path targetPath = clusterFS.makeQualified(new Path("/tmp/slider-test.war"))
if (clusterFS.exists(targetPath)) {
log.info("Deleting {}", targetPath)
clusterFS.delete(targetPath, true)
}
log.info("Copying {} on {} to {} on {}", sourcePath, fs, targetPath, clusterFS)
// Copy the file
FileUtil.copy(fs, sourcePath, clusterFS, targetPath, false, true, clusterFS.getConf())
FileStatus fileStatus = clusterFS.getFileStatus(targetPath)
FileStatus origFileStatus = fs.getFileStatus(sourcePath)
assert origFileStatus.getLen() == fileStatus.getLen(), "Expected file length to be the same in both source and destination"
log.info("Setting {} to {} in appConfig.json", AgentKeys.APP_RESOURCES, targetPath.toString())
// Set that path in the appConfig
original.global.put(AgentKeys.APP_RESOURCES, targetPath.toString())
return original
}
@Override
public String getClusterName() {
return "test_tomcat_basic"
}
protected Map<String, Integer> getRoleMap() {
// must match the values in src/test/resources/resources.json
return [
"TOMCAT" : 1
];
}
@Test
public void testTomcatClusterCreate() throws Throwable {
describe getDescription()
def path = buildClusterPath(getClusterName())
assert !clusterFS.exists(path)
SliderShell shell = createTemplatedSliderApplication(getClusterName(),
APP_TEMPLATE, APP_RESOURCE, [])
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, containers to get launched
waitForRoleCount(sliderClient, getRoleMap(), TOMCAT_LAUNCH_WAIT_TIME)
// Wait for Tomcat itself to boot
sleep(TOMCAT_LAUNCH_WAIT_TIME);
clusterLoadOperations(cd, sliderClient)
}
public String getDescription() {
return "Create a working Tomcat 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
}
/**
* Override point for any cluster load operations
*/
public void clusterLoadOperations(ClusterDescription cd, SliderClient sliderClient) {
String httpAddress = getHttpAddress(sliderClient, getClusterName())
assert httpAddress.startsWith("http://"), "Tomcat HTTP URL didn't have expected protocol"
checkHttpAddress(httpAddress)
}
/**
* Attempt to fetch the published Tomcat webserver address from the quicklinks.
*/
public static String getHttpAddress(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 httpAddress = configuration.entries.get("HTTP")
assertNotNull httpAddress
log.info("Got exported server address: '{}'", httpAddress)
return httpAddress
} catch (Exception e) {
caught = e;
log.info("Got exception trying to read quicklinks", e)
if (tries-- == 0) {
break
}
sleep(20000)
}
}
throw caught;
}
/**
* Validate the URL for the Tomcat server, checking deployed web content.
*/
public static void checkHttpAddress(String serverAddress) {
// Check the Tomcat manager webapp
String page = fetchWebPageRaisedErrorCodes(serverAddress);
assert page != null, "Tomcat manager page null"
assert page.length() > 100, "Tomcat manager page too short"
assert page.contains("Apache Tomcat"), "Tomcat monitor page didn't contain expected text"
// Check our test war we deployed too
page = fetchWebPageRaisedErrorCodes(serverAddress + '/slider-test');
assert page != null, "Could not fetch auto-deployed webapp"
// The custom war file will return a plain-text response of "Success" for "/"
assert page == "Success", "Did not find the expected content produced by the webapp"
}
}