| /** |
| * 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.server.appmaster.web.rest.management; |
| |
| import com.google.inject.Guice; |
| import com.google.inject.Inject; |
| import com.google.inject.Injector; |
| import com.google.inject.servlet.GuiceServletContextListener; |
| import com.google.inject.servlet.ServletModule; |
| import com.sun.jersey.api.client.ClientResponse; |
| import com.sun.jersey.api.client.WebResource; |
| import com.sun.jersey.api.client.config.DefaultClientConfig; |
| import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; |
| import com.sun.jersey.test.framework.JerseyTest; |
| import com.sun.jersey.test.framework.WebAppDescriptor; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.fs.FileSystem; |
| import org.apache.hadoop.yarn.conf.YarnConfiguration; |
| import org.apache.hadoop.yarn.webapp.GenericExceptionHandler; |
| import org.apache.slider.common.tools.SliderUtils; |
| import org.apache.slider.core.conf.AggregateConf; |
| import org.apache.slider.core.conf.ConfTree; |
| import org.apache.slider.core.exceptions.BadClusterStateException; |
| import org.apache.slider.core.exceptions.BadConfigException; |
| import org.apache.slider.core.persist.JsonSerDeser; |
| import org.apache.slider.server.appmaster.management.MetricsAndMonitoring; |
| import org.apache.slider.server.appmaster.model.mock.MockFactory; |
| import org.apache.slider.server.appmaster.model.mock.MockProviderService; |
| import org.apache.slider.server.appmaster.model.mock.MockRecordFactory; |
| import org.apache.slider.server.appmaster.model.mock.MockSliderClusterProtocol; |
| import org.apache.slider.server.appmaster.state.AppState; |
| import org.apache.slider.server.appmaster.state.ProviderAppState; |
| import org.apache.slider.server.appmaster.state.SimpleReleaseSelector; |
| import org.apache.slider.server.appmaster.web.WebAppApi; |
| import org.apache.slider.server.appmaster.web.WebAppApiImpl; |
| import org.apache.slider.server.appmaster.web.rest.AMWebServices; |
| import org.apache.slider.server.appmaster.web.rest.SliderJacksonJaxbJsonProvider; |
| import org.apache.slider.server.appmaster.web.rest.management.resources.AggregateConfResource; |
| import org.apache.slider.server.appmaster.web.rest.management.resources.ConfTreeResource; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import javax.ws.rs.Path; |
| import javax.ws.rs.core.MediaType; |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.util.Map; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.fail; |
| |
| public class TestAMManagementWebServices extends JerseyTest { |
| protected static final Logger log = |
| LoggerFactory.getLogger(TestAMManagementWebServices.class); |
| public static final int RM_MAX_RAM = 4096; |
| public static final int RM_MAX_CORES = 64; |
| public static final String EXAMPLES = |
| "/org/apache/slider/core/conf/examples/"; |
| static MockFactory factory = new MockFactory(); |
| private static Configuration conf = new Configuration(); |
| private static WebAppApi slider; |
| |
| private static Injector injector = createInjector(); |
| private static FileSystem fs; |
| |
| public static class GuiceServletConfig extends GuiceServletContextListener { |
| |
| public GuiceServletConfig() { |
| super(); |
| } |
| |
| @Override |
| protected Injector getInjector() { |
| return injector; |
| } |
| } |
| |
| @Path("/ws/v1/slider") |
| public static class MockSliderAMWebServices extends AMWebServices { |
| |
| @Inject |
| public MockSliderAMWebServices(WebAppApi slider) { |
| super(slider); |
| } |
| |
| @Override |
| public ManagementResource getManagementResource() { |
| return new MockManagementResource(slider); |
| } |
| |
| } |
| |
| public static class MockManagementResource extends ManagementResource { |
| public MockManagementResource(WebAppApi slider) { |
| super(slider); |
| } |
| |
| protected AggregateConf getAggregateConf() { |
| JsonSerDeser<ConfTree> confTreeJsonSerDeser = |
| new JsonSerDeser<ConfTree>(ConfTree.class); |
| ConfTree internal = null; |
| ConfTree app_conf = null; |
| ConfTree resources = null; |
| try { |
| internal = |
| confTreeJsonSerDeser.fromResource( |
| EXAMPLES +"internal.json"); |
| app_conf = |
| confTreeJsonSerDeser.fromResource( |
| EXAMPLES + "app_configuration.json"); |
| resources = |
| confTreeJsonSerDeser.fromResource( |
| EXAMPLES + "resources.json"); |
| } catch (IOException e) { |
| fail(e.getMessage()); |
| } |
| AggregateConf aggregateConf = new AggregateConf( |
| resources, |
| app_conf, |
| internal); |
| aggregateConf.setName("test"); |
| return aggregateConf; |
| } |
| |
| } |
| @Before |
| @Override |
| public void setUp() throws Exception { |
| super.setUp(); |
| injector = createInjector(); |
| YarnConfiguration conf = SliderUtils.createConfiguration(); |
| fs = FileSystem.get(new URI("file:///"), conf); |
| } |
| |
| private static Injector createInjector() { |
| return Guice.createInjector(new ServletModule() { |
| @Override |
| protected void configureServlets() { |
| |
| AppState appState = null; |
| try { |
| fs = FileSystem.get(new URI("file:///"), conf); |
| File |
| historyWorkDir = |
| new File("target/history", "TestAMManagementWebServices"); |
| org.apache.hadoop.fs.Path |
| historyPath = |
| new org.apache.hadoop.fs.Path(historyWorkDir.toURI()); |
| fs.delete(historyPath, true); |
| appState = new AppState(new MockRecordFactory(), new MetricsAndMonitoring()); |
| appState.setContainerLimits(RM_MAX_RAM, RM_MAX_CORES); |
| appState.buildInstance( |
| factory.newInstanceDefinition(0, 0, 0), |
| new Configuration(), |
| new Configuration(false), |
| factory.ROLES, |
| fs, |
| historyPath, |
| null, null, new SimpleReleaseSelector()); |
| // JDK7 } catch (IOException | BadClusterStateException | URISyntaxException | BadConfigException e) { |
| } catch (IOException e) { |
| log.error("{}", e, e); |
| } catch (BadClusterStateException e) { |
| log.error("{}", e, e); |
| } catch (URISyntaxException e) { |
| log.error("{}", e, e); |
| } catch (BadConfigException e) { |
| log.error("{}", e, e); |
| } |
| ProviderAppState providerAppState = new ProviderAppState("undefined", |
| appState); |
| |
| slider = new WebAppApiImpl(new MockSliderClusterProtocol(), providerAppState, |
| new MockProviderService(), null, null, null); |
| |
| bind(SliderJacksonJaxbJsonProvider.class); |
| bind(MockSliderAMWebServices.class); |
| bind(GenericExceptionHandler.class); |
| bind(WebAppApi.class).toInstance(slider); |
| bind(Configuration.class).toInstance(conf); |
| |
| serve("/*").with(GuiceContainer.class); |
| } |
| }); |
| } |
| |
| public TestAMManagementWebServices() { |
| super(new WebAppDescriptor.Builder( |
| "org.apache.hadoop.yarn.appmaster.web") |
| .contextListenerClass(GuiceServletConfig.class) |
| .filterClass(com.google.inject.servlet.GuiceFilter.class) |
| .contextPath("slideram").servletPath("/") |
| .clientConfig( |
| new DefaultClientConfig(SliderJacksonJaxbJsonProvider.class)) |
| .build()); |
| } |
| |
| @Test |
| public void testAppResource() throws Exception { |
| WebResource r = resource(); |
| ClientResponse response = r.path("ws").path("v1").path("slider").path("mgmt").path("app") |
| .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); |
| assertEquals(200, response.getStatus()); |
| assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); |
| AggregateConfResource json = response.getEntity(AggregateConfResource.class); |
| assertEquals("wrong href", |
| "http://localhost:9998/slideram/ws/v1/slider/mgmt/app", |
| json.getHref()); |
| assertNotNull("no resources", json.getResources()); |
| assertNotNull("no internal", json.getInternal()); |
| assertNotNull("no appConf", json.getAppConf()); |
| } |
| |
| @Test |
| public void testAppInternal() throws Exception { |
| WebResource r = resource(); |
| ClientResponse |
| response = |
| r.path("ws").path("v1").path("slider").path("mgmt").path("app").path("configurations").path( |
| "internal") |
| .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); |
| assertEquals(200, response.getStatus()); |
| assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); |
| ConfTreeResource json = response.getEntity(ConfTreeResource.class); |
| assertEquals("wrong href", |
| "http://localhost:9998/slideram/ws/v1/slider/mgmt/app/configurations/internal", |
| json.getHref()); |
| assertEquals("wrong description", |
| "Internal configuration DO NOT EDIT", |
| json.getMetadata().get("description")); |
| } |
| |
| @Test |
| public void testAppResources() throws Exception { |
| WebResource r = resource(); |
| ClientResponse |
| response = |
| r.path("ws").path("v1").path("slider").path("mgmt").path("app").path("configurations").path( |
| "resources") |
| .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); |
| |
| assertEquals(200, response.getStatus()); |
| assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); |
| ConfTreeResource json = response.getEntity(ConfTreeResource.class); |
| assertEquals("wrong href", |
| "http://localhost:9998/slideram/ws/v1/slider/mgmt/app/configurations/resources", |
| json.getHref()); |
| Map<String,Map<String, String>> components = json.getComponents(); |
| assertNotNull("no components", components); |
| assertEquals("incorrect number of components", 2, components.size()); |
| assertNotNull("wrong component", components.get("worker")); |
| } |
| |
| @Test |
| public void testAppAppConf() throws Exception { |
| WebResource r = resource(); |
| ClientResponse |
| response = |
| r.path("ws").path("v1").path("slider").path("mgmt").path("app").path("configurations").path( |
| "appConf") |
| .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); |
| assertEquals(200, response.getStatus()); |
| assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); |
| ConfTreeResource json = response.getEntity(ConfTreeResource.class); |
| assertEquals("wrong href", |
| "http://localhost:9998/slideram/ws/v1/slider/mgmt/app/configurations/appConf", |
| json.getHref()); |
| Map<String,Map<String, String>> components = json.getComponents(); |
| assertNotNull("no components", components); |
| assertEquals("incorrect number of components", 2, components.size()); |
| assertNotNull("wrong component", components.get("worker")); |
| } |
| } |