package org.apache.helix.webapp.resources;
/*
* 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.
*/
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.apache.helix.HelixAdmin;
import org.apache.helix.HelixException;
import org.apache.helix.ZNRecord;
import org.apache.helix.manager.zk.ZkClient;
import org.apache.helix.model.HelixConfigScope;
import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
import org.apache.helix.model.builder.HelixConfigScopeBuilder;
import org.apache.helix.tools.ClusterSetup;
import org.apache.helix.webapp.RestAdminApplication;
import org.apache.log4j.Logger;
import org.restlet.data.MediaType;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.representation.Variant;
import org.restlet.resource.ServerResource;
public class ConfigResource extends ServerResource {
private final static Logger LOG = Logger.getLogger(ConfigResource.class);
public ConfigResource() {
getVariants().add(new Variant(MediaType.TEXT_PLAIN));
getVariants().add(new Variant(MediaType.APPLICATION_JSON));
setNegotiated(false);
}
String getValue(String key) {
return (String) getRequest().getAttributes().get(key);
}
static StringRepresentation getConfigScopes() throws Exception {
StringRepresentation representation = null;
ZNRecord record = new ZNRecord("Config");
List<String> scopeList =
Arrays.asList(ConfigScopeProperty.CLUSTER.toString(),
ConfigScopeProperty.RESOURCE.toString(), ConfigScopeProperty.PARTICIPANT.toString(),
ConfigScopeProperty.PARTITION.toString());
record.setListField("scopes", scopeList);
representation =
new StringRepresentation(ClusterRepresentationUtil.ZNRecordToJson(record),
MediaType.APPLICATION_JSON);
return representation;
}
StringRepresentation getConfigKeys(ConfigScopeProperty scopeProperty, String... keys)
throws Exception {
StringRepresentation representation = null;
// String clusterName = getValue("clusterName");
ZkClient zkClient = (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
ClusterSetup setupTool = new ClusterSetup(zkClient);
HelixAdmin admin = setupTool.getClusterManagementTool();
ZNRecord record = new ZNRecord(scopeProperty + " Config");
HelixConfigScope scope = new HelixConfigScopeBuilder(scopeProperty, keys).build();
// List<String> configKeys = admin.getConfigKeys(scopeProperty, clusterName, keys);
List<String> configKeys = admin.getConfigKeys(scope);
record.setListField(scopeProperty.toString(), configKeys);
representation =
new StringRepresentation(ClusterRepresentationUtil.ZNRecordToJson(record),
MediaType.APPLICATION_JSON);
return representation;
}
StringRepresentation getConfigs(// ConfigScope scope,
ConfigScopeProperty scopeProperty, String... keys) throws Exception {
StringRepresentation representation = null;
// String clusterName = getValue("clusterName");
ZkClient zkClient = (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
ClusterSetup setupTool = new ClusterSetup(zkClient);
HelixAdmin admin = setupTool.getClusterManagementTool();
ZNRecord record = new ZNRecord(scopeProperty + " Config");
HelixConfigScope scope = new HelixConfigScopeBuilder(scopeProperty, keys).build();
List<String> configKeys = admin.getConfigKeys(scope);
Map<String, String> configs = admin.getConfig(scope, configKeys);
record.setSimpleFields(configs);
representation =
new StringRepresentation(ClusterRepresentationUtil.ZNRecordToJson(record),
MediaType.APPLICATION_JSON);
return representation;
}
@Override
public Representation get() {
StringRepresentation representation = null;
String clusterName = getValue("clusterName");
String scopeStr = getValue("scope");
try {
if (scopeStr == null) {
// path is "/clusters/{clusterName}/configs"
return getConfigScopes();
}
scopeStr = scopeStr.toUpperCase();
ConfigScopeProperty scopeProperty = ConfigScopeProperty.valueOf(scopeStr);
switch (scopeProperty) {
case CLUSTER:
case PARTICIPANT:
case RESOURCE:
String scopeKey1 = getValue("scopeKey1");
if (scopeKey1 == null) {
// path is "/clusters/{clusterName}/configs/cluster|participant|resource"
representation = getConfigKeys(scopeProperty, clusterName);
} else {
// path is "/clusters/{clusterName}/configs/cluster|participant|resource/
// {clusterName}|{participantName}|{resourceName}"
// ConfigScope scope;
// if (scopeProperty == ConfigScopeProperty.CLUSTER)
// {
// scope = new ConfigScopeBuilder().build(scopeProperty, clusterName);
// }
// else
// {
// scope = new ConfigScopeBuilder().build(scopeProperty, clusterName, scopeKey1);
// }
representation = getConfigs(scopeProperty, clusterName, scopeKey1);
}
break;
case PARTITION:
scopeKey1 = getValue("scopeKey1");
String scopeKey2 = getValue("scopeKey2");
if (scopeKey1 == null) {
// path is "/clusters/{clusterName}/configs/partition"
throw new HelixException("Missing resourceName");
} else if (scopeKey2 == null) {
// path is "/clusters/{clusterName}/configs/partition/resourceName"
representation = getConfigKeys(scopeProperty, clusterName, scopeKey1);
} else {
// path is
// "/clusters/{clusterName}/configs/partition/resourceName/partitionName"
// ConfigScope scope =
// new ConfigScopeBuilder().build(scopeProperty,
// clusterName,
// scopeKey1,
// scopeKey2);
representation = getConfigs(scopeProperty, clusterName, scopeKey1, scopeKey2);
}
break;
default:
break;
}
} catch (Exception e) {
String error = ClusterRepresentationUtil.getErrorAsJsonStringFromException(e);
representation = new StringRepresentation(error, MediaType.APPLICATION_JSON);
LOG.error("", e);
}
return representation;
}
/**
* set or remove configs depends on "command" field of jsonParameters in POST body
* @param entity
* @param scopeStr
* @throws Exception
*/
void setConfigs(Representation entity, ConfigScopeProperty type, String scopeArgs)
throws Exception {
JsonParameters jsonParameters = new JsonParameters(entity);
String command = jsonParameters.getCommand();
ZkClient zkClient = (ZkClient) getContext().getAttributes().get(RestAdminApplication.ZKCLIENT);
ClusterSetup setupTool = new ClusterSetup(zkClient);
if (command.equalsIgnoreCase(ClusterSetup.setConfig)) {
jsonParameters.verifyCommand(ClusterSetup.setConfig);
String propertiesStr = jsonParameters.getParameter(JsonParameters.CONFIGS);
// setupTool.setConfig(scopeStr, propertiesStr);
setupTool.setConfig(type, scopeArgs, propertiesStr);
} else if (command.equalsIgnoreCase(ClusterSetup.removeConfig)) {
jsonParameters.verifyCommand(ClusterSetup.removeConfig);
String propertiesStr = jsonParameters.getParameter(JsonParameters.CONFIGS);
setupTool.removeConfig(type, scopeArgs, propertiesStr);
} else {
throw new HelixException("Unsupported command: " + command + ". Should be one of ["
+ ClusterSetup.setConfig + ", " + ClusterSetup.removeConfig + "]");
}
getResponse().setEntity(get());
getResponse().setStatus(Status.SUCCESS_OK);
}
@Override
public Representation post(Representation entity) {
String clusterName = getValue("clusterName");
String scopeStr = getValue("scope").toUpperCase();
try {
ConfigScopeProperty scopeProperty = ConfigScopeProperty.valueOf(scopeStr);
switch (scopeProperty) {
case CLUSTER:
String scopeArgs = clusterName;
setConfigs(entity, scopeProperty, scopeArgs);
break;
case PARTICIPANT:
case RESOURCE:
String scopeKey1 = getValue("scopeKey1");
if (scopeKey1 == null) {
throw new HelixException("Missing resourceName|participantName");
} else {
scopeArgs = clusterName + "," + scopeKey1;
setConfigs(entity, scopeProperty, scopeArgs);
}
break;
case PARTITION:
scopeKey1 = getValue("scopeKey1");
String scopeKey2 = getValue("scopeKey2");
if (scopeKey1 == null || scopeKey2 == null) {
throw new HelixException("Missing resourceName|partitionName");
} else {
scopeArgs = clusterName + "," + scopeKey1 + "," + scopeKey2;
setConfigs(entity, scopeProperty, scopeArgs);
}
break;
default:
break;
}
} catch (Exception e) {
LOG.error("Error in posting " + entity, e);
getResponse().setEntity(ClusterRepresentationUtil.getErrorAsJsonStringFromException(e),
MediaType.APPLICATION_JSON);
getResponse().setStatus(Status.SUCCESS_OK);
}
return null;
}
}