/*
* 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.flink.runtime.webmonitor.history;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.testkit.TestActorRef;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.IOUtils;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.configuration.HistoryServerOptions;
import org.apache.flink.configuration.JobManagerOptions;
import org.apache.flink.core.fs.Path;
import org.apache.flink.runtime.akka.AkkaUtils;
import org.apache.flink.runtime.executiongraph.ArchivedExecutionGraph;
import org.apache.flink.runtime.jobmanager.JobManager;
import org.apache.flink.runtime.jobmanager.MemoryArchivist;
import org.apache.flink.runtime.messages.ArchiveMessages;
import org.apache.flink.runtime.webmonitor.utils.ArchivedJobGenerationUtils;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import scala.Option;
public class HistoryServerTest {
@Rule
public TemporaryFolder tmpDir = new TemporaryFolder();
@Test
public void testFullArchiveLifecycle() throws Exception {
ArchivedExecutionGraph graph = (ArchivedExecutionGraph) ArchivedJobGenerationUtils.getTestJob();
File jmDirectory = tmpDir.newFolder("jm");
File hsDirectory = tmpDir.newFolder("hs");
Configuration config = new Configuration();
config.setString(JobManagerOptions.ARCHIVE_DIR, jmDirectory.toURI().toString());
config.setString(HistoryServerOptions.HISTORY_SERVER_ARCHIVE_DIRS, jmDirectory.toURI().toString());
config.setString(HistoryServerOptions.HISTORY_SERVER_WEB_DIR, hsDirectory.getAbsolutePath());
config.setInteger(HistoryServerOptions.HISTORY_SERVER_WEB_PORT, 0);
ActorSystem actorSystem = AkkaUtils.createLocalActorSystem(config);
Option<Path> archivePath = Option.apply(new Path(jmDirectory.toURI().toString()));
ActorRef memoryArchivist = TestActorRef.apply(JobManager.getArchiveProps(MemoryArchivist.class, 1, archivePath), actorSystem);
memoryArchivist.tell(new ArchiveMessages.ArchiveExecutionGraph(graph.getJobID(), graph), null);
File archive = new File(jmDirectory, graph.getJobID().toString());
Assert.assertTrue(archive.exists());
CountDownLatch numFinishedPolls = new CountDownLatch(1);
HistoryServer hs = new HistoryServer(config, numFinishedPolls);
try {
hs.start();
String baseUrl = "http://localhost:" + hs.getWebPort();
numFinishedPolls.await(10L, TimeUnit.SECONDS);
ObjectMapper mapper = new ObjectMapper();
String response = getFromHTTP(baseUrl + "/joboverview");
JsonNode overview = mapper.readTree(response);
String jobID = overview.get("finished").get(0).get("jid").asText();
JsonNode jobDetails = mapper.readTree(getFromHTTP(baseUrl + "/jobs/" + jobID));
Assert.assertNotNull(jobDetails.get("jid"));
} finally {
hs.stop();
}
}
public static String getFromHTTP(String url) throws Exception {
URL u = new URL(url);
HttpURLConnection connection = (HttpURLConnection) u.openConnection();
connection.setConnectTimeout(100000);
connection.connect();
InputStream is;
if (connection.getResponseCode() >= 400) {
// error!
is = connection.getErrorStream();
} else {
is = connection.getInputStream();
}
return IOUtils.toString(is, connection.getContentEncoding() != null ? connection.getContentEncoding() : "UTF-8");
}
}