Repository: ambari Updated Branches: refs/heads/trunk d429b30a3 -> a9ca4747f
AMBARI-5803. Implement Slider Apps View status endpoint. (srimanth) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a9ca4747 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a9ca4747 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a9ca4747 Branch: refs/heads/trunk Commit: a9ca4747fbb6579060371a41c2481edd8f3aca3c Parents: d429b30 Author: Srimanth Gunturi <[email protected]> Authored: Mon May 19 01:45:53 2014 -0700 Committer: Srimanth Gunturi <[email protected]> Committed: Mon May 19 09:22:59 2014 -0700 ---------------------------------------------------------------------- contrib/views/slider/pom.xml | 7 + .../apache/ambari/view/slider/SliderApp.java | 40 +++++ .../view/slider/SliderAppsConfiguration.java | 51 ++++++ .../view/slider/SliderAppsResourceProvider.java | 75 ++++++++ .../view/slider/SliderAppsViewController.java | 33 ++++ .../slider/SliderAppsViewControllerImpl.java | 141 +++++++++++++++ .../apache/ambari/view/slider/ViewStatus.java | 51 ++++++ .../view/slider/rest/SliderAppsResource.java | 30 ++++ .../view/slider/rest/ViewStatusResource.java | 40 +++++ .../view/slider/rest/client/AmbariCluster.java | 52 ++++++ .../slider/rest/client/AmbariClusterInfo.java | 40 +++++ .../slider/rest/client/AmbariHttpClient.java | 176 +++++++++++++++++++ .../view/slider/rest/client/AmbariService.java | 42 +++++ .../view/slider/rest/client/BaseHttpClient.java | 116 ++++++++++++ .../slider/src/main/resources/slider.properties | 19 ++ .../views/slider/src/main/resources/view.xml | 12 ++ 16 files changed, 925 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/pom.xml ---------------------------------------------------------------------- diff --git a/contrib/views/slider/pom.xml b/contrib/views/slider/pom.xml index 74a0d47..477669f 100644 --- a/contrib/views/slider/pom.xml +++ b/contrib/views/slider/pom.xml @@ -221,6 +221,13 @@ </plugins> <resources> <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + <includes> + <include>slider.properties</include> + </includes> + </resource> + <resource> <directory>src/main/resources/</directory> <filtering>false</filtering> <includes> http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderApp.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderApp.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderApp.java new file mode 100644 index 0000000..a1d4d53 --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderApp.java @@ -0,0 +1,40 @@ +/** + * 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.ambari.view.slider; + +public class SliderApp { + private String id; + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsConfiguration.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsConfiguration.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsConfiguration.java new file mode 100644 index 0000000..05c7687 --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsConfiguration.java @@ -0,0 +1,51 @@ +/** + * 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.ambari.view.slider; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.log4j.Logger; + +public class SliderAppsConfiguration { + + public static final SliderAppsConfiguration INSTANCE = new SliderAppsConfiguration(); + private static final Logger logger = Logger + .getLogger(SliderAppsConfiguration.class); + private static final String SLIDER_APPS_PROPERTIES_FILE = "/slider.properties"; + private PropertiesConfiguration propertiesConfig = null; + + private PropertiesConfiguration getConfiguration() + throws ConfigurationException { + if (propertiesConfig == null) { + propertiesConfig = new PropertiesConfiguration(); + propertiesConfig.load(getClass().getResourceAsStream( + SLIDER_APPS_PROPERTIES_FILE)); + } + return propertiesConfig; + } + + public String getVersion() { + try { + return getConfiguration().getString("slider.view.version"); + } catch (ConfigurationException e) { + logger.warn("Unable to get version configuration", e); + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsResourceProvider.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsResourceProvider.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsResourceProvider.java new file mode 100644 index 0000000..7024104 --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsResourceProvider.java @@ -0,0 +1,75 @@ +/** + * 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.ambari.view.slider; + +import java.util.Map; +import java.util.Set; + +import org.apache.ambari.view.NoSuchResourceException; +import org.apache.ambari.view.ReadRequest; +import org.apache.ambari.view.ResourceAlreadyExistsException; +import org.apache.ambari.view.ResourceProvider; +import org.apache.ambari.view.SystemException; +import org.apache.ambari.view.UnsupportedPropertyException; + +import com.google.inject.Inject; + +public class SliderAppsResourceProvider implements ResourceProvider<SliderApp> { + + @Inject + SliderAppsViewController sliderController; + + @Override + public void createResource(String resourceId, Map<String, Object> properties) + throws SystemException, ResourceAlreadyExistsException, + NoSuchResourceException, UnsupportedPropertyException { + // TODO Auto-generated method stub + } + + @Override + public boolean deleteResource(String resourceId) throws SystemException, + NoSuchResourceException, UnsupportedPropertyException { + // TODO Auto-generated method stub + return false; + } + + @Override + public SliderApp getResource(String resourceId, Set<String> properties) + throws SystemException, NoSuchResourceException, + UnsupportedPropertyException { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set<SliderApp> getResources(ReadRequest request) throws SystemException, + NoSuchResourceException, UnsupportedPropertyException { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean updateResource(String resourceId, Map<String, Object> properties) + throws SystemException, NoSuchResourceException, + UnsupportedPropertyException { + // TODO Auto-generated method stub + return false; + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java new file mode 100644 index 0000000..309617e --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java @@ -0,0 +1,33 @@ +/** + * 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.ambari.view.slider; + +import java.util.List; + +import com.google.inject.ImplementedBy; + +@ImplementedBy(SliderAppsViewControllerImpl.class) +public interface SliderAppsViewController { + + public ViewStatus getViewStatus(); + + public SliderApp getSliderApp(String applicationId); + + public List<SliderApp> getSliderApps(); +} http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java new file mode 100644 index 0000000..57275fc --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java @@ -0,0 +1,141 @@ +/** + * 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.ambari.view.slider; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.ambari.view.ViewContext; +import org.apache.ambari.view.slider.rest.client.AmbariCluster; +import org.apache.ambari.view.slider.rest.client.AmbariClusterInfo; +import org.apache.ambari.view.slider.rest.client.AmbariHttpClient; +import org.apache.ambari.view.slider.rest.client.AmbariService; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +@Singleton +public class SliderAppsViewControllerImpl implements SliderAppsViewController { + + @Inject + private ViewContext viewContext; + private AmbariHttpClient ambariClient; + + private AmbariHttpClient getAmbariClient() { + // TODO Calculate Ambari location dynamically + if (ambariClient == null) + ambariClient = new AmbariHttpClient("http://localhost:8080", + viewContext.getUsername(), "admin"); + return ambariClient; + } + + @Override + public ViewStatus getViewStatus() { + ViewStatus status = new ViewStatus(); + List<String> viewErrors = new ArrayList<String>(); + + AmbariHttpClient client = getAmbariClient(); + AmbariClusterInfo clusterInfo = client.getClusterInfo(); + if (clusterInfo != null) { + AmbariCluster cluster = client.getCluster(clusterInfo); + List<String> services = cluster.getServices(); + if (services != null && services.size() > 0) { + boolean zkFound = services.indexOf("ZOOKEEPER") > -1; + boolean hdfsFound = services.indexOf("HDFS") > -1; + boolean yarnFound = services.indexOf("YARN") > -1; + if (!hdfsFound) { + viewErrors.add("Slider applications view requires HDFS service"); + } else { + AmbariService service = client.getService(clusterInfo, "HDFS"); + if (service != null) { + if (!service.isStarted()) { + viewErrors + .add("Slider applications view requires HDFS service to be started"); + } + } + } + if (!yarnFound) { + viewErrors.add("Slider applications view requires YARN service"); + } else { + AmbariService service = client.getService(clusterInfo, "YARN"); + if (service != null) { + if (!service.isStarted()) { + viewErrors + .add("Slider applications view requires YARN service to be started"); + } + } + } + if (!zkFound) { + viewErrors.add("Slider applications view requires ZooKeeper service"); + } else { + AmbariService service = client.getService(clusterInfo, "ZOOKEEPER"); + if (service != null) { + if (!service.isStarted()) { + viewErrors + .add("Slider applications view requires ZooKeeper service to be started"); + } + } + } + } else { + viewErrors + .add("Slider applications view is unable to locate any services"); + } + // Check security + if (cluster.getDesiredConfigs() != null + && cluster.getDesiredConfigs().containsKey("global")) { + Map<String, String> globalConfig = client.getConfiguration(clusterInfo, + "global", cluster.getDesiredConfigs().get("global")); + if (globalConfig != null + && globalConfig.containsKey("security_enabled")) { + String securityValue = globalConfig.get("security_enabled"); + if (Boolean.valueOf(securityValue)) { + viewErrors + .add("Slider applications view cannot be rendered in secure mode"); + } + } else { + viewErrors + .add("Slider applications view is unable to determine the security status of the cluster"); + } + } else { + viewErrors + .add("Slider applications view is unable to determine the security status of the cluster"); + } + } else { + viewErrors.add("Slider applications view requires a cluster"); + } + status.setVersion(SliderAppsConfiguration.INSTANCE.getVersion()); + status.setViewEnabled(viewErrors.size() < 1); + status.setViewErrors(viewErrors); + return status; + } + + @Override + public SliderApp getSliderApp(String applicationId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List<SliderApp> getSliderApps() { + // TODO Auto-generated method stub + return null; + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/ViewStatus.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/ViewStatus.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/ViewStatus.java new file mode 100644 index 0000000..134f400 --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/ViewStatus.java @@ -0,0 +1,51 @@ +/** + * 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.ambari.view.slider; + +import java.util.List; + +public class ViewStatus { + private String version; + private boolean viewEnabled; + private List<String> viewErrors; + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public boolean isViewEnabled() { + return viewEnabled; + } + + public void setViewEnabled(boolean viewEnabled) { + this.viewEnabled = viewEnabled; + } + + public List<String> getViewErrors() { + return viewErrors; + } + + public void setViewErrors(List<String> viewErrors) { + this.viewErrors = viewErrors; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/SliderAppsResource.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/SliderAppsResource.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/SliderAppsResource.java new file mode 100644 index 0000000..7b11d94 --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/SliderAppsResource.java @@ -0,0 +1,30 @@ +/** + * 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.ambari.view.slider.rest; + +import org.apache.ambari.view.slider.SliderAppsResourceProvider; + +import com.google.inject.Inject; + +public class SliderAppsResource { + + @Inject + SliderAppsResourceProvider resourceHandler; + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/ViewStatusResource.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/ViewStatusResource.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/ViewStatusResource.java new file mode 100644 index 0000000..5023d90 --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/ViewStatusResource.java @@ -0,0 +1,40 @@ +/** + * 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.ambari.view.slider.rest; + +import javax.ws.rs.GET; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.apache.ambari.view.slider.SliderAppsViewController; +import org.apache.ambari.view.slider.ViewStatus; + +import com.google.inject.Inject; + +public class ViewStatusResource { + + @Inject + SliderAppsViewController sliderController; + + @GET + @Produces({ MediaType.APPLICATION_JSON }) + public ViewStatus getViewStatus() { + return sliderController.getViewStatus(); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariCluster.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariCluster.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariCluster.java new file mode 100644 index 0000000..381a65d --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariCluster.java @@ -0,0 +1,52 @@ +/** + * 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.ambari.view.slider.rest.client; + +import java.util.List; +import java.util.Map; + +public class AmbariCluster extends AmbariClusterInfo { + private Map<String, String> desiredConfigs; + private List<String> services; + private List<String> hosts; + + public Map<String, String> getDesiredConfigs() { + return desiredConfigs; + } + + public void setDesiredConfigs(Map<String, String> desiredConfigs) { + this.desiredConfigs = desiredConfigs; + } + + public List<String> getServices() { + return services; + } + + public void setServices(List<String> services) { + this.services = services; + } + + public List<String> getHosts() { + return hosts; + } + + public void setHosts(List<String> hosts) { + this.hosts = hosts; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariClusterInfo.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariClusterInfo.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariClusterInfo.java new file mode 100644 index 0000000..56f57a3 --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariClusterInfo.java @@ -0,0 +1,40 @@ +/** + * 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.ambari.view.slider.rest.client; + +public class AmbariClusterInfo { + private String name; + private String version; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariHttpClient.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariHttpClient.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariHttpClient.java new file mode 100644 index 0000000..b4c780d --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariHttpClient.java @@ -0,0 +1,176 @@ +/** + * 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.ambari.view.slider.rest.client; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.httpclient.HttpException; +import org.apache.log4j.Logger; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +public class AmbariHttpClient extends BaseHttpClient { + + private static final Logger logger = Logger.getLogger(AmbariHttpClient.class); + + public AmbariHttpClient(String url, String userId, String password) { + super(url, userId, password); + } + + /** + * Provides the first cluster defined on this Ambari server. + * + * @return + */ + public AmbariClusterInfo getClusterInfo() { + try { + JsonElement jsonElement = doGetJson("/api/v1/clusters"); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + JsonArray clustersArray = jsonObject.get("items").getAsJsonArray(); + if (clustersArray.size() > 0) { + AmbariClusterInfo cluster = new AmbariClusterInfo(); + JsonObject clusterObj = clustersArray.get(0).getAsJsonObject() + .get("Clusters").getAsJsonObject(); + cluster.setName(clusterObj.get("cluster_name").getAsString()); + cluster.setVersion(clusterObj.get("version").getAsString()); + return cluster; + } + } catch (HttpException e) { + logger.warn("Unable to determine Ambari clusters", e); + throw new RuntimeException(e.getMessage(), e); + } catch (IOException e) { + logger.warn("Unable to determine Ambari clusters", e); + throw new RuntimeException(e.getMessage(), e); + } + return null; + } + + public AmbariCluster getCluster(AmbariClusterInfo clusterInfo) { + if (clusterInfo != null) { + try { + JsonElement jsonElement = doGetJson("/api/v1/clusters/" + + clusterInfo.getName()); + if (jsonElement != null) { + AmbariCluster cluster = new AmbariCluster(); + // desired configs + Map<String, String> desiredConfigs = new HashMap<String, String>(); + JsonObject desiredConfigsObj = jsonElement.getAsJsonObject() + .get("Clusters").getAsJsonObject().get("desired_configs") + .getAsJsonObject(); + for (Map.Entry<String, JsonElement> entry : desiredConfigsObj + .entrySet()) { + desiredConfigs.put(entry.getKey(), entry.getValue() + .getAsJsonObject().get("tag").getAsString()); + } + cluster.setDesiredConfigs(desiredConfigs); + // services + List<String> services = new ArrayList<String>(); + JsonArray servicesArray = jsonElement.getAsJsonObject() + .get("services").getAsJsonArray(); + for (JsonElement entry : servicesArray) { + services.add(entry.getAsJsonObject().get("ServiceInfo") + .getAsJsonObject().get("service_name").getAsString()); + } + cluster.setServices(services); + // hosts + List<String> hosts = new ArrayList<String>(); + JsonArray hostsArray = jsonElement.getAsJsonObject().get("hosts") + .getAsJsonArray(); + for (JsonElement entry : hostsArray) { + hosts.add(entry.getAsJsonObject().get("Hosts").getAsJsonObject() + .get("host_name").getAsString()); + } + cluster.setHosts(hosts); + return cluster; + } + } catch (HttpException e) { + logger.warn("Unable to determine Ambari cluster details - " + + clusterInfo.getName(), e); + throw new RuntimeException(e.getMessage(), e); + } catch (IOException e) { + logger.warn("Unable to determine Ambari cluster details - " + + clusterInfo.getName(), e); + throw new RuntimeException(e.getMessage(), e); + } + } + return null; + } + + public AmbariService getService(AmbariClusterInfo clusterInfo, + String serviceId) { + if (clusterInfo != null) { + try { + JsonElement jsonElement = doGetJson("/api/v1/clusters/" + + clusterInfo.getName() + "/services/" + serviceId); + if (jsonElement != null) { + AmbariService service = new AmbariService(); + String serviceState = jsonElement.getAsJsonObject() + .get("ServiceInfo").getAsJsonObject().get("state").getAsString(); + service.setStarted("STARTED".equals(serviceState)); + return service; + } + } catch (HttpException e) { + logger.warn( + "Unable to determine Ambari service details - " + serviceId, e); + throw new RuntimeException(e.getMessage(), e); + } catch (IOException e) { + logger.warn( + "Unable to determine Ambari cluster details - " + serviceId, e); + throw new RuntimeException(e.getMessage(), e); + } + } + return null; + } + + public Map<String, String> getConfiguration(AmbariClusterInfo cluster, + String configType, String configTag) { + if (cluster != null && configType != null && configTag != null) { + try { + JsonElement jsonElement = doGetJson("/api/v1/clusters/" + + cluster.getName() + "/configurations?type=" + configType + + "&tag=" + configTag); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + JsonArray configsArray = jsonObject.get("items").getAsJsonArray(); + if (configsArray.size() > 0) { + JsonObject propertiesObj = configsArray.get(0).getAsJsonObject() + .get("properties").getAsJsonObject(); + Map<String, String> properties = new HashMap<String, String>(); + for (Map.Entry<String, JsonElement> entry : propertiesObj.entrySet()) { + properties.put(entry.getKey(), entry.getValue().getAsString()); + } + return properties; + } + } catch (HttpException e) { + logger.warn("Unable to determine Ambari clusters", e); + throw new RuntimeException(e.getMessage(), e); + } catch (IOException e) { + logger.warn("Unable to determine Ambari clusters", e); + throw new RuntimeException(e.getMessage(), e); + } + } + return null; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariService.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariService.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariService.java new file mode 100644 index 0000000..527ea2d --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariService.java @@ -0,0 +1,42 @@ +/** + * 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.ambari.view.slider.rest.client; + +public class AmbariService { + + private String id; + private boolean started; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public boolean isStarted() { + return started; + } + + public void setStarted(boolean started) { + this.started = started; + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/BaseHttpClient.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/BaseHttpClient.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/BaseHttpClient.java new file mode 100644 index 0000000..139494c --- /dev/null +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/BaseHttpClient.java @@ -0,0 +1,116 @@ +/** + * 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.ambari.view.slider.rest.client; + +import java.io.IOException; +import java.io.InputStreamReader; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.auth.AuthScope; +import org.apache.commons.httpclient.methods.GetMethod; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; + +public class BaseHttpClient { + + private HttpClient httpClient; + private String url; + private boolean needsAuthentication; + private String userId; + private String password; + + public BaseHttpClient(String url) { + setUrl(url); + setNeedsAuthentication(false); + } + + public BaseHttpClient(String url, String userId, String password) { + setUrl(url); + setNeedsAuthentication(true); + setUserId(userId); + setPassword(password); + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public boolean isNeedsAuthentication() { + return needsAuthentication; + } + + public void setNeedsAuthentication(boolean needsAuthentication) { + this.needsAuthentication = needsAuthentication; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public JsonElement doGetJson(String path) throws HttpException, IOException { + GetMethod get = new GetMethod(url + path); + if (isNeedsAuthentication()) { + get.setDoAuthentication(true); + } + int executeMethod = getHttpClient().executeMethod(get); + switch (executeMethod) { + case HttpStatus.SC_OK: + JsonElement jsonElement = new JsonParser().parse(new JsonReader( + new InputStreamReader(get.getResponseBodyAsStream()))); + return jsonElement; + default: + break; + } + return null; + } + + private HttpClient getHttpClient() { + if (httpClient == null) { + httpClient = new HttpClient(); + } + if (isNeedsAuthentication()) { + httpClient.getState().setCredentials( + new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), + new UsernamePasswordCredentials(getUserId(), getPassword())); + httpClient.getParams().setAuthenticationPreemptive(true); + } + return httpClient; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/resources/slider.properties ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/slider.properties b/contrib/views/slider/src/main/resources/slider.properties new file mode 100644 index 0000000..c635e15 --- /dev/null +++ b/contrib/views/slider/src/main/resources/slider.properties @@ -0,0 +1,19 @@ +# Copyright 2011 The Apache Software Foundation +# +# 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. + +slider.view.version=${project.version} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/a9ca4747/contrib/views/slider/src/main/resources/view.xml ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/view.xml b/contrib/views/slider/src/main/resources/view.xml index 43dacbe..c960e15 100644 --- a/contrib/views/slider/src/main/resources/view.xml +++ b/contrib/views/slider/src/main/resources/view.xml @@ -21,4 +21,16 @@ limitations under the License. Kerberos, LDAP, Custom. Binary/Htt <instance> <name>SLIDER_1</name> </instance> + <resource> + <name>status</name> + <service-class>org.apache.ambari.view.slider.rest.ViewStatusResource</service-class> + </resource> + <resource> + <name>app</name> + <plural-name>apps</plural-name> + <id-property>id</id-property> + <resource-class>org.apache.ambari.view.slider.SliderApp</resource-class> + <provider-class>org.apache.ambari.view.slider.SliderAppsResourceProvider</provider-class> + <service-class>org.apache.ambari.view.slider.rest.SliderAppsResource</service-class> + </resource> </view> \ No newline at end of file
