blob: 5235ef4fb1306e3354678fd92c9bdb1574e62ce9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ambari.server.controller.internal;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.DuplicateResourceException;
import org.apache.ambari.server.StaticallyInject;
import org.apache.ambari.server.controller.SettingResponse;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.spi.Request;
import org.apache.ambari.server.controller.spi.RequestStatus;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.orm.dao.SettingDAO;
import org.apache.ambari.server.orm.entities.SettingEntity;
import org.apache.ambari.server.security.authorization.AuthorizationException;
import org.apache.ambari.server.security.authorization.AuthorizationHelper;
import org.apache.ambari.server.security.authorization.RoleAuthorization;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
/**
* This class deals with managing CRUD operation on {@link SettingEntity}.
*/
@StaticallyInject
public class SettingResourceProvider extends AbstractAuthorizedResourceProvider {
public static final String RESPONSE_KEY = "Settings";
protected static final String ID = "id";
protected static final String SETTING = "Setting";
public static final String NAME = "name";
public static final String SETTING_TYPE = "setting_type";
public static final String CONTENT = "content";
public static final String UPDATED_BY = "updated_by";
public static final String UPDATE_TIMESTAMP = "update_timestamp";
public static final String SETTING_NAME_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + NAME;
public static final String SETTING_SETTING_TYPE_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + SETTING_TYPE;
public static final String SETTING_CONTENT_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + CONTENT;
public static final String SETTING_UPDATED_BY_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + UPDATED_BY;
public static final String SETTING_UPDATE_TIMESTAMP_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + UPDATE_TIMESTAMP;
public static final String ALL_PROPERTIES = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "*";
/**
* The property ids for setting resource.
*/
private static final Set<String> propertyIds = new HashSet<>();
/**
* The key property ids for setting resource.
*/
private static final Map<Resource.Type, String> keyPropertyIds = new HashMap<>();
private static final Set<String> REQUIRED_PROPERTIES = ImmutableSet.of(
SETTING_NAME_PROPERTY_ID,
SETTING_SETTING_TYPE_PROPERTY_ID,
SETTING_CONTENT_PROPERTY_ID
);
@Inject
private static SettingDAO dao;
static {
propertyIds.add(SETTING_NAME_PROPERTY_ID);
propertyIds.add(SETTING_SETTING_TYPE_PROPERTY_ID);
propertyIds.add(SETTING_CONTENT_PROPERTY_ID);
propertyIds.add(SETTING_UPDATED_BY_PROPERTY_ID);
propertyIds.add(SETTING_UPDATE_TIMESTAMP_PROPERTY_ID);
propertyIds.add(SETTING_SETTING_TYPE_PROPERTY_ID);
propertyIds.add(SETTING);
keyPropertyIds.put(Resource.Type.Setting, SETTING_NAME_PROPERTY_ID);
}
protected SettingResourceProvider() {
super(propertyIds, keyPropertyIds);
EnumSet<RoleAuthorization> requiredAuthorizations = EnumSet.of(RoleAuthorization.AMBARI_MANAGE_SETTINGS);
setRequiredCreateAuthorizations(requiredAuthorizations);
setRequiredDeleteAuthorizations(requiredAuthorizations);
setRequiredUpdateAuthorizations(requiredAuthorizations);
}
@Override
protected Set<String> getPKPropertyIds() {
return new HashSet<>(keyPropertyIds.values());
}
@Override
public RequestStatus createResourcesAuthorized(Request request)
throws NoSuchParentResourceException, ResourceAlreadyExistsException, SystemException {
Set<Resource> associatedResources = new HashSet<>();
for (Map<String, Object> properties : request.getProperties()) {
SettingResponse setting = createResources(newCreateCommand(request, properties));
Resource resource = new ResourceImpl(Resource.Type.Setting);
resource.setProperty(SETTING_NAME_PROPERTY_ID, setting.getName());
associatedResources.add(resource);
}
return getRequestStatus(null, associatedResources);
}
@Override
public Set<Resource> getResourcesAuthorized(Request request, Predicate predicate) throws NoSuchResourceException {
List<SettingEntity> entities = new LinkedList<>();
final Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
if (propertyMaps.isEmpty()) {
entities = dao.findAll();
}
for (Map<String, Object> propertyMap: propertyMaps) {
if (propertyMap.containsKey(SETTING_NAME_PROPERTY_ID)) {
String name = propertyMap.get(SETTING_NAME_PROPERTY_ID).toString();
SettingEntity entity = dao.findByName(name);
if (entity == null) {
throw new NoSuchResourceException(String.format("Setting with name %s does not exists", name));
}
entities.add(entity);
} else {
entities = dao.findAll();
break;
}
}
Set<String> requestedIds = getRequestPropertyIds(request, predicate);
Set<Resource> resources = new HashSet<>();
for(SettingEntity entity : entities) {
resources.add(toResource(toResponse(entity), requestedIds));
}
return resources;
}
@Override
public RequestStatus updateResourcesAuthorized(Request request, Predicate predicate)
throws NoSuchResourceException, NoSuchParentResourceException, SystemException {
modifyResources(newUpdateCommand(request));
return getRequestStatus(null);
}
@Override
public RequestStatus deleteResourcesAuthorized(Request request, Predicate predicate) {
final Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
for (Map<String, Object> propertyMap : propertyMaps) {
if (propertyMap.containsKey(SETTING_NAME_PROPERTY_ID)) {
dao.removeByName(propertyMap.get(SETTING_NAME_PROPERTY_ID).toString());
}
}
return getRequestStatus(null);
}
private Command<SettingResponse> newCreateCommand(final Request request, final Map<String, Object> properties) {
return new Command<SettingResponse>() {
@Override
public SettingResponse invoke() throws AmbariException, AuthorizationException {
SettingEntity entity = toEntity(properties);
if (dao.findByName(entity.getName()) != null) {
throw new DuplicateResourceException(
String.format("Setting already exists. setting name :%s ", entity.getName()));
}
dao.create(entity);
notifyCreate(Resource.Type.Setting, request);
return toResponse(entity);
}
};
}
private Command<Void> newUpdateCommand(final Request request) throws NoSuchResourceException, SystemException {
return new Command<Void>() {
@Override
public Void invoke() throws AmbariException {
final Set<Map<String, Object>> propertyMaps = request.getProperties();
for (Map<String, Object> propertyMap : propertyMaps) {
if (propertyMap.containsKey(SETTING_NAME_PROPERTY_ID)) {
String name = propertyMap.get(SETTING_NAME_PROPERTY_ID).toString();
SettingEntity entity = dao.findByName(name);
if (entity == null) {
throw new AmbariException(String.format("There is no setting with name: %s ", name));
}
updateEntity(entity, propertyMap);
dao.merge(entity);
}
}
return null;
}
};
}
private void updateEntity(SettingEntity entity, Map<String, Object> propertyMap) throws AmbariException {
String name = propertyMap.get(SETTING_NAME_PROPERTY_ID).toString();
if (!Objects.equals(name, entity.getName())) {
throw new AmbariException("Name for Setting is immutable, cannot change name.");
}
if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(SETTING_CONTENT_PROPERTY_ID)))) {
entity.setContent(propertyMap.get(SETTING_CONTENT_PROPERTY_ID).toString());
}
if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(SETTING_SETTING_TYPE_PROPERTY_ID)))) {
entity.setSettingType(propertyMap.get(SETTING_SETTING_TYPE_PROPERTY_ID).toString());
}
entity.setUpdatedBy(AuthorizationHelper.getAuthenticatedName());
entity.setUpdateTimestamp(System.currentTimeMillis());
}
private Resource toResource(final SettingResponse setting, final Set<String> requestedIds) {
Resource resource = new ResourceImpl(Resource.Type.Setting);
setResourceProperty(resource, SETTING_NAME_PROPERTY_ID, setting.getName(), requestedIds);
setResourceProperty(resource, SETTING_SETTING_TYPE_PROPERTY_ID, setting.getSettingType(), requestedIds);
setResourceProperty(resource, SETTING_CONTENT_PROPERTY_ID, setting.getContent(), requestedIds);
setResourceProperty(resource, SETTING_UPDATED_BY_PROPERTY_ID, setting.getUpdatedBy(), requestedIds);
setResourceProperty(resource, SETTING_UPDATE_TIMESTAMP_PROPERTY_ID, setting.getUpdateTimestamp(), requestedIds);
return resource;
}
private SettingEntity toEntity(final Map<String, Object> properties) throws AmbariException {
for (String propertyName: REQUIRED_PROPERTIES) {
if (properties.get(propertyName) == null) {
throw new AmbariException(String.format("Property %s should be provided", propertyName));
}
}
SettingEntity entity = new SettingEntity();
entity.setName(properties.get(SETTING_NAME_PROPERTY_ID).toString());
entity.setSettingType(properties.get(SETTING_SETTING_TYPE_PROPERTY_ID).toString());
entity.setContent(properties.get(SETTING_CONTENT_PROPERTY_ID).toString());
entity.setUpdatedBy(AuthorizationHelper.getAuthenticatedName());
entity.setUpdateTimestamp(System.currentTimeMillis());
return entity;
}
private static SettingResponse toResponse(SettingEntity entity) {
return new SettingResponse(entity.getName(), entity.getSettingType(), entity.getContent(), entity.getUpdatedBy(), entity.getUpdateTimestamp());
}
}