SLIDER-5 CLI minimal configs come back from parent; full from full path
git-svn-id: https://svn.apache.org/repos/asf/incubator/slider/trunk@1592568 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
index 054fc66..866ee88 100644
--- a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
+++ b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
@@ -1958,6 +1958,11 @@
} else if (registryArgs.listConf) {
// list the configurations
actionRegistryListConfigs(registryArgs);
+ } else if (SliderUtils.isSet(registryArgs.getConf)) {
+ // get a configuration
+ PublishedConfiguration publishedConfiguration =
+ actionRegistryGetConfig(registryArgs);
+
} else {
exitCode = EXIT_FALSE;
}
@@ -1986,7 +1991,7 @@
}
/**
- * Registry operation
+ * list configs available for an instance
*
* @param registryArgs registry Arguments
* @throws YarnException YARN problems
@@ -2013,6 +2018,44 @@
}
}
+ /**
+ * list configs available for an instance
+ *
+ * @param registryArgs registry Arguments
+ * @throws YarnException YARN problems
+ * @throws IOException Network or other problems
+ */
+ public PublishedConfiguration actionRegistryGetConfig(ActionRegistryArgs registryArgs)
+ throws YarnException, IOException {
+ ServiceInstanceData instance = lookupInstance(registryArgs);
+
+ RegistryRetriever retriever = new RegistryRetriever(instance);
+ boolean external = !registryArgs.internal;
+ PublishedConfigSet configurations =
+ retriever.getConfigurations(external);
+
+ PublishedConfiguration published =
+ retriever.retrieveConfiguration(registryArgs.getConf, external);
+ return published;
+ }
+
+ private void outputConfig(PublishedConfiguration published,
+ ActionRegistryArgs registryArgs) {
+ // decide whether or not to print
+ boolean print = registryArgs.dest == null;
+ String entry = registryArgs.getConf;
+ String format = registryArgs.format;
+ File destFile;
+ if (!print) {
+ destFile = registryArgs.dest;
+ if (destFile.isDirectory()) {
+ // creating it under a directory
+ destFile = new File(destFile, entry + "." + format);
+ }
+ log.info("Destination path: {}", destFile);
+ }
+
+ }
/**
* Look up an instance
@@ -2123,4 +2166,13 @@
IOException {
return maybeStartRegistry();
}
+
+ /**
+ * Output to standard out/stderr (implementation specific detail)
+ * @param src source
+ */
+ @SuppressWarnings("UseOfSystemOutOrSystemErr")
+ private static void print(CharSequence src) {
+ System.out.append(src);
+ }
}
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/ConfigFormats.java b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/ConfigFormats.java
new file mode 100644
index 0000000..b18cebb
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/ConfigFormats.java
@@ -0,0 +1,38 @@
+/*
+ * 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.core.registry.docstore;
+
+public enum ConfigFormats {
+
+ JSON("json"),
+ PROPERTIES("properties"),
+ XML("xml"),
+ YAML("yaml");
+
+ ConfigFormats(String suffix) {
+ this.suffix = suffix;
+ }
+
+ private final String suffix;
+
+ public String getSuffix() {
+ return suffix;
+ }
+
+}
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfiguration.java b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfiguration.java
index 3c7b521..00bdeb5 100644
--- a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfiguration.java
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfiguration.java
@@ -21,7 +21,6 @@
import org.apache.hadoop.conf.Configuration;
import org.apache.slider.common.tools.ConfigHelper;
import org.apache.slider.core.exceptions.BadConfigException;
-import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@@ -43,9 +42,6 @@
public class PublishedConfiguration {
public String description;
-
- public int size;
-
public long updated;
public String updatedTime;
@@ -59,7 +55,7 @@
return updated;
}
- private Map<String, String> values = new HashMap<String, String>();
+ public Map<String, String> entries = new HashMap<String, String>();
/**
* Is the configuration empty. This means either that it has not
@@ -68,7 +64,7 @@
* @return
*/
public boolean isEmpty() {
- return values.isEmpty();
+ return entries.isEmpty();
}
/**
@@ -78,9 +74,9 @@
* @param entries entries to put
*/
public void putValues(Iterable<Map.Entry<String, String>> entries) {
- values = new HashMap<String, String>();
+ this.entries = new HashMap<String, String>();
for (Map.Entry<String, String> entry : entries) {
- values.put(entry.getKey(), entry.getValue());
+ this.entries.put(entry.getKey(), entry.getValue());
}
}
@@ -92,7 +88,7 @@
public Configuration asConfiguration() {
Configuration conf = new Configuration(false);
try {
- ConfigHelper.addConfigMap(conf, values, "");
+ ConfigHelper.addConfigMap(conf, entries, "");
} catch (BadConfigException e) {
// triggered on a null value; switch to a runtime (and discard the stack)
throw new RuntimeException(e.toString());
@@ -110,7 +106,7 @@
*/
public Properties asProperties() {
Properties props = new Properties();
- props.putAll(values);
+ props.putAll(entries);
return props;
}
@@ -121,7 +117,7 @@
*/
public String asJson() throws IOException {
ObjectMapper mapper = new ObjectMapper();
- String json = mapper.writeValueAsString(values);
+ String json = mapper.writeValueAsString(entries);
return json;
}
@@ -134,9 +130,18 @@
public PublishedConfiguration shallowCopy() {
PublishedConfiguration that = new PublishedConfiguration();
that.description = this.description;
- that.size = this.size;
that.updated = this.updated;
that.updatedTime = this.updatedTime;
return that;
}
+
+ @Override
+ public String toString() {
+ final StringBuilder sb =
+ new StringBuilder("PublishedConfiguration{");
+ sb.append("description='").append(description).append('\'');
+ sb.append("entries = ").append(entries.size());
+ sb.append('}');
+ return sb.toString();
+ }
}
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfigurationOutputter.java b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfigurationOutputter.java
new file mode 100644
index 0000000..ba38967
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfigurationOutputter.java
@@ -0,0 +1,34 @@
+/*
+ * 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.core.registry.docstore;
+
+import java.io.File;
+import java.io.IOException;
+
+public abstract class PublishedConfigurationOutputter {
+
+ public void save(File dest) throws IOException {
+
+ }
+
+ public String asString() {
+ return "";
+ }
+
+}
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/info/ServiceInstanceData.java b/slider-core/src/main/java/org/apache/slider/core/registry/info/ServiceInstanceData.java
index 6c6918c..e123a12 100644
--- a/slider-core/src/main/java/org/apache/slider/core/registry/info/ServiceInstanceData.java
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/info/ServiceInstanceData.java
@@ -50,7 +50,7 @@
final StringBuilder sb =
new StringBuilder("ServiceInstanceData{");
sb.append(", id='").append(id).append('\'');
- sb.append("serviceType='").append(serviceType).append('\'');
+ sb.append(", serviceType='").append(serviceType).append('\'');
sb.append('}');
return sb.toString();
}
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/retrieve/RegistryRetriever.java b/slider-core/src/main/java/org/apache/slider/core/registry/retrieve/RegistryRetriever.java
index 5d34ea8..e4cf428 100644
--- a/slider-core/src/main/java/org/apache/slider/core/registry/retrieve/RegistryRetriever.java
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/retrieve/RegistryRetriever.java
@@ -25,8 +25,10 @@
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.json.JSONConfiguration;
+import org.apache.slider.common.tools.SliderUtils;
import org.apache.slider.core.exceptions.ExceptionConverter;
import org.apache.slider.core.registry.docstore.PublishedConfigSet;
+import org.apache.slider.core.registry.docstore.PublishedConfiguration;
import org.apache.slider.core.registry.info.RegistryView;
import org.apache.slider.core.registry.info.ServiceInstanceData;
import org.slf4j.Logger;
@@ -98,8 +100,7 @@
+ destination(external) + " view");
}
try {
- WebResource webResource = jerseyClient.resource(confURL);
- webResource.type(MediaType.APPLICATION_JSON);
+ WebResource webResource = jsonResource(confURL);
log.debug("GET {}", confURL);
PublishedConfigSet configSet = webResource.get(PublishedConfigSet.class);
return configSet;
@@ -108,6 +109,38 @@
}
}
+ private WebResource resource(String url) {
+ WebResource resource = jerseyClient.resource(url);
+ return resource;
+ }
+
+ private WebResource jsonResource(String url) {
+ WebResource resource = resource(url);
+ resource.type(MediaType.APPLICATION_JSON);
+ return resource;
+ }
+
+ /**
+ * Get a complete configuration, with all values
+ * @param name
+ * @param external
+ * @return
+ * @throws IOException
+ */
+ public PublishedConfiguration retrieveConfiguration(String name,
+ boolean external) throws IOException {
+ String confURL = getRegistryView(external).configurationsURL;
+ confURL = SliderUtils.appendToURL(confURL, name);
+ try {
+ WebResource webResource = jsonResource(confURL);
+ log.debug("GET {}", confURL);
+ PublishedConfiguration configSet = webResource.get(PublishedConfiguration.class);
+ return configSet;
+ } catch (UniformInterfaceException e) {
+ throw ExceptionConverter.convertJerseyException(confURL, e);
+ }
+ }
+
@Override
public String toString() {
return super.toString() + " - " + instance;
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/publisher/PublisherResource.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/publisher/PublisherResource.java
index 318ca03..d18a08d 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/publisher/PublisherResource.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/publisher/PublisherResource.java
@@ -75,7 +75,7 @@
@GET
@Path("/{config}")
- @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+ @Produces({MediaType.APPLICATION_JSON})
public PublishedConfiguration getConfigurationInstance(
@PathParam("config") String config,
@Context UriInfo uriInfo,
diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneRegistryAM.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneRegistryAM.groovy
index 904f715..6de0a9f 100644
--- a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneRegistryAM.groovy
+++ b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneRegistryAM.groovy
@@ -22,6 +22,7 @@
import groovy.util.logging.Slf4j
import org.apache.hadoop.yarn.api.records.ApplicationReport
import org.apache.hadoop.yarn.api.records.YarnApplicationState
+import org.apache.hadoop.yarn.conf.YarnConfiguration
import org.apache.slider.agent.AgentMiniClusterTestBase
import org.apache.slider.api.ClusterNode
import org.apache.slider.client.SliderClient
@@ -30,6 +31,7 @@
import org.apache.slider.core.main.ServiceLauncher
import org.apache.slider.core.persist.JsonSerDeser
import org.apache.slider.core.registry.docstore.PublishedConfigSet
+import org.apache.slider.core.registry.docstore.PublishedConfiguration
import org.apache.slider.core.registry.info.CustomRegistryConstants
import org.apache.slider.core.registry.info.ServiceInstanceData
import org.apache.slider.core.registry.retrieve.RegistryRetriever
@@ -129,9 +131,17 @@
def externalEndpoints = serviceInstanceData.externalView.endpoints
- def endpoint = externalEndpoints.get(CustomRegistryConstants.PUBLISHER_REST_API)
- assert endpoint != null
- def publisherURL = endpoint.asURL()
+ // hit the registry web page
+
+ def registryEndpoint = externalEndpoints.get(
+ CustomRegistryConstants.REGISTRY_REST_API)
+ assert registryEndpoint != null
+ def registryURL = registryEndpoint.asURL()
+ describe("Registry WADL @ $registryURL")
+
+ def publisherEndpoint = externalEndpoints.get(CustomRegistryConstants.PUBLISHER_REST_API)
+ assert publisherEndpoint != null
+ def publisherURL = publisherEndpoint.asURL()
def publisher = publisherURL.toString()
describe("Publisher")
@@ -142,24 +152,31 @@
def configSet = serDeser.fromJson(publishedJSON)
assert configSet.size() >= 1
assert configSet.contains(YARN_SITE)
- def publishedYarnSite = configSet.get(YARN_SITE)
+ PublishedConfiguration publishedYarnSite = configSet.get(YARN_SITE)
+ assert publishedYarnSite.empty
+ //get the full URL
def yarnSitePublisher = appendToURL(publisher, YARN_SITE)
+
+ String confJSON = GET(yarnSitePublisher)
+ log.info(confJSON)
+ JsonSerDeser< PublishedConfiguration> confSerDeser =
+ new JsonSerDeser<PublishedConfiguration>(PublishedConfiguration)
+
+ publishedYarnSite = confSerDeser.fromJson(confJSON)
+
+ assert !publishedYarnSite.empty
+
+
+ //get the XML
def yarnSiteXML = appendToURL(yarnSitePublisher, "xml")
String confXML = GET(yarnSiteXML)
log.info("Conf XML at $yarnSiteXML = \n $confXML")
- String confJSON = GET(yarnSitePublisher, "json")
- // hit the registry web page
-
- def registryEndpoint = externalEndpoints.get(CustomRegistryConstants.REGISTRY_REST_API)
- assert registryEndpoint != null
- def registryURL = registryEndpoint.asURL()
- describe("Registry WADL @ $registryURL")
describe("Registry List")
log.info(GET(registryURL, RestPaths.REGISTRY_SERVICE ))
@@ -177,8 +194,16 @@
def config = externalConf.get(key)
log.info "$key -- ${config.description}"
}
- assert externalConf["yarn-site.xml"]
+ assert externalConf[YARN_SITE]
+
+ def yarnSite = retriever.retrieveConfiguration(YARN_SITE, true)
+ assert !yarnSite.empty
+ def siteXML = yarnSite.asConfiguration()
+ def rmAddr = siteXML.get(YarnConfiguration.RM_ADDRESS)
+ assert rmAddr
+
+
describe "Internal configurations"
assert !retriever.hasConfigurations(false)
try {