in ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java [403:638]
private void populateEntity(AlertDefinitionEntity entity,
Map<String, Object> requestMap) throws AmbariException, AuthorizationException {
// some fields are required on creation; on update we keep what's there
boolean bCreate = true;
if (null != entity.getDefinitionId()) {
bCreate = false;
}
String clusterName = (String) requestMap.get(ALERT_DEF_CLUSTER_NAME);
String definitionName = (String) requestMap.get(ALERT_DEF_NAME);
String serviceName = (String) requestMap.get(ALERT_DEF_SERVICE_NAME);
String componentName = (String) requestMap.get(ALERT_DEF_COMPONENT_NAME);
String type = (String) requestMap.get(ALERT_DEF_SOURCE_TYPE);
String label = (String) requestMap.get(ALERT_DEF_LABEL);
String helpURL = (String) requestMap.get(ALERT_DEF_HELP_URL);
String description = (String) requestMap.get(ALERT_DEF_DESCRIPTION);
String desiredScope = (String) requestMap.get(ALERT_DEF_SCOPE);
Integer interval = null;
if (requestMap.containsKey(ALERT_DEF_INTERVAL)) {
interval = Integer.valueOf((String) requestMap.get(ALERT_DEF_INTERVAL));
}
Boolean enabled = null;
if (requestMap.containsKey(ALERT_DEF_ENABLED)) {
enabled = Boolean.parseBoolean((String) requestMap.get(ALERT_DEF_ENABLED));
} else if (bCreate) {
enabled = Boolean.TRUE;
}
Boolean ignoreHost = null;
if (requestMap.containsKey(ALERT_DEF_IGNORE_HOST)) {
ignoreHost = Boolean.parseBoolean((String) requestMap.get(ALERT_DEF_IGNORE_HOST));
} else if (bCreate) {
ignoreHost = Boolean.FALSE;
}
Scope scope = null;
if (null != desiredScope && desiredScope.length() > 0) {
scope = Scope.valueOf(desiredScope);
}
SourceType sourceType = null;
if (null != type && type.length() > 0) {
sourceType = SourceType.valueOf(type);
}
// if not specified when creating an alert definition, the scope is
// assumed to be ANY
if (null == scope && bCreate) {
scope = Scope.ANY;
}
Integer repeatTolerance = null;
if (requestMap.containsKey(ALERT_DEF_REPEAT_TOLERANCE)) {
repeatTolerance = Integer.valueOf((String) requestMap.get(ALERT_DEF_REPEAT_TOLERANCE));
}
Boolean repeatToleranceEnabled = null;
if (requestMap.containsKey(ALERT_DEF_REPEAT_TOLERANCE_ENABLED)) {
repeatToleranceEnabled = Boolean.valueOf(
requestMap.get(ALERT_DEF_REPEAT_TOLERANCE_ENABLED).toString());
}
if (StringUtils.isEmpty(clusterName)) {
throw new IllegalArgumentException(
"Invalid argument, cluster name is required");
}
if (bCreate && !requestMap.containsKey(ALERT_DEF_INTERVAL)) {
throw new IllegalArgumentException("Check interval must be specified");
}
if (bCreate && StringUtils.isEmpty(definitionName)) {
throw new IllegalArgumentException("Definition name must be specified");
}
if (bCreate && StringUtils.isEmpty(serviceName)) {
throw new IllegalArgumentException("Service name must be specified");
}
// on creation, source type is required
if (bCreate && null == sourceType) {
throw new IllegalArgumentException(String.format(
"Source type must be specified and one of %s",
EnumSet.allOf(SourceType.class)));
}
// !!! The AlertDefinition "source" field is a nested JSON object;
// build a JSON representation from the flat properties and then
// serialize that JSON object as a string
Map<String,JsonObject> jsonObjectMapping = new HashMap<>();
// for every property in the request, if it's a source property, then
// add it to the JSON model
for (Entry<String, Object> entry : requestMap.entrySet()) {
String propertyKey = entry.getKey();
// only handle "source" subproperties
if (!propertyKey.startsWith(ALERT_DEF_SOURCE)) {
continue;
}
// gets a JSON object to add the property to; this will create the
// property and all of its parent properties recursively if necessary
JsonObject jsonObject = getJsonObjectMapping(ALERT_DEF_SOURCE,
jsonObjectMapping, propertyKey);
String propertyName = PropertyHelper.getPropertyName(propertyKey);
Object entryValue = entry.getValue();
// determine if the object is a collection, a number, or a string
if( entryValue instanceof Collection<?> ){
// add it as a tree (collection)
JsonElement jsonElement = gson.toJsonTree(entryValue);
jsonObject.add(propertyName, jsonElement);
} else if (entryValue instanceof Number) {
// add it as a number
jsonObject.addProperty(propertyName, (Number) entryValue);
} else {
// it's a string, but it could still be a Number since Ambari's higher
// level JSON processor converts all JSON bodies into Map<String,String>
// instead of Map<String,Object>
String value = entryValue.toString();
if (StringUtils.isNotEmpty(value) && NumberUtils.isNumber(value)) {
Number number = NumberUtils.createNumber(value);
jsonObject.addProperty(propertyName, number);
} else {
jsonObject.addProperty(propertyName, value);
}
}
}
// "source" must be filled in when creating
JsonObject source = jsonObjectMapping.get(ALERT_DEF_SOURCE);
if (bCreate && (null == source || 0 == source.entrySet().size())) {
throw new IllegalArgumentException("Source must be specified");
}
Clusters clusters = getManagementController().getClusters();
Cluster cluster = clusters.getCluster(clusterName);
Long clusterId = cluster.getClusterId();
boolean managed = false;
boolean toggled = false;
// at this point, we have either validated all required properties or
// we are using the exiting entity properties where not defined, so we
// can do simply null checks
if (!clusterId.equals(entity.getClusterId())) {
entity.setClusterId(clusterId);
managed = true;
}
if ((null != componentName) && !componentName.equals(entity.getComponentName())) {
entity.setComponentName(componentName);
managed = true;
}
if ((null != definitionName) && !definitionName.equals(entity.getDefinitionName())) {
entity.setDefinitionName(definitionName);
managed = true;
}
if ((null != label) && !label.equals(entity.getLabel())) {
entity.setLabel(label);
managed = true;
}
if ((null != helpURL) && !helpURL.equals(entity.getHelpURL())) {
entity.setHelpURL(helpURL);
managed = true;
}
if ((null != description) && !description.equals(entity.getDescription())) {
entity.setDescription(description);
managed = true;
}
if ((null != enabled) && !enabled.equals(entity.getEnabled())) {
entity.setEnabled(enabled);
toggled = true;
}
if ((null != ignoreHost) && !ignoreHost.equals(entity.isHostIgnored())) {
entity.setHostIgnored(ignoreHost);
managed = true;
}
if ((null != interval) && !interval.equals(entity.getScheduleInterval())) {
entity.setScheduleInterval(interval);
managed = true;
}
if ((null != serviceName) && !serviceName.equals(entity.getServiceName())) {
entity.setServiceName(serviceName);
managed = true;
}
if ((null != sourceType) && !sourceType.equals(entity.getSourceType())) {
entity.setSourceType(sourceType);
managed = true;
}
if (null != source) {
entity.setSource(source.toString());
managed = true;
}
if ((null != scope) && !scope.equals(entity.getScope())) {
entity.setScope(scope);
managed = true;
}
// repeat tolerance is only for non-AGGREGATE alerts
if (entity.getSourceType() != SourceType.AGGREGATE) {
if (null != repeatTolerance) {
entity.setRepeatTolerance(repeatTolerance);
managed = true;
}
if (null != repeatToleranceEnabled) {
entity.setRepeatToleranceEnabled(repeatToleranceEnabled);
managed = true;
}
}
if (managed) {
AlertResourceProviderUtils.verifyManageAuthorization(entity);
} else if (toggled) {
AlertResourceProviderUtils.verifyToggleAuthorization(entity);
}
entity.setHash(UUID.randomUUID().toString());
}