SLIDER-35 core of provider config publishing; tests on hbase showing things aren't quite there yet...
git-svn-id: https://svn.apache.org/repos/asf/incubator/slider/trunk@1596353 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/slider-core/src/main/java/org/apache/slider/Slider.java b/slider-core/src/main/java/org/apache/slider/Slider.java
index 5fc8618..0d25f00 100644
--- a/slider-core/src/main/java/org/apache/slider/Slider.java
+++ b/slider-core/src/main/java/org/apache/slider/Slider.java
@@ -42,7 +42,7 @@
//turn the args to a list
List<String> argsList = Arrays.asList(args);
//create a new list, as the ArrayList type doesn't push() on an insert
- List<String> extendedArgs = new ArrayList<String>(argsList);
+ List<String> extendedArgs = new ArrayList<>(argsList);
//insert the service name
extendedArgs.add(0, SERVICE_CLASSNAME);
//now have the service launcher do its work
diff --git a/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java b/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
index 3f49e1f..bdc381e 100644
--- a/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
+++ b/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
@@ -1342,11 +1342,25 @@
} else {
fullpath.append(path);
}
-
return fullpath.toString();
}
/**
+ * Append a list of paths, inserting "/" signs as appropriate
+ * @param base
+ * @param paths
+ * @return
+ */
+ public static String appendToURL(String base, String...paths) {
+ String result = base;
+ for (String path : paths) {
+ result = appendToURL(result, path);
+ }
+ return result;
+ }
+
+
+ /**
* Callable for async/scheduled halt
*/
public static class DelayedHalt extends TimerTask {
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfigSet.java b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfigSet.java
index 7db56f4..f498916 100644
--- a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfigSet.java
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfigSet.java
@@ -19,6 +19,7 @@
package org.apache.slider.core.registry.docstore;
import org.apache.slider.server.appmaster.web.rest.RestPaths;
+import org.apache.slider.server.services.utility.PatternValidator;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@@ -27,7 +28,6 @@
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
-import java.util.regex.Pattern;
/**
* Represents a set of configurations for an application, component, etc.
@@ -37,15 +37,15 @@
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class PublishedConfigSet {
- public static final String VALID_NAME_PATTERN = RestPaths.PUBLISHED_CONFIGURATION_REGEXP;
- public static final String E_INVALID_NAME =
- "Invalid configuration name -it must match the pattern " +
- VALID_NAME_PATTERN;
- private static final Pattern validNames = Pattern.compile(VALID_NAME_PATTERN);
+ private static final PatternValidator validator = new PatternValidator(
+ RestPaths.PUBLISHED_CONFIGURATION_REGEXP);
public Map<String, PublishedConfiguration> configurations =
new HashMap<>();
+ public PublishedConfigSet() {
+ }
+
/**
* Put a name -it will be converted to lower case before insertion.
* Any existing entry will be overwritten (that includes an entry
@@ -62,14 +62,13 @@
/**
* Validate the name -restricting it to the set defined in
- * {@link #VALID_NAME_PATTERN}
+ * {@link RestPaths#PUBLISHED_CONFIGURATION_REGEXP}
* @param name name to validate
* @throws IllegalArgumentException if not a valid name
*/
public static void validateName(String name) {
- if (!validNames.matcher(name).matches()) {
- throw new IllegalArgumentException(E_INVALID_NAME);
- }
+ validator.validate(name);
+
}
public PublishedConfiguration get(String name) {
@@ -92,8 +91,8 @@
public PublishedConfigSet shallowCopy() {
PublishedConfigSet that = new PublishedConfigSet();
- for (Map.Entry<String, PublishedConfiguration> entry : configurations
- .entrySet()) {
+ for (Map.Entry<String, PublishedConfiguration> entry :
+ configurations.entrySet()) {
that.put(entry.getKey(), entry.getValue().shallowCopy());
}
return that;
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/UriMap.java b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/UriMap.java
new file mode 100644
index 0000000..120966f
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/UriMap.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;
+
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+public class UriMap {
+
+ public Map<String, String> uris = new HashMap<>();
+
+ @JsonIgnore
+ public void put(String key, String value) {
+ uris.put(key, value);
+ }
+}
diff --git a/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java b/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
index 2c82b15..8d3146a 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
@@ -62,10 +62,11 @@
ProviderService {
private static final Logger log =
LoggerFactory.getLogger(AbstractProviderService.class);
- protected AggregateConf instanceDefinition;
- protected StateAccessForProviders stateAccessor;
+ protected StateAccessForProviders amState;
protected AgentRestOperations restOps;
protected RegistryViewForProviders registry;
+ protected ServiceInstanceData registryInstanceData;
+ protected URL amWebAPI;
public AbstractProviderService(String name) {
super(name);
@@ -76,18 +77,18 @@
return getConfig();
}
- public StateAccessForProviders getStateAccessor() {
- return stateAccessor;
+ public StateAccessForProviders getAmState() {
+ return amState;
}
- public void setStateAccessor(StateAccessForProviders stateAccessor) {
- this.stateAccessor = stateAccessor;
+ public void setAmState(StateAccessForProviders amState) {
+ this.amState = amState;
}
@Override
public void bind(StateAccessForProviders stateAccessor,
RegistryViewForProviders registry) {
- this.stateAccessor = stateAccessor;
+ this.amState = stateAccessor;
this.registry = registry;
}
@@ -308,6 +309,7 @@
ServiceInstanceData registryInstanceData) throws MalformedURLException,
IOException {
- //no-op
+ this.amWebAPI = amWebAPI;
+ this.registryInstanceData = registryInstanceData;
}
}
diff --git a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
index bbbbe70..f7f2b21 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
@@ -72,7 +72,6 @@
import java.io.File;
import java.io.IOException;
-import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
@@ -171,7 +170,6 @@
}
}
- this.instanceDefinition = instanceDefinition;
log.info("Build launch context for Agent");
log.debug(instanceDefinition.toString());
@@ -262,13 +260,13 @@
pubconf.description = description;
pubconf.putValues(entries);
log.info("publishing {}", pubconf);
- getStateAccessor().getPublishedConfigurations().put(name, pubconf);
+ getAmState().getPublishedSliderConfigurations().put(name, pubconf);
}
protected Map<String, Map<String, ClusterNode>> getRoleClusterNodeMapping() {
- stateAccessor.refreshClusterStatus();
+ amState.refreshClusterStatus();
return (Map<String, Map<String, ClusterNode>>)
- stateAccessor.getClusterStatus().status.get(
+ amState.getClusterStatus().status.get(
ClusterDescriptionKeys.KEY_CLUSTER_LIVE);
}
@@ -277,7 +275,7 @@
}
protected String getClusterInfoPropertyValue(String name) {
- StateAccessForProviders accessor = getStateAccessor();
+ StateAccessForProviders accessor = getAmState();
assert accessor.isApplicationLive();
ClusterDescription description = accessor.getClusterStatus();
return description.getInfo(name);
@@ -367,7 +365,7 @@
String label = heartBeat.getHostname();
String roleName = getRoleName(label);
String containerId = getContainerId(label);
- StateAccessForProviders accessor = getStateAccessor();
+ StateAccessForProviders accessor = getAmState();
String scriptPath = getScriptPathFromMetainfo(roleName);
if (scriptPath == null) {
@@ -550,10 +548,10 @@
protected void addInstallCommand(String roleName, String containerId, HeartBeatResponse response, String scriptPath)
throws SliderException {
- assert getStateAccessor().isApplicationLive();
- ConfTreeOperations appConf = getStateAccessor().getAppConfSnapshot();
- ConfTreeOperations resourcesConf = getStateAccessor().getResourcesSnapshot();
- ConfTreeOperations internalsConf = getStateAccessor().getInternalsSnapshot();
+ assert getAmState().isApplicationLive();
+ ConfTreeOperations appConf = getAmState().getAppConfSnapshot();
+ ConfTreeOperations resourcesConf = getAmState().getResourcesSnapshot();
+ ConfTreeOperations internalsConf = getAmState().getInternalsSnapshot();
ExecutionCommand cmd = new ExecutionCommand(AgentCommandType.EXECUTION_COMMAND);
prepareExecutionCommand(cmd);
@@ -597,7 +595,7 @@
}
private void setInstallCommandConfigurations(ExecutionCommand cmd) {
- ConfTreeOperations appConf = getStateAccessor().getAppConfSnapshot();
+ ConfTreeOperations appConf = getAmState().getAppConfSnapshot();
Map<String, Map<String, String>> configurations = buildCommandConfigurations(appConf);
cmd.setConfigurations(configurations);
}
@@ -605,9 +603,9 @@
@VisibleForTesting
protected void addStatusCommand(String roleName, String containerId, HeartBeatResponse response, String scriptPath)
throws SliderException {
- assert getStateAccessor().isApplicationLive();
- ConfTreeOperations appConf = getStateAccessor().getAppConfSnapshot();
- ConfTreeOperations internalsConf = getStateAccessor().getInternalsSnapshot();
+ assert getAmState().isApplicationLive();
+ ConfTreeOperations appConf = getAmState().getAppConfSnapshot();
+ ConfTreeOperations internalsConf = getAmState().getInternalsSnapshot();
StatusCommand cmd = new StatusCommand();
String clusterName = internalsConf.get(OptionKeys.APPLICATION_NAME);
@@ -635,8 +633,8 @@
@VisibleForTesting
protected void addGetConfigCommand(String roleName, String containerId, HeartBeatResponse response)
throws SliderException {
- assert getStateAccessor().isApplicationLive();
- ConfTreeOperations internalsConf = getStateAccessor().getInternalsSnapshot();
+ assert getAmState().isApplicationLive();
+ ConfTreeOperations internalsConf = getAmState().getInternalsSnapshot();
StatusCommand cmd = new StatusCommand();
String clusterName = internalsConf.get(OptionKeys.APPLICATION_NAME);
@@ -659,9 +657,9 @@
protected void addStartCommand(String roleName, String containerId, HeartBeatResponse response, String scriptPath)
throws
SliderException {
- assert getStateAccessor().isApplicationLive();
- ConfTreeOperations appConf = getStateAccessor().getAppConfSnapshot();
- ConfTreeOperations internalsConf = getStateAccessor().getInternalsSnapshot();
+ assert getAmState().isApplicationLive();
+ ConfTreeOperations appConf = getAmState().getAppConfSnapshot();
+ ConfTreeOperations internalsConf = getAmState().getInternalsSnapshot();
ExecutionCommand cmd = new ExecutionCommand(AgentCommandType.EXECUTION_COMMAND);
prepareExecutionCommand(cmd);
diff --git a/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java b/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
index bf6ddd0..09e8229 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
@@ -26,6 +26,7 @@
import org.apache.slider.common.SliderKeys;
import org.apache.slider.common.tools.ConfigHelper;
import org.apache.slider.common.tools.SliderFileSystem;
+import org.apache.slider.common.tools.SliderUtils;
import org.apache.slider.core.conf.AggregateConf;
import org.apache.slider.core.conf.MapOperations;
import org.apache.slider.core.exceptions.BadCommandArgumentsException;
@@ -42,7 +43,6 @@
import org.apache.slider.providers.ProviderRole;
import org.apache.slider.providers.agent.AgentKeys;
import org.apache.slider.server.appmaster.PublishedArtifacts;
-import org.apache.slider.server.appmaster.state.StateAccessForProviders;
import org.apache.slider.server.appmaster.web.rest.RestPaths;
import org.apache.slider.server.services.utility.EventCallback;
@@ -54,7 +54,6 @@
import java.util.List;
import java.util.Map;
-import static org.apache.slider.server.appmaster.web.rest.RestPaths.SLIDER_PATH_AGENTS;
import static org.apache.slider.server.appmaster.web.rest.RestPaths.SLIDER_PATH_MANAGEMENT;
import static org.apache.slider.server.appmaster.web.rest.RestPaths.SLIDER_PATH_PUBLISHER;
@@ -117,34 +116,31 @@
// now publish site.xml files
YarnConfiguration defaultYarnConfig = new YarnConfiguration();
- stateAccessor.getPublishedConfigurations().put(
+ amState.getPublishedSliderConfigurations().put(
PublishedArtifacts.COMPLETE_CONFIG,
new PublishedConfiguration(
"Complete slider application settings",
getConfig(), getConfig())
);
- stateAccessor.getPublishedConfigurations().put(
+ amState.getPublishedSliderConfigurations().put(
PublishedArtifacts.YARN_SITE_CONFIG,
new PublishedConfiguration(
"YARN site settings",
ConfigHelper.loadFromResource("yarn-site.xml"),
- defaultYarnConfig)
- );
+ defaultYarnConfig) );
- stateAccessor.getPublishedConfigurations().put(
+ amState.getPublishedSliderConfigurations().put(
PublishedArtifacts.CORE_SITE_CONFIG,
new PublishedConfiguration(
"Core site settings",
ConfigHelper.loadFromResource("core-site.xml"),
- defaultYarnConfig)
- );
- stateAccessor.getPublishedConfigurations().put(
+ defaultYarnConfig) );
+ amState.getPublishedSliderConfigurations().put(
PublishedArtifacts.HDFS_SITE_CONFIG,
new PublishedConfiguration(
"HDFS site settings",
ConfigHelper.loadFromResource("hdfs-site.xml"),
- new HdfsConfiguration(true))
- );
+ new HdfsConfiguration(true)) );
try {
@@ -158,34 +154,30 @@
CustomRegistryConstants.MANAGEMENT_REST_API,
new RegisteredEndpoint(
new URL(amWebAPI, SLIDER_PATH_MANAGEMENT),
- "Management REST API")
- );
+ "Management REST API") );
externalView.endpoints.put(
CustomRegistryConstants.REGISTRY_REST_API,
new RegisteredEndpoint(
new URL(amWebAPI, RestPaths.SLIDER_PATH_REGISTRY + "/" +
RestPaths.REGISTRY_SERVICE),
- "Registry Web Service"
- )
- );
+ "Registry Web Service" ) );
URL publisherURL = new URL(amWebAPI, SLIDER_PATH_PUBLISHER);
externalView.endpoints.put(
CustomRegistryConstants.PUBLISHER_REST_API,
new RegisteredEndpoint(
publisherURL,
- "Publisher Service")
- );
+ "Publisher Service") );
/*
* Set the configurations URL.
*/
- externalView.configurationsURL = publisherURL.toExternalForm();
+ externalView.configurationsURL = SliderUtils.appendToURL(
+ publisherURL.toExternalForm(), RestPaths.SLIDER_CONFIGSET);
} catch (URISyntaxException e) {
throw new IOException(e);
}
-
}
}
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
index f72f507..25037ea 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
@@ -100,6 +100,7 @@
import org.apache.slider.server.appmaster.state.AppState;
import org.apache.slider.server.appmaster.state.ContainerAssignment;
import org.apache.slider.server.appmaster.state.ContainerReleaseOperation;
+import org.apache.slider.server.appmaster.state.ProviderAppState;
import org.apache.slider.server.appmaster.state.RMOperationHandler;
import org.apache.slider.server.appmaster.state.RoleInstance;
import org.apache.slider.server.appmaster.state.RoleStatus;
@@ -223,6 +224,9 @@
*/
private final AppState appState = new AppState(new ProtobufRecordFactory());
+ private final ProviderAppState stateForProviders =
+ new ProviderAppState("undefined", appState);
+
/**
* model the state using locks and conditions
@@ -379,13 +383,16 @@
String action = serviceArgs.getAction();
List<String> actionArgs = serviceArgs.getActionArgs();
int exitCode;
- if (action.equals(SliderActions.ACTION_HELP)) {
- log.info(getName() + serviceArgs.usage());
- exitCode = LauncherExitCodes.EXIT_USAGE;
- } else if (action.equals(SliderActions.ACTION_CREATE)) {
- exitCode = createAndRunCluster(actionArgs.get(0));
- } else {
- throw new SliderException("Unimplemented: " + action);
+ switch (action) {
+ case SliderActions.ACTION_HELP:
+ log.info(getName() + serviceArgs.usage());
+ exitCode = LauncherExitCodes.EXIT_USAGE;
+ break;
+ case SliderActions.ACTION_CREATE:
+ exitCode = createAndRunCluster(actionArgs.get(0));
+ break;
+ default:
+ throw new SliderException("Unimplemented: " + action);
}
log.info("Exiting AM; final exit code = {}", exitCode);
return exitCode;
@@ -425,10 +432,13 @@
AggregateConf instanceDefinition =
InstanceIO.loadInstanceDefinitionUnresolved(fs, clusterDirPath);
+ instanceDefinition.setName(clustername);
log.info("Deploying cluster {}:", instanceDefinition);
- //REVISIT: why is this done?
+ stateForProviders.setApplicationName(clustername);
+
+ // triggers resolution and snapshotting in agent
appState.updateInstanceDefinition(instanceDefinition);
File confDir = getLocalConfDir();
if (!confDir.exists() || !confDir.isDirectory()) {
@@ -561,7 +571,7 @@
// Start up the WebApp and track the URL for it
webApp = new SliderAMWebApp(registry);
WebApps.$for(SliderAMWebApp.BASE_PATH, WebAppApi.class,
- new WebAppApiImpl(this, appState, providerService),
+ new WebAppApiImpl(this, stateForProviders, providerService),
RestPaths.WS_CONTEXT)
.with(serviceConf)
.start(webApp);
@@ -665,8 +675,8 @@
//Give the provider restricted access to the state, registry
- providerService.bind(appState, registry);
- sliderAMProvider.bind(appState, registry);
+ providerService.bind(stateForProviders, registry);
+ sliderAMProvider.bind(stateForProviders, registry);
// now do the registration
registerServiceInstance(clustername, appid);
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java
index 087bf63..b5e67f5 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java
@@ -88,7 +88,7 @@
* is not synchronized and intended to be used during
* initialization.
*/
-public class AppState implements StateAccessForProviders {
+public class AppState {
protected static final Logger log =
LoggerFactory.getLogger(AppState.class);
@@ -142,10 +142,6 @@
*/
private ClusterDescription clusterSpec = new ClusterDescription();
- private final PublishedConfigSet
- publishedConfigurations = new PublishedConfigSet();
-
-
private final Map<Integer, RoleStatus> roleStatusMap =
new ConcurrentHashMap<>();
@@ -308,7 +304,7 @@
return completionOfUnknownContainerEvent;
}
- @Override
+
public Map<Integer, RoleStatus> getRoleStatusMap() {
return roleStatusMap;
}
@@ -326,18 +322,11 @@
}
- @Override
- public PublishedConfigSet getPublishedConfigurations() {
- return publishedConfigurations;
- }
-
-
- @Override
public Map<ContainerId, RoleInstance> getFailedNodes() {
return failedNodes;
}
- @Override
+
public Map<ContainerId, RoleInstance> getLiveNodes() {
return liveNodes;
}
@@ -350,7 +339,7 @@
return clusterSpec;
}
- @Override
+
public ClusterDescription getClusterStatus() {
return clusterStatus;
}
@@ -409,33 +398,33 @@
containerMaxMemory = maxMemory;
}
- @Override
+
public ConfTreeOperations getResourcesSnapshot() {
return resourcesSnapshot;
}
- @Override
+
public ConfTreeOperations getAppConfSnapshot() {
return appConfSnapshot;
}
- @Override
+
public ConfTreeOperations getInternalsSnapshot() {
return internalsSnapshot;
}
- @Override
+
public boolean isApplicationLive() {
return applicationLive;
}
- @Override
+
public long getSnapshotTime() {
return snapshotTime;
}
- @Override
+
public AggregateConf getInstanceDefinitionSnapshot() {
return instanceDefinitionSnapshot;
}
@@ -607,6 +596,7 @@
instanceDefinitionSnapshot = new AggregateConf(resourcesSnapshot.confTree,
appConfSnapshot.confTree,
internalsSnapshot.confTree);
+ instanceDefinitionSnapshot.setName(instanceDefinition.getName());
clusterSpec =
ClusterDescriptionOperations.buildFromInstanceDefinition(
@@ -751,7 +741,7 @@
return appMasterNode;
}
- @Override
+
public RoleStatus lookupRoleStatus(int key) {
RoleStatus rs = getRoleStatusMap().get(key);
if (rs == null) {
@@ -760,13 +750,13 @@
return rs;
}
- @Override
+
public RoleStatus lookupRoleStatus(Container c) throws YarnRuntimeException {
return lookupRoleStatus(ContainerPriority.extractRole(c));
}
- @Override
+
public RoleStatus lookupRoleStatus(String name) throws YarnRuntimeException {
ProviderRole providerRole = roles.get(name);
if (providerRole == null) {
@@ -775,23 +765,23 @@
return lookupRoleStatus(providerRole.id);
}
- @Override
+
public synchronized List<RoleInstance> cloneActiveContainerList() {
Collection<RoleInstance> values = activeContainers.values();
return new ArrayList<>(values);
}
- @Override
+
public int getNumActiveContainers() {
return activeContainers.size();
}
- @Override
+
public RoleInstance getActiveContainer(ContainerId id) {
return activeContainers.get(id);
}
- @Override
+
public synchronized List<RoleInstance> cloneLiveContainerInfoList() {
List<RoleInstance> allRoleInstances;
Collection<RoleInstance> values = getLiveNodes().values();
@@ -800,7 +790,7 @@
}
- @Override
+
public synchronized RoleInstance getLiveInstanceByContainerID(String containerId)
throws NoSuchNodeException {
Collection<RoleInstance> nodes = getLiveNodes().values();
@@ -813,7 +803,7 @@
throw new NoSuchNodeException(containerId);
}
- @Override
+
public synchronized List<RoleInstance> getLiveInstancesByContainerIDs(
Collection<String> containerIDs) {
//first, a hashmap of those containerIDs is built up
@@ -1152,7 +1142,7 @@
public RoleInstance roleInstance;
public boolean containerFailed;
- @Override
+
public String toString() {
final StringBuilder sb =
new StringBuilder("NodeCompletionResult{");
@@ -1311,7 +1301,7 @@
return percentage;
}
- @Override
+
public void refreshClusterStatus() {
refreshClusterStatus(null);
}
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java
new file mode 100644
index 0000000..6caf1a9
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java
@@ -0,0 +1,202 @@
+/*
+ * 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.state;
+
+import org.apache.hadoop.yarn.api.records.Container;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
+import org.apache.slider.api.ClusterDescription;
+import org.apache.slider.core.conf.AggregateConf;
+import org.apache.slider.core.conf.ConfTreeOperations;
+import org.apache.slider.core.exceptions.NoSuchNodeException;
+import org.apache.slider.core.registry.docstore.PublishedConfigSet;
+import org.apache.slider.server.appmaster.web.rest.RestPaths;
+import org.apache.slider.server.services.utility.PatternValidator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class ProviderAppState implements StateAccessForProviders {
+
+
+ private final Map<String, PublishedConfigSet> publishedConfigSets =
+ new ConcurrentHashMap<>(5);
+ private static final PatternValidator validator = new PatternValidator(
+ RestPaths.PUBLISHED_CONFIGURATION_SET_REGEXP);
+ private String applicationName;
+
+ private final AppState appState;
+
+ public ProviderAppState(String applicationName, AppState appState) {
+ this.appState = appState;
+ this.applicationName = applicationName;
+ }
+
+ public void setApplicationName(String applicationName) {
+ this.applicationName = applicationName;
+ }
+
+ @Override
+ public String getApplicationName() {
+ return applicationName;
+ }
+
+ @Override
+ public PublishedConfigSet getPublishedSliderConfigurations() {
+ return getOrCreatePublishedConfigSet(RestPaths.SLIDER_CONFIGSET);
+ }
+
+ @Override
+ public PublishedConfigSet getPublishedConfigSet(String name) {
+ return publishedConfigSets.get(name);
+ }
+
+ @Override
+ public PublishedConfigSet getOrCreatePublishedConfigSet(String name) {
+ PublishedConfigSet set = publishedConfigSets.get(name);
+ if (set == null) {
+ validator.validate(name);
+ synchronized (publishedConfigSets) {
+ // synchronized double check to ensure that there is never an overridden
+ // config set created
+ set = publishedConfigSets.get(name);
+ if (set == null) {
+ set = new PublishedConfigSet();
+ publishedConfigSets.put(name, set);
+ }
+ }
+ }
+ return set;
+ }
+
+ @Override
+ public List<String> listConfigSets() {
+
+ synchronized (publishedConfigSets) {
+ List<String> sets = new ArrayList<>(publishedConfigSets.keySet());
+ return sets;
+ }
+ }
+
+ @Override
+ public Map<Integer, RoleStatus> getRoleStatusMap() {
+ return appState.getRoleStatusMap();
+ }
+
+
+ @Override
+ public Map<ContainerId, RoleInstance> getFailedNodes() {
+ return appState.getFailedNodes();
+ }
+
+ @Override
+ public Map<ContainerId, RoleInstance> getLiveNodes() {
+ return appState.getLiveNodes();
+ }
+
+ @Override
+ public ClusterDescription getClusterStatus() {
+ return appState.getClusterStatus();
+ }
+
+ @Override
+ public ConfTreeOperations getResourcesSnapshot() {
+ return appState.getResourcesSnapshot();
+ }
+
+ @Override
+ public ConfTreeOperations getAppConfSnapshot() {
+ return appState.getAppConfSnapshot();
+ }
+
+ @Override
+ public ConfTreeOperations getInternalsSnapshot() {
+ return appState.getInternalsSnapshot();
+ }
+
+ @Override
+ public boolean isApplicationLive() {
+ return appState.isApplicationLive();
+ }
+
+ @Override
+ public long getSnapshotTime() {
+ return appState.getSnapshotTime();
+ }
+
+ @Override
+ public AggregateConf getInstanceDefinitionSnapshot() {
+ return appState.getInstanceDefinitionSnapshot();
+ }
+
+ @Override
+ public RoleStatus lookupRoleStatus(int key) {
+ return appState.lookupRoleStatus(key);
+ }
+
+ @Override
+ public RoleStatus lookupRoleStatus(Container c) throws YarnRuntimeException {
+ return appState.lookupRoleStatus(c);
+ }
+
+ @Override
+ public RoleStatus lookupRoleStatus(String name) throws YarnRuntimeException {
+ return appState.lookupRoleStatus(name);
+ }
+
+ @Override
+ public List<RoleInstance> cloneActiveContainerList() {
+ return appState.cloneActiveContainerList();
+ }
+
+ @Override
+ public int getNumActiveContainers() {
+ return appState.getNumActiveContainers();
+ }
+
+ @Override
+ public RoleInstance getActiveContainer(ContainerId id) {
+ return appState.getActiveContainer(id);
+ }
+
+ @Override
+ public List<RoleInstance> cloneLiveContainerInfoList() {
+ return appState.cloneLiveContainerInfoList();
+ }
+
+ @Override
+ public RoleInstance getLiveInstanceByContainerID(String containerId) throws
+ NoSuchNodeException {
+ return appState.getLiveInstanceByContainerID(containerId);
+ }
+
+ @Override
+ public List<RoleInstance> getLiveInstancesByContainerIDs(Collection<String> containerIDs) {
+ return appState.getLiveInstancesByContainerIDs(containerIDs);
+ }
+
+ @Override
+ public void refreshClusterStatus() {
+ appState.refreshClusterStatus();
+ }
+
+}
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java
index 4713dcd..acba8cc 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java
@@ -35,13 +35,40 @@
* The methods to offer state access to the providers
*/
public interface StateAccessForProviders {
+
Map<Integer, RoleStatus> getRoleStatusMap();
/**
+ * Get the name of the application
+ * @return the name
+ */
+ String getApplicationName();
+
+ /**
* Get the published configurations
* @return the configuration set
*/
- PublishedConfigSet getPublishedConfigurations();
+ PublishedConfigSet getPublishedSliderConfigurations();
+
+ /**
+ * Get a named published config set
+ * @param name name to look up
+ * @return the instance or null
+ */
+ PublishedConfigSet getPublishedConfigSet(String name);
+
+ /**
+ * Get a named published config set, creating it if need be.
+ * @param name name to look up
+ * @return the instance -possibly a new one
+ */
+ PublishedConfigSet getOrCreatePublishedConfigSet(String name);
+
+ /**
+ * List the config sets -this takes a clone of the current set
+ * @return a list of config sets
+ */
+ List<String> listConfigSets();
Map<ContainerId, RoleInstance> getFailedNodes();
@@ -163,4 +190,6 @@
* @param providerStatus status from the provider for the cluster info section
*/
void refreshClusterStatus();
+
+
}
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/RestPaths.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/RestPaths.java
index e2ca42f..fed8afe 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/RestPaths.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/RestPaths.java
@@ -50,7 +50,10 @@
* fragments: {@value}
*/
public static final String PUBLISHED_CONFIGURATION_REGEXP
- ="[a-z0-9][a-z0-9_\\+-]*";
-
-
+ = "[a-z0-9][a-z0-9_\\+-]*";
+
+ public static final String PUBLISHED_CONFIGURATION_SET_REGEXP
+ = "[a-z0-9][a-z0-9_.\\+-]*";
+
+ public static final String SLIDER_CONFIGSET = "slider";
}
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 fc487fe..b139f74 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
@@ -23,6 +23,8 @@
import org.apache.slider.core.registry.docstore.PublishedConfigSet;
import org.apache.slider.core.registry.docstore.PublishedConfiguration;
import org.apache.slider.core.registry.docstore.PublishedConfigurationOutputter;
+import org.apache.slider.core.registry.docstore.UriMap;
+import org.apache.slider.server.appmaster.state.StateAccessForProviders;
import org.apache.slider.server.appmaster.web.WebAppApi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,11 +50,15 @@
protected static final Logger log =
LoggerFactory.getLogger(PublisherResource.class);
private final WebAppApi slider;
+ public static final String SET_NAME =
+ "{setname: " + PUBLISHED_CONFIGURATION_SET_REGEXP + "}";
private static final String CONFIG =
- "{config: " + PUBLISHED_CONFIGURATION_REGEXP + "}";
-
+ SET_NAME + "/{config: " + PUBLISHED_CONFIGURATION_REGEXP + "}";
+ private final StateAccessForProviders appState;
+
public PublisherResource(WebAppApi slider) {
this.slider = slider;
+ appState = slider.getAppState();
}
private void init(HttpServletResponse res, UriInfo uriInfo) {
@@ -60,20 +66,51 @@
log.debug(uriInfo.getRequestUri().toString());
}
- private PublishedConfigSet getContent() {
- return slider.getAppState().getPublishedConfigurations();
+ /**
+ * Get a named config set
+ * @param setname name of the config set
+ * @return the config set
+ * @throws NotFoundException if there was no matching set
+ */
+ private PublishedConfigSet getConfigSet(String setname) {
+ PublishedConfigSet configSet =
+ appState.getPublishedConfigSet(setname);
+ if (configSet == null) {
+ throw new NotFoundException("Not found: " + setname);
+ }
+ return configSet;
}
@GET
@Path("/")
@Produces({MediaType.APPLICATION_JSON})
+ public UriMap enumConfigSets(
+ @Context UriInfo uriInfo,
+ @Context HttpServletResponse res) {
+ init(res, uriInfo);
+ String baseURL = uriInfo.getRequestUri().toString();
+ if (!baseURL.endsWith("/")) {
+ baseURL += "/";
+ }
+ UriMap uriMap = new UriMap();
+ for (String name : appState.listConfigSets()) {
+ uriMap.put(name, baseURL + name);
+ }
+ return uriMap;
+ }
+
+ @GET
+ @Path("/"+ SET_NAME)
+ @Produces({MediaType.APPLICATION_JSON})
public PublishedConfigSet getPublishedConfiguration(
+ @PathParam("setname") String setname,
@Context UriInfo uriInfo,
@Context HttpServletResponse res) {
init(res, uriInfo);
- PublishedConfigSet publishedConfigSet = getContent();
- log.debug("number of available configurations: {}", publishedConfigSet.size());
+ logRequest(uriInfo);
+ PublishedConfigSet publishedConfigSet = getConfigSet(setname);
+ log.debug("Number of configurations: {}", publishedConfigSet.size());
return publishedConfigSet.shallowCopy();
}
@@ -85,27 +122,43 @@
@Path("/" + CONFIG)
@Produces({MediaType.APPLICATION_JSON})
public PublishedConfiguration getConfigurationInstance(
+ @PathParam("setname") String setname,
@PathParam("config") String config,
@Context UriInfo uriInfo,
@Context HttpServletResponse res) {
init(res, uriInfo);
- PublishedConfiguration publishedConfig = getContent().get(config);
+ PublishedConfiguration publishedConfig =
+ getPublishedConfiguration(setname, config);
if (publishedConfig == null) {
log.info("Configuration {} not found", config);
throw new NotFoundException("Not found: " + uriInfo.getAbsolutePath());
}
return publishedConfig;
}
-
+
+ /**
+ * Get a configuration
+ * @param setname name of the config set
+ * @param config config
+ * @return null if there was a config, but not a set
+ * @throws NotFoundException if there was no matching set
+ */
+ public PublishedConfiguration getPublishedConfiguration(String setname,
+ String config) {
+ return getConfigSet(setname).get(config);
+ }
+
@GET
@Path("/" + CONFIG+ ".json")
@Produces({MediaType.APPLICATION_JSON})
public String getConfigurationContentJson(
+ @PathParam("setname") String setname,
+
@PathParam("config") String config,
@Context UriInfo uriInfo,
@Context HttpServletResponse res) throws IOException {
- return getStringRepresentation(config, uriInfo, res,
+ return getStringRepresentation(setname, config, uriInfo, res,
ConfigFormat.JSON);
}
@@ -113,10 +166,11 @@
@Path("/" + CONFIG + ".xml")
@Produces({MediaType.APPLICATION_XML})
public String getConfigurationContentXML(
+ @PathParam("setname") String setname,
@PathParam("config") String config,
@Context UriInfo uriInfo,
@Context HttpServletResponse res) throws IOException {
- return getStringRepresentation(config, uriInfo, res,
+ return getStringRepresentation(setname, config, uriInfo, res,
ConfigFormat.XML);
}
@@ -124,39 +178,43 @@
@Path("/" + CONFIG + ".properties")
@Produces({MediaType.APPLICATION_XML})
public String getConfigurationContentProperties(
+ @PathParam("setname") String setname,
+
@PathParam("config") String config,
@Context UriInfo uriInfo,
@Context HttpServletResponse res) throws IOException {
- return getStringRepresentation(config, uriInfo, res,
+ return getStringRepresentation(setname, config, uriInfo, res,
ConfigFormat.PROPERTIES);
}
- public String getStringRepresentation(String config,
+ public String getStringRepresentation(String setname,
+ String config,
UriInfo uriInfo,
HttpServletResponse res, ConfigFormat format) throws IOException {
// delegate (including init)
PublishedConfiguration publishedConfig =
- getConfigurationInstance(config, uriInfo, res);
+ getConfigurationInstance(setname, config, uriInfo, res);
PublishedConfigurationOutputter outputter =
publishedConfig.createOutputter(format);
return outputter.asString();
}
@GET
- @Path("/{config}/{propertyName}")
+ @Path("/" + CONFIG +"/{propertyName}")
@Produces({MediaType.APPLICATION_JSON})
public Map<String,String> getConfigurationProperty(
- @PathParam("propertyName") String propertyName,
+ @PathParam("setname") String setname,
@PathParam("config") String config,
+ @PathParam("propertyName") String propertyName,
@Context UriInfo uriInfo,
@Context HttpServletResponse res) {
PublishedConfiguration publishedConfig =
- getConfigurationInstance(config, uriInfo, res);
+ getConfigurationInstance(setname, config, uriInfo, res);
String propVal = publishedConfig.entries.get(propertyName);
if (propVal == null) {
- log.info("Configuration property {} not found in configuration {}",
- propertyName, config);
+ log.debug("Configuration property {} not found in configuration {}",
+ propertyName, config);
throw new NotFoundException("Property not found: " + propertyName);
}
Map<String,String> rtnVal = new HashMap<>();
diff --git a/slider-core/src/main/java/org/apache/slider/server/services/curator/CuratorService.java b/slider-core/src/main/java/org/apache/slider/server/services/curator/CuratorService.java
index b903fc7..657fa57 100644
--- a/slider-core/src/main/java/org/apache/slider/server/services/curator/CuratorService.java
+++ b/slider-core/src/main/java/org/apache/slider/server/services/curator/CuratorService.java
@@ -30,7 +30,7 @@
import java.io.Closeable;
public class CuratorService extends AbstractService {
- protected static final Logger log =
+ private static final Logger log =
LoggerFactory.getLogger(CuratorService.class);
protected final String basePath;
diff --git a/slider-core/src/main/java/org/apache/slider/server/services/curator/RegistryBinderService.java b/slider-core/src/main/java/org/apache/slider/server/services/curator/RegistryBinderService.java
index 29e9c7d..f4bd9bd 100644
--- a/slider-core/src/main/java/org/apache/slider/server/services/curator/RegistryBinderService.java
+++ b/slider-core/src/main/java/org/apache/slider/server/services/curator/RegistryBinderService.java
@@ -28,7 +28,6 @@
import org.apache.curator.x.discovery.ServiceType;
import org.apache.curator.x.discovery.UriSpec;
import org.apache.slider.core.exceptions.BadClusterStateException;
-import org.apache.slider.core.exceptions.UnknownApplicationInstanceException;
import org.apache.slider.core.persist.JsonSerDeser;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
@@ -49,7 +48,7 @@
* @param <Payload> the payload of the operation
*/
public class RegistryBinderService<Payload> extends CuratorService {
- protected static final Logger log =
+ private static final Logger log =
LoggerFactory.getLogger(RegistryBinderService.class);
private final ServiceDiscovery<Payload> discovery;
@@ -57,12 +56,13 @@
private final Map<String, ServiceInstance<Payload>> entries =
new HashMap<>();
- JsonSerDeser<CuratorServiceInstance<Payload>> deser =
+ private JsonSerDeser<CuratorServiceInstance<Payload>> deser =
new JsonSerDeser<>(CuratorServiceInstance.class);
/**
* Create an instance
- * @param curator. Again, does not need to be started
+ * @param curator Does not need to be started
+ * @param basePath base directory
* @param discovery discovery instance -not yet started
*/
public RegistryBinderService(CuratorFramework curator,
@@ -106,7 +106,6 @@
Payload payload) throws Exception {
Preconditions.checkNotNull(id, "null `id` arg");
Preconditions.checkNotNull(name, "null `name` arg");
- Preconditions.checkNotNull(url, "null `url` arg");
Preconditions.checkState(isInState(STATE.STARTED), "Not started: " + this);
if (lookup(id) != null) {
@@ -114,19 +113,24 @@
"existing entry for service id %s name %s %s",
id, name, url);
}
- int port = url.getPort();
- if (port == 0) {
- throw new IOException("Port undefined in " + url);
+
+ ServiceInstanceBuilder<Payload> instanceBuilder = builder()
+ .name(name)
+ .id(id)
+ .payload(payload)
+ .serviceType(ServiceType.DYNAMIC);
+ if (url != null) {
+ UriSpec uriSpec = new UriSpec(url.toString());
+
+ int port = url.getPort();
+ if (port == 0) {
+ throw new IOException("Port undefined in " + url);
+ }
+ instanceBuilder
+ .uriSpec(uriSpec)
+ .port(port);
}
- UriSpec uriSpec = new UriSpec(url.toString());
- ServiceInstance<Payload> instance = builder()
- .name(name)
- .id(id)
- .payload(payload)
- .port(port)
- .serviceType(ServiceType.DYNAMIC)
- .uriSpec(uriSpec)
- .build();
+ ServiceInstance<Payload> instance = instanceBuilder.build();
log.info("registering {}", instance.toString());
discovery.registerService(instance);
log.info("registration completed {}", instance.toString());
@@ -184,7 +188,7 @@
/**
* List all service types registered
- * @return
+ * @return a list of service types
* @throws Exception
*/
public List<String> serviceTypes() throws Exception {
@@ -296,7 +300,12 @@
return instances;
}
- public Collection<String> queryForNames() throws IOException {
+ /**
+ * Enum all service types in the registry
+ * @return a possibly empty collection of service types
+ * @throws IOException networking
+ */
+ public Collection<String> getServiceTypes() throws IOException {
try {
return getDiscovery().queryForNames();
} catch (IOException e) {
diff --git a/slider-core/src/main/java/org/apache/slider/server/services/registry/RegistryViewForProviders.java b/slider-core/src/main/java/org/apache/slider/server/services/registry/RegistryViewForProviders.java
index f50e9bd..e3d642b 100644
--- a/slider-core/src/main/java/org/apache/slider/server/services/registry/RegistryViewForProviders.java
+++ b/slider-core/src/main/java/org/apache/slider/server/services/registry/RegistryViewForProviders.java
@@ -21,6 +21,7 @@
import org.apache.slider.core.registry.info.ServiceInstanceData;
import java.io.IOException;
+import java.net.URL;
import java.util.List;
/**
@@ -35,4 +36,18 @@
* @return the registration of slider
*/
ServiceInstanceData getSelfRegistration();
+
+ /**
+ * Register the service, raising IOExceptions when anything fails
+ * @param serviceType service type
+ * @param instanceName ID -must be unique
+ * @param url URL to register
+ * @param instanceData instance data
+ * @throws IOException on registration problems
+ */
+ void registerServiceInstance(
+ String serviceType,
+ String instanceName,
+ URL url,
+ ServiceInstanceData instanceData) throws IOException;
}
diff --git a/slider-core/src/main/java/org/apache/slider/server/services/registry/SliderRegistryService.java b/slider-core/src/main/java/org/apache/slider/server/services/registry/SliderRegistryService.java
index d57db50..0d4a357 100644
--- a/slider-core/src/main/java/org/apache/slider/server/services/registry/SliderRegistryService.java
+++ b/slider-core/src/main/java/org/apache/slider/server/services/registry/SliderRegistryService.java
@@ -18,6 +18,7 @@
package org.apache.slider.server.services.registry;
+import com.google.common.base.Preconditions;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.slider.core.registry.info.ServiceInstanceData;
@@ -37,7 +38,7 @@
public class SliderRegistryService
extends RegistryBinderService<ServiceInstanceData>
implements RegistryViewForProviders {
-
+
private ServiceInstanceData selfRegistration;
public SliderRegistryService(CuratorFramework curator,
@@ -71,20 +72,29 @@
/**
* register an instance -only valid once the service is started.
* This sets the selfRegistration field
- * @param id ID -must be unique
- * @param name name
- * @param url URL
- * @param payload payload (may be null)
- * @return the instance
+ * @param serviceType service type
+ * @param instanceName ID -must be unique
+ * @param url URL to register
+ * @param instanceData instance data
* @throws IOException on registration problems
*/
- public void registerSelf(String name,
- String id,
+ public void registerSelf(String serviceType,
+ String instanceName,
URL url,
ServiceInstanceData instanceData) throws IOException {
+ registerServiceInstance(serviceType, instanceName, url, instanceData);
+ setSelfRegistration(instanceData);
+ }
+
+ @Override
+ public void registerServiceInstance(
+ String serviceType,
+ String instanceName,
+ URL url,
+ ServiceInstanceData instanceData) throws IOException {
+ Preconditions.checkNotNull(instanceData);
try {
- register(name, id, url, instanceData);
- setSelfRegistration(instanceData);
+ register(serviceType, instanceName, url, instanceData);
} catch (IOException e) {
throw e;
} catch (Exception e) {
diff --git a/slider-core/src/main/java/org/apache/slider/server/services/utility/PatternValidator.java b/slider-core/src/main/java/org/apache/slider/server/services/utility/PatternValidator.java
new file mode 100644
index 0000000..3542549
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/server/services/utility/PatternValidator.java
@@ -0,0 +1,49 @@
+/*
+ * 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.services.utility;
+
+import org.apache.slider.server.appmaster.web.rest.RestPaths;
+
+import java.util.regex.Pattern;
+
+public class PatternValidator {
+
+ public static final String E_INVALID_NAME =
+ "Invalid name %s does not match the pattern pattern %s ";
+ private final Pattern valid;
+ private final String pattern;
+
+ public PatternValidator(String pattern) {
+ this.pattern = pattern;
+ valid = Pattern.compile(pattern);
+ }
+
+ /**
+ * Validate the name -restricting it to the set defined in
+ * {@link RestPaths#PUBLISHED_CONFIGURATION_REGEXP}
+ * @param name name to validate
+ * @throws IllegalArgumentException if not a valid name
+ */
+ public void validate(String name) {
+ if (!valid.matcher(name).matches()) {
+ throw new IllegalArgumentException(
+ String.format(E_INVALID_NAME, name, pattern));
+ }
+ }
+}
diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy
index ab0c855..6794327 100644
--- a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy
+++ b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy
@@ -97,7 +97,7 @@
describe "service registry names"
SliderRegistryService registry = client.registry
- def names = registry.queryForNames();
+ def names = registry.getServiceTypes();
dumpRegistryNames(names)
describe "service registry instance IDs"
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 a548a64..7582b72 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
@@ -33,10 +33,12 @@
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.docstore.UriMap
import org.apache.slider.core.registry.info.CustomRegistryConstants
import org.apache.slider.core.registry.info.ServiceInstanceData
import org.apache.slider.core.registry.retrieve.RegistryRetriever
import org.apache.slider.server.appmaster.PublishedArtifacts
+import org.apache.slider.server.appmaster.web.rest.RestPaths
import org.apache.slider.server.services.curator.CuratorServiceInstance
import org.apache.slider.server.services.registry.SliderRegistryService
import org.junit.Test
@@ -112,8 +114,8 @@
describe "service registry names"
SliderRegistryService registryService = client.registry
- def names = registryService.queryForNames();
- dumpRegistryNames(names)
+ def serviceTypes = registryService.serviceTypes;
+ dumpRegistryNames(serviceTypes)
List<String> instanceIds = client.listRegistryInstanceIDs()
@@ -146,8 +148,14 @@
def publisher = publisherURL.toString()
describe("Publisher")
- def publishedJSON = GET(publisherURL)
-// log.info(publishedJSON)
+ JsonSerDeser<UriMap> uriMapDeser = new JsonSerDeser<>(UriMap)
+ def setlisting = GET(publisherURL)
+
+ log.info(setlisting)
+
+ UriMap uris = uriMapDeser.fromJson(setlisting)
+ assert uris.uris[RestPaths.SLIDER_CONFIGSET]
+ def publishedJSON = GET(publisherURL, RestPaths.SLIDER_CONFIGSET)
JsonSerDeser< PublishedConfigSet> serDeser= new JsonSerDeser<>(
PublishedConfigSet)
def configSet = serDeser.fromJson(publishedJSON)
@@ -158,7 +166,9 @@
assert publishedYarnSite.empty
//get the full URL
- def yarnSitePublisher = appendToURL(publisher, ARTIFACT_NAME)
+ def yarnSitePublisher = appendToURL(publisher,
+ RestPaths.SLIDER_CONFIGSET,
+ ARTIFACT_NAME)
String confJSON = GET(yarnSitePublisher)
// log.info(confJSON)
@@ -202,10 +212,7 @@
assert retriever.hasConfigurations(true)
PublishedConfigSet externalConfSet = retriever.getConfigurations(true)
- externalConfSet.keys().each { String key ->
- def config = externalConfSet.get(key)
- log.info "$key -- ${config.description}"
- }
+ dumpConfigurationSet(externalConfSet)
assert externalConfSet[ARTIFACT_NAME]
@@ -221,8 +228,6 @@
assert rmHostnameViaClientSideXML == rmHostnameFromDownloadedProperties
def rmAddrViaClientSideXML = siteXML.get(YarnConfiguration.RM_ADDRESS)
- //TODO SLIDER-52 PublishedConfiguration XML conf values are not resolved until client-side
-
log.info("RM from downloaded props = $rmAddrFromDownloadedProperties")
assert rmAddrViaClientSideXML == rmAddrFromDownloadedProperties
@@ -355,6 +360,4 @@
assert instances.size() == 0
}
-
-
}
diff --git a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestClusterSpecificationBlock.groovy b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestClusterSpecificationBlock.groovy
index ca3421b..4304452 100644
--- a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestClusterSpecificationBlock.groovy
+++ b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestClusterSpecificationBlock.groovy
@@ -31,6 +31,7 @@
import org.apache.slider.server.appmaster.model.mock.MockSliderClusterProtocol
import org.apache.slider.server.appmaster.state.AbstractRecordFactory
import org.apache.slider.server.appmaster.state.AppState
+import org.apache.slider.server.appmaster.state.ProviderAppState
import org.apache.slider.server.appmaster.web.WebAppApi
import org.apache.slider.server.appmaster.web.WebAppApiImpl
import org.junit.Before
@@ -46,9 +47,12 @@
public void setup() {
SliderClusterProtocol clusterProto = new MockSliderClusterProtocol();
AppState appState = new MyAppState(new MockRecordFactory());
+ ProviderAppState providerAppState = new ProviderAppState(
+ "undefined",
+ appState)
ProviderService providerService = new MockProviderService();
- WebAppApiImpl inst = new WebAppApiImpl(clusterProto, appState, providerService);
+ WebAppApiImpl inst = new WebAppApiImpl(clusterProto, providerAppState, providerService);
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
diff --git a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestContainerStatsBlock.groovy b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestContainerStatsBlock.groovy
index 2290dfa..69cdd2b 100644
--- a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestContainerStatsBlock.groovy
+++ b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestContainerStatsBlock.groovy
@@ -33,6 +33,7 @@
import org.apache.slider.providers.ProviderService
import org.apache.slider.server.appmaster.model.mock.*
import org.apache.slider.server.appmaster.state.AppState
+import org.apache.slider.server.appmaster.state.ProviderAppState
import org.apache.slider.server.appmaster.state.RoleInstance
import org.apache.slider.server.appmaster.web.WebAppApi
import org.apache.slider.server.appmaster.web.WebAppApiImpl
@@ -56,8 +57,11 @@
SliderClusterProtocol clusterProto = new MockSliderClusterProtocol();
AppState appState = new MockAppState(new MockRecordFactory());
ProviderService providerService = new MockProviderService();
+ ProviderAppState providerAppState = new ProviderAppState(
+ "undefined",
+ appState)
- WebAppApiImpl inst = new WebAppApiImpl(clusterProto, appState, providerService);
+ WebAppApiImpl inst = new WebAppApiImpl(clusterProto, providerAppState, providerService);
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
diff --git a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestIndexBlock.groovy b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestIndexBlock.groovy
index 0311eaa..176299d 100644
--- a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestIndexBlock.groovy
+++ b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestIndexBlock.groovy
@@ -28,6 +28,7 @@
import org.apache.slider.providers.ProviderService
import org.apache.slider.server.appmaster.model.mock.*
import org.apache.slider.server.appmaster.state.AppState
+import org.apache.slider.server.appmaster.state.ProviderAppState
import org.apache.slider.server.appmaster.web.WebAppApi
import org.apache.slider.server.appmaster.web.WebAppApiImpl
import org.junit.Before
@@ -46,8 +47,11 @@
SliderClusterProtocol clusterProto = new MockSliderClusterProtocol();
AppState appState = new MockAppState(new MockRecordFactory());
ProviderService providerService = new MockProviderService();
+ ProviderAppState providerAppState = new ProviderAppState(
+ "undefined",
+ appState)
- WebAppApiImpl inst = new WebAppApiImpl(clusterProto, appState, providerService);
+ WebAppApiImpl inst = new WebAppApiImpl(clusterProto, providerAppState, providerService);
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
diff --git a/slider-core/src/test/groovy/org/apache/slider/test/SliderTestUtils.groovy b/slider-core/src/test/groovy/org/apache/slider/test/SliderTestUtils.groovy
index c6e1f0e..8588a53 100644
--- a/slider-core/src/test/groovy/org/apache/slider/test/SliderTestUtils.groovy
+++ b/slider-core/src/test/groovy/org/apache/slider/test/SliderTestUtils.groovy
@@ -44,6 +44,7 @@
import org.apache.slider.core.main.ServiceLaunchException
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.info.ServiceInstanceData
import org.apache.slider.server.services.curator.CuratorServiceInstance
import org.junit.Assert
@@ -377,6 +378,10 @@
return SliderUtils.appendToURL(base, path)
}
+ public static String appendToURL(String base, String... paths) {
+ return SliderUtils.appendToURL(base, paths)
+ }
+
/**
* Fetch a web page
* @param url URL
@@ -718,4 +723,11 @@
}
return time;
}
+
+ def dumpConfigurationSet(PublishedConfigSet confSet) {
+ confSet.keys().each { String key ->
+ def config = confSet.get(key)
+ log.info "$key -- ${config.description}"
+ }
+ }
}
diff --git a/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java b/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
index 6ef77aa..11339c1 100644
--- a/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
+++ b/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
@@ -18,9 +18,6 @@
package org.apache.slider.providers.agent;
-import org.apache.slider.server.appmaster.web.rest.agent.CommandReport;
-import org.junit.Assert;
-import org.junit.Test;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FilterFileSystem;
import org.apache.hadoop.fs.Path;
@@ -56,14 +53,16 @@
import org.apache.slider.server.appmaster.model.mock.MockContainerId;
import org.apache.slider.server.appmaster.model.mock.MockFileSystem;
import org.apache.slider.server.appmaster.model.mock.MockNodeId;
-import org.apache.slider.server.appmaster.state.AppState;
+import org.apache.slider.server.appmaster.state.ProviderAppState;
import org.apache.slider.server.appmaster.state.StateAccessForProviders;
+import org.apache.slider.server.appmaster.web.rest.agent.CommandReport;
import org.apache.slider.server.appmaster.web.rest.agent.ComponentStatus;
import org.apache.slider.server.appmaster.web.rest.agent.HeartBeat;
import org.apache.slider.server.appmaster.web.rest.agent.HeartBeatResponse;
import org.apache.slider.server.appmaster.web.rest.agent.Register;
import org.apache.slider.server.appmaster.web.rest.agent.RegistrationResponse;
import org.apache.slider.server.appmaster.web.rest.agent.RegistrationStatus;
+import org.junit.Assert;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@@ -204,7 +203,7 @@
StateAccessForProviders access = createNiceMock(StateAccessForProviders.class);
AgentProviderService mockAps = Mockito.spy(aps);
- doReturn(access).when(mockAps).getStateAccessor();
+ doReturn(access).when(mockAps).getAmState();
doReturn("scripts/hbase_master.py").when(mockAps).getScriptPathFromMetainfo(anyString());
Metainfo metainfo = new Metainfo();
metainfo.addService(new Service());
@@ -244,10 +243,8 @@
resourceComponent,
appComponent,
containerTmpDirPath);
- } catch (SliderException he) {
- log.warn(he.getMessage());
- } catch (IOException ioe) {
- log.warn(ioe.getMessage());
+ } catch (SliderException | IOException he) {
+ log.warn("{}", he, he);
}
Register reg = new Register();
@@ -267,7 +264,7 @@
@Test
public void testRoleHostMapping() throws Exception {
AgentProviderService aps = new AgentProviderService();
- StateAccessForProviders appState = new AppState(null) {
+ StateAccessForProviders appState = new ProviderAppState("undefined", null) {
@Override
public ClusterDescription getClusterStatus() {
ClusterDescription cd = new ClusterDescription();
@@ -304,8 +301,8 @@
}
};
- aps.setStateAccessor(appState);
- Map<String, String> tokens = new HashMap<String, String>();
+ aps.setAmState(appState);
+ Map<String, String> tokens = new HashMap<>();
aps.addRoleRelatedTokens(tokens);
Assert.assertEquals(2, tokens.size());
Assert.assertEquals("FIRST_HOST", tokens.get("${FIRST_ROLE_HOST}"));
@@ -486,7 +483,7 @@
StateAccessForProviders access = createNiceMock(StateAccessForProviders.class);
AgentProviderService mockAps = Mockito.spy(aps);
- doReturn(access).when(mockAps).getStateAccessor();
+ doReturn(access).when(mockAps).getAmState();
doReturn(metainfo).when(mockAps).getApplicationMetainfo(any(SliderFileSystem.class), anyString());
try {
@@ -662,10 +659,8 @@
anyString(),
any(HeartBeatResponse.class),
anyString());
- } catch (SliderException he) {
+ } catch (SliderException | IOException he) {
log.warn(he.getMessage());
- } catch (IOException ioe) {
- log.warn(ioe.getMessage());
}
}
@@ -677,7 +672,7 @@
StateAccessForProviders access = createNiceMock(StateAccessForProviders.class);
AgentProviderService mockAps = Mockito.spy(aps);
- doReturn(access).when(mockAps).getStateAccessor();
+ doReturn(access).when(mockAps).getAmState();
AggregateConf aggConf = new AggregateConf();
ConfTreeOperations treeOps = aggConf.getAppConfOperations();
diff --git a/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/agent/TestAMAgentWebServices.java b/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/agent/TestAMAgentWebServices.java
index f6155c9..75ee7db 100644
--- a/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/agent/TestAMAgentWebServices.java
+++ b/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/agent/TestAMAgentWebServices.java
@@ -43,6 +43,7 @@
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.web.WebAppApi;
import org.apache.slider.server.appmaster.web.WebAppApiImpl;
import org.apache.slider.server.appmaster.web.rest.AMWebServices;
@@ -138,7 +139,10 @@
} catch (Exception e) {
log.error("Failed to set up app {}", e);
}
- slider = new WebAppApiImpl(new MockSliderClusterProtocol(), appState,
+ ProviderAppState providerAppState = new ProviderAppState("undefined",
+ appState);
+
+ slider = new WebAppApiImpl(new MockSliderClusterProtocol(), providerAppState,
new MockProviderService());
bind(SliderJacksonJaxbJsonProvider.class);
diff --git a/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/management/TestAMManagementWebServices.java b/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/management/TestAMManagementWebServices.java
index a3256ca..c958081 100644
--- a/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/management/TestAMManagementWebServices.java
+++ b/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/management/TestAMManagementWebServices.java
@@ -43,6 +43,7 @@
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.web.WebAppApi;
import org.apache.slider.server.appmaster.web.WebAppApiImpl;
import org.apache.slider.server.appmaster.web.rest.AMWebServices;
@@ -51,6 +52,8 @@
import org.codehaus.jettison.json.JSONObject;
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;
@@ -64,7 +67,8 @@
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 =
@@ -169,16 +173,13 @@
fs,
historyPath,
null, null);
- } catch (IOException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- } catch (URISyntaxException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- } catch (BadClusterStateException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- } catch (BadConfigException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ } catch (IOException | BadClusterStateException | URISyntaxException | BadConfigException e) {
+ log.error("{}", e, e);
}
- slider = new WebAppApiImpl(new MockSliderClusterProtocol(), appState,
+ ProviderAppState providerAppState = new ProviderAppState("undefined",
+ appState);
+
+ slider = new WebAppApiImpl(new MockSliderClusterProtocol(), providerAppState,
new MockProviderService());
bind(SliderJacksonJaxbJsonProvider.class);
diff --git a/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/TestClusterLifecycle.groovy b/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/TestAgentClusterLifecycle.groovy
similarity index 96%
rename from slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/TestClusterLifecycle.groovy
rename to slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/TestAgentClusterLifecycle.groovy
index afbe5c6..7769ce1 100644
--- a/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/TestClusterLifecycle.groovy
+++ b/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/TestAgentClusterLifecycle.groovy
@@ -34,11 +34,11 @@
@CompileStatic
@Slf4j
-public class TestClusterLifecycle extends AgentCommandTestBase
+public class TestAgentClusterLifecycle extends AgentCommandTestBase
implements FuntestProperties, Arguments, SliderExitCodes {
- static String CLUSTER = "test_cluster_lifecycle"
+ static String CLUSTER = "test_agent_cluster_lifecycle"
@Before
@@ -52,7 +52,7 @@
}
@Test
- public void testClusterLifecycle() throws Throwable {
+ public void testAgentClusterLifecycle() throws Throwable {
describe "Walk a 0-role cluster through its lifecycle"
diff --git a/slider-providers/accumulo/slider-accumulo-provider/src/main/java/org/apache/slider/providers/accumulo/AccumuloProviderService.java b/slider-providers/accumulo/slider-accumulo-provider/src/main/java/org/apache/slider/providers/accumulo/AccumuloProviderService.java
index 904514d..8396ff1 100644
--- a/slider-providers/accumulo/slider-accumulo-provider/src/main/java/org/apache/slider/providers/accumulo/AccumuloProviderService.java
+++ b/slider-providers/accumulo/slider-accumulo-provider/src/main/java/org/apache/slider/providers/accumulo/AccumuloProviderService.java
@@ -126,7 +126,6 @@
Path containerTmpDirPath) throws IOException, SliderException {
this.fileSystem = fileSystem;
- this.instanceDefinition = instanceDefinition;
// Set the environment
launcher.putEnv(SliderUtils.buildEnvMap(appComponent));
diff --git a/slider-providers/hbase/slider-hbase-provider/src/main/java/org/apache/slider/providers/hbase/HBaseKeys.java b/slider-providers/hbase/slider-hbase-provider/src/main/java/org/apache/slider/providers/hbase/HBaseKeys.java
index fc7305a..af799c0 100644
--- a/slider-providers/hbase/slider-hbase-provider/src/main/java/org/apache/slider/providers/hbase/HBaseKeys.java
+++ b/slider-providers/hbase/slider-hbase-provider/src/main/java/org/apache/slider/providers/hbase/HBaseKeys.java
@@ -67,8 +67,11 @@
String HBASE_LOG_DIR = "HBASE_LOG_DIR";
String HBASE_HEAPSIZE = "HBASE_HEAPSIZE";
- String HBASE_GC_OPTS = "SERVER_GC_OPTS";
+ String HBASE_GC_OPTS = "SERVER_GC_OPTS";
+ String PROPAGATED_CONFDIR = "PROPAGATED_CONFDIR";
+ String HBASE_SERVICE_TYPE = "org.apache.hbase";
+ String HBASE_SITE_PUBLISHED_CONFIG = "hbase-site";
}
diff --git a/slider-providers/hbase/slider-hbase-provider/src/main/java/org/apache/slider/providers/hbase/HBaseProviderService.java b/slider-providers/hbase/slider-hbase-provider/src/main/java/org/apache/slider/providers/hbase/HBaseProviderService.java
index c63c26b..236ec62 100644
--- a/slider-providers/hbase/slider-hbase-provider/src/main/java/org/apache/slider/providers/hbase/HBaseProviderService.java
+++ b/slider-providers/hbase/slider-hbase-provider/src/main/java/org/apache/slider/providers/hbase/HBaseProviderService.java
@@ -34,6 +34,9 @@
import org.apache.slider.core.exceptions.BadCommandArgumentsException;
import org.apache.slider.core.exceptions.SliderException;
import org.apache.slider.core.exceptions.SliderInternalStateException;
+import org.apache.slider.core.registry.docstore.PublishedConfigSet;
+import org.apache.slider.core.registry.docstore.PublishedConfiguration;
+import org.apache.slider.core.registry.info.ServiceInstanceData;
import org.apache.slider.providers.AbstractProviderService;
import org.apache.slider.providers.ProviderCore;
import org.apache.slider.providers.ProviderRole;
@@ -58,6 +61,8 @@
import java.util.List;
import java.util.Map;
+import static org.apache.slider.server.appmaster.web.rest.RestPaths.SLIDER_PATH_PUBLISHER;
+
/**
* This class implements the server-side aspects
* of an HBase Cluster
@@ -73,7 +78,6 @@
private static final ProviderUtils providerUtils = new ProviderUtils(log);
private HBaseClientProvider clientProvider;
private Configuration siteConf;
- private SliderFileSystem sliderFileSystem = null;
public HBaseProviderService() {
super("HBaseProviderService");
@@ -101,7 +105,7 @@
/**
* Validate the cluster specification. This can be invoked on both
* server and client
- * @param instanceDefinition
+ * @param instanceDefinition the instance definition to validate
*/
@Override // Client and Server
public void validateInstanceDefinition(AggregateConf instanceDefinition) throws
@@ -114,20 +118,18 @@
AggregateConf instanceDefinition,
Container container,
String role,
- SliderFileSystem sliderFileSystem,
+ SliderFileSystem coreFS,
Path generatedConfPath,
MapOperations resourceComponent,
MapOperations appComponent,
Path containerTmpDirPath) throws IOException, SliderException {
- this.sliderFileSystem = sliderFileSystem;
- this.instanceDefinition = instanceDefinition;
// Set the environment
launcher.putEnv(SliderUtils.buildEnvMap(appComponent));
launcher.setEnv(HBASE_LOG_DIR, providerUtils.getLogdir());
- launcher.setEnv("PROPAGATED_CONFDIR",
+ launcher.setEnv(PROPAGATED_CONFDIR,
ProviderUtils.convertToAppRelativePath(
SliderKeys.PROPAGATED_CONF_DIR_NAME) );
@@ -135,13 +137,14 @@
//local resources
//add the configuration resources
- launcher.addLocalResources(sliderFileSystem.submitDirectory(
+ launcher.addLocalResources(coreFS.submitDirectory(
generatedConfPath,
SliderKeys.PROPAGATED_CONF_DIR_NAME));
//Add binaries
//now add the image if it was set
- String imageURI = instanceDefinition.getInternalOperations().get(OptionKeys.INTERNAL_APPLICATION_IMAGE_PATH);
- sliderFileSystem.maybeAddImagePath(launcher.getLocalResources(), imageURI);
+ String imageURI = instanceDefinition.getInternalOperations()
+ .get(OptionKeys.INTERNAL_APPLICATION_IMAGE_PATH);
+ coreFS.maybeAddImagePath(launcher.getLocalResources(), imageURI);
CommandLineBuilder cli = new CommandLineBuilder();
@@ -191,6 +194,44 @@
}
+ @Override
+ public void applyInitialRegistryDefinitions(URL web,
+ ServiceInstanceData instanceData) throws
+ IOException {
+ super.applyInitialRegistryDefinitions(web, instanceData);
+ }
+
+ @Override
+ protected void serviceStart() throws Exception {
+ registerHBaseServiceEntry();
+
+
+ super.serviceStart();
+ }
+
+ private void registerHBaseServiceEntry() throws IOException {
+
+ // not a URL, but needed
+ URL hbaseURL = new URL("http://localhost:0");
+ ServiceInstanceData instanceData = new ServiceInstanceData();
+ PublishedConfiguration publishedSite =
+ new PublishedConfiguration("HBase site",
+ siteConf);
+ PublishedConfigSet configSet =
+ amState.getOrCreatePublishedConfigSet(HBASE_SERVICE_TYPE);
+ instanceData.externalView.configurationsURL = SliderUtils.appendToURL(
+ amWebAPI.toExternalForm(), SLIDER_PATH_PUBLISHER, HBASE_SERVICE_TYPE);
+ configSet.put(HBASE_SITE_PUBLISHED_CONFIG,
+ publishedSite);
+ String name = amState.getApplicationName()+".hbase";
+ log.info("registering {}/{}", name, HBASE_SERVICE_TYPE);
+ registry.registerServiceInstance(HBASE_SERVICE_TYPE,
+ name,
+ null,
+ instanceData
+ );
+ }
+
/**
* Run this service
*
@@ -292,4 +333,6 @@
response.setResponseId(id + 1L);
return response;
}
+
+
}
diff --git a/slider-providers/hbase/slider-hbase-provider/src/test/groovy/org/apache/slider/providers/hbase/minicluster/live/TestHBaseMaster.groovy b/slider-providers/hbase/slider-hbase-provider/src/test/groovy/org/apache/slider/providers/hbase/minicluster/live/TestHBaseMaster.groovy
index 55ff38a..01996ee 100644
--- a/slider-providers/hbase/slider-hbase-provider/src/test/groovy/org/apache/slider/providers/hbase/minicluster/live/TestHBaseMaster.groovy
+++ b/slider-providers/hbase/slider-hbase-provider/src/test/groovy/org/apache/slider/providers/hbase/minicluster/live/TestHBaseMaster.groovy
@@ -20,19 +20,20 @@
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
-import org.apache.hadoop.hbase.ClusterStatus
-import org.apache.slider.common.SliderExitCodes
import org.apache.slider.common.SliderXmlConfKeys
import org.apache.slider.api.ClusterDescription
import org.apache.slider.api.RoleKeys
-import org.apache.slider.core.conf.AggregateConf
+import org.apache.slider.core.registry.docstore.PublishedConfigSet
+import org.apache.slider.core.registry.info.ServiceInstanceData
+import org.apache.slider.core.registry.retrieve.RegistryRetriever
import org.apache.slider.providers.hbase.HBaseKeys
import org.apache.slider.core.registry.zk.ZKIntegration
import org.apache.slider.common.params.Arguments
import org.apache.slider.client.SliderClient
import org.apache.slider.providers.hbase.minicluster.HBaseMiniClusterTestBase
-import org.apache.slider.core.main.ServiceLaunchException
import org.apache.slider.core.main.ServiceLauncher
+import org.apache.slider.server.services.curator.CuratorServiceInstance
+import org.apache.slider.server.services.registry.SliderRegistryService
import org.junit.Test
/**
@@ -41,6 +42,7 @@
@CompileStatic
@Slf4j
class TestHBaseMaster extends HBaseMiniClusterTestBase {
+ public static final String HBASE_SITE = HBaseKeys.HBASE_SITE_PUBLISHED_CONFIG;
@Test
public void testHBaseMaster() throws Throwable {
@@ -57,22 +59,49 @@
],
true,
true)
- SliderClient sliderClient = launcher.service
- addToTeardown(sliderClient);
- ClusterDescription status = sliderClient.getClusterDescription(clustername)
+ SliderClient client = launcher.service
+ addToTeardown(client);
+ ClusterDescription status = client.getClusterDescription(clustername)
//dumpFullHBaseConf(sliderClient, clustername)
- basicHBaseClusterStartupSequence(sliderClient)
+ basicHBaseClusterStartupSequence(client)
//verify the #of region servers is as expected
- dumpClusterStatus(sliderClient, "post-hbase-boot status")
+ dumpClusterStatus(client, "post-hbase-boot status")
//get the hbase status
- waitForHBaseRegionServerCount(sliderClient, clustername, 1, hbaseClusterStartupToLiveTime)
- waitForWorkerInstanceCount(sliderClient, 1, hbaseClusterStartupToLiveTime)
- waitForRoleCount(sliderClient, HBaseKeys.ROLE_MASTER, 1,
+ waitForHBaseRegionServerCount(client, clustername, 1, hbaseClusterStartupToLiveTime)
+ waitForWorkerInstanceCount(client, 1, hbaseClusterStartupToLiveTime)
+ waitForRoleCount(client, HBaseKeys.ROLE_MASTER, 1,
hbaseClusterStartupToLiveTime)
+
+ // look up the registry entries for HBase
+ describe "service registry names"
+ SliderRegistryService registryService = client.registry
+ def names = registryService.getServiceTypes();
+ dumpRegistryNames(names)
+
+ List<CuratorServiceInstance<ServiceInstanceData>> instances =
+ client.listRegistryInstances();
+ def hbaseService = registryService.findByID(
+ instances,
+ HBaseKeys.HBASE_SERVICE_TYPE)
+ assert hbaseService
+ RegistryRetriever retriever = new RegistryRetriever(hbaseService.payload)
+ log.info retriever.toString()
+ assert retriever.hasConfigurations(true)
+ PublishedConfigSet externalConfSet = retriever.getConfigurations(true)
+ dumpConfigurationSet(externalConfSet)
+ assert externalConfSet[HBASE_SITE]
+
+
+ def yarnSite = retriever.retrieveConfiguration(
+ externalConfSet,
+ HBASE_SITE,
+ true)
+ assert !yarnSite.empty
+ def siteXML = yarnSite.asConfiguration()
}
}
diff --git a/slider-providers/hbase/slider-hbase-provider/src/test/groovy/org/apache/slider/providers/hbase/minicluster/live/TestTwoLiveClusters.groovy b/slider-providers/hbase/slider-hbase-provider/src/test/groovy/org/apache/slider/providers/hbase/minicluster/live/TestTwoLiveClusters.groovy
index 22d2018..dba52ba 100644
--- a/slider-providers/hbase/slider-hbase-provider/src/test/groovy/org/apache/slider/providers/hbase/minicluster/live/TestTwoLiveClusters.groovy
+++ b/slider-providers/hbase/slider-hbase-provider/src/test/groovy/org/apache/slider/providers/hbase/minicluster/live/TestTwoLiveClusters.groovy
@@ -82,7 +82,7 @@
// registry instances def names = client.listRegistryNames(clustername)
describe "service registry names"
SliderRegistryService registry = cluster2Client.registry
- def names = registry.queryForNames();
+ def names = registry.getServiceTypes();
dumpRegistryNames(names)
List<String> instanceIds = sliderClient.listRegistryInstanceIDs()