/**
* 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.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.StaticallyInject;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.WidgetResponse;
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.Resource.Type;
import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.orm.dao.UserDAO;
import org.apache.ambari.server.orm.dao.WidgetDAO;
import org.apache.ambari.server.orm.dao.WidgetLayoutDAO;
import org.apache.ambari.server.orm.entities.UserEntity;
import org.apache.ambari.server.orm.entities.WidgetEntity;
import org.apache.ambari.server.orm.entities.WidgetLayoutEntity;
import org.apache.ambari.server.orm.entities.WidgetLayoutUserWidgetEntity;
import org.apache.ambari.server.security.authorization.AuthorizationException;
import org.apache.ambari.server.security.authorization.AuthorizationHelper;
import org.apache.ambari.server.security.authorization.ResourceType;
import org.apache.ambari.server.security.authorization.RoleAuthorization;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.inject.Inject;
/**
* Resource provider for widget layout resources.
*/
@StaticallyInject
public class ActiveWidgetLayoutResourceProvider extends AbstractControllerResourceProvider {
// ----- Property ID constants ---------------------------------------------
public static final String WIDGETLAYOUT_ID_PROPERTY_ID = PropertyHelper.getPropertyId("WidgetLayoutInfo", "id");
public static final String WIDGETLAYOUT_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("WidgetLayoutInfo", "cluster_name");
public static final String WIDGETLAYOUT_SECTION_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("WidgetLayoutInfo", "section_name");
public static final String WIDGETLAYOUT_LAYOUT_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("WidgetLayoutInfo", "layout_name");
public static final String WIDGETLAYOUT_SCOPE_PROPERTY_ID = PropertyHelper.getPropertyId("WidgetLayoutInfo", "scope");
public static final String WIDGETLAYOUT_WIDGETS_PROPERTY_ID = PropertyHelper.getPropertyId("WidgetLayoutInfo", "widgets");
public static final String WIDGETLAYOUT_USERNAME_PROPERTY_ID = PropertyHelper.getPropertyId("WidgetLayoutInfo", "user_name");
public static final String WIDGETLAYOUT_DISPLAY_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("WidgetLayoutInfo", "display_name");
public static final String WIDGETLAYOUT = "WidgetLayouts";
public static final String ID = "id";
@SuppressWarnings("serial")
private static Set<String> pkPropertyIds = new HashSet<>();
@SuppressWarnings("serial")
public static Set<String> propertyIds = new HashSet<>();
@SuppressWarnings("serial")
public static Map<Type, String> keyPropertyIds = new HashMap<>();
static {
pkPropertyIds.add(WIDGETLAYOUT_ID_PROPERTY_ID);
propertyIds.add(WIDGETLAYOUT_ID_PROPERTY_ID);
propertyIds.add(WIDGETLAYOUT_SECTION_NAME_PROPERTY_ID);
propertyIds.add(WIDGETLAYOUT_LAYOUT_NAME_PROPERTY_ID);
propertyIds.add(WIDGETLAYOUT_CLUSTER_NAME_PROPERTY_ID);
propertyIds.add(WIDGETLAYOUT_WIDGETS_PROPERTY_ID);
propertyIds.add(WIDGETLAYOUT_SCOPE_PROPERTY_ID);
propertyIds.add(WIDGETLAYOUT_USERNAME_PROPERTY_ID);
propertyIds.add(WIDGETLAYOUT_DISPLAY_NAME_PROPERTY_ID);
propertyIds.add(WIDGETLAYOUT);
keyPropertyIds.put(Type.ActiveWidgetLayout, WIDGETLAYOUT_ID_PROPERTY_ID);
keyPropertyIds.put(Type.User, WIDGETLAYOUT_USERNAME_PROPERTY_ID);
}
@Inject
private static UserDAO userDAO;
@Inject
private static WidgetDAO widgetDAO;
@Inject
private static WidgetLayoutDAO widgetLayoutDAO;
@Inject
private static Gson gson;
/**
* For testing purposes
*/
public static void init(UserDAO userDAO, WidgetDAO widgetDAO, WidgetLayoutDAO widgetLayoutDAO, Gson gson){
ActiveWidgetLayoutResourceProvider.userDAO = userDAO;
ActiveWidgetLayoutResourceProvider.widgetDAO = widgetDAO;
ActiveWidgetLayoutResourceProvider.widgetLayoutDAO = widgetLayoutDAO;
ActiveWidgetLayoutResourceProvider.gson = gson;
}
/**
* Create a new resource provider.
*
*/
public ActiveWidgetLayoutResourceProvider(AmbariManagementController managementController) {
super(propertyIds, keyPropertyIds, managementController);
}
@Override
public RequestStatus createResources(final Request request)
throws SystemException,
UnsupportedPropertyException,
ResourceAlreadyExistsException,
NoSuchParentResourceException {
throw new SystemException("The request is not supported");
}
@Override
public Set<Resource> getResources(Request request, Predicate predicate)
throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
final Set<Resource> resources = new HashSet<>();
final Set<String> requestedIds = getRequestPropertyIds(request, predicate);
final Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
List<WidgetLayoutEntity> layoutEntities = new ArrayList<>();
boolean isUserAdministrator = AuthorizationHelper.isAuthorized(ResourceType.AMBARI, null,
RoleAuthorization.AMBARI_MANAGE_USERS);
for (Map<String, Object> propertyMap: propertyMaps) {
final String userName = propertyMap.get(WIDGETLAYOUT_USERNAME_PROPERTY_ID).toString();
// Ensure that the authenticated user has authorization to get this information
if (!isUserAdministrator && !AuthorizationHelper.getAuthenticatedName().equalsIgnoreCase(userName)) {
throw new AuthorizationException();
}
java.lang.reflect.Type type = new TypeToken<Set<Map<String, String>>>(){}.getType();
Set<Map<String, String>> activeWidgetLayouts = gson.fromJson(userDAO.findSingleUserByName(userName).getActiveWidgetLayouts(), type);
if (activeWidgetLayouts != null) {
for (Map<String, String> widgetLayoutId : activeWidgetLayouts) {
layoutEntities.add(widgetLayoutDAO.findById(Long.parseLong(widgetLayoutId.get(ID))));
}
}
}
for (WidgetLayoutEntity layoutEntity : layoutEntities) {
Resource resource = new ResourceImpl(Type.ActiveWidgetLayout);
resource.setProperty(WIDGETLAYOUT_ID_PROPERTY_ID, layoutEntity.getId());
String clusterName = null;
try {
clusterName = getManagementController().getClusters().getClusterById(layoutEntity.getClusterId()).getClusterName();
} catch (AmbariException e) {
throw new SystemException(e.getMessage());
}
resource.setProperty(WIDGETLAYOUT_CLUSTER_NAME_PROPERTY_ID, clusterName);
resource.setProperty(WIDGETLAYOUT_LAYOUT_NAME_PROPERTY_ID, layoutEntity.getLayoutName());
resource.setProperty(WIDGETLAYOUT_SECTION_NAME_PROPERTY_ID, layoutEntity.getSectionName());
resource.setProperty(WIDGETLAYOUT_SCOPE_PROPERTY_ID, layoutEntity.getScope());
resource.setProperty(WIDGETLAYOUT_USERNAME_PROPERTY_ID, layoutEntity.getUserName());
resource.setProperty(WIDGETLAYOUT_DISPLAY_NAME_PROPERTY_ID, layoutEntity.getDisplayName());
List<HashMap> widgets = new ArrayList<>();
List<WidgetLayoutUserWidgetEntity> widgetLayoutUserWidgetEntityList = layoutEntity.getListWidgetLayoutUserWidgetEntity();
for (WidgetLayoutUserWidgetEntity widgetLayoutUserWidgetEntity : widgetLayoutUserWidgetEntityList) {
WidgetEntity widgetEntity = widgetLayoutUserWidgetEntity.getWidget();
HashMap<String, Object> widgetInfoMap = new HashMap<>();
widgetInfoMap.put("WidgetInfo",WidgetResponse.coerce(widgetEntity));
widgets.add(widgetInfoMap);
}
resource.setProperty(WIDGETLAYOUT_WIDGETS_PROPERTY_ID, widgets);
resources.add(resource);
}
return resources;
}
@Override
public RequestStatus updateResources(Request request, Predicate predicate)
throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
final Set<Map<String, Object>> propertyMaps = request.getProperties();
modifyResources(new Command<Void>() {
@Override
public Void invoke() throws AmbariException, AuthorizationException {
boolean isUserAdministrator = AuthorizationHelper.isAuthorized(ResourceType.AMBARI, null,
RoleAuthorization.AMBARI_MANAGE_USERS);
for (Map<String, Object> propertyMap : propertyMaps) {
// Ensure that the authenticated user has authorization to get this information
String userName = propertyMap.get(WIDGETLAYOUT_USERNAME_PROPERTY_ID).toString();
if (!isUserAdministrator && !AuthorizationHelper.getAuthenticatedName().equalsIgnoreCase(userName)) {
throw new AuthorizationException();
}
Set<HashMap<String, String>> widgetLayouts = (Set) propertyMap.get(WIDGETLAYOUT);
for (HashMap<String, String> widgetLayout : widgetLayouts) {
final Long layoutId;
try {
layoutId = Long.parseLong(widgetLayout.get(ID));
} catch (Exception ex) {
throw new AmbariException("WidgetLayout should have numerical id");
}
final WidgetLayoutEntity entity = widgetLayoutDAO.findById(layoutId);
if (entity == null) {
throw new AmbariException("There is no widget layout with id " + layoutId);
}
}
UserEntity user = userDAO.findUserByName(userName);
user.setActiveWidgetLayouts(gson.toJson(propertyMap.get(WIDGETLAYOUT)));
userDAO.merge(user);
}
return null;
}
});
return getRequestStatus(null);
}
@Override
public RequestStatus deleteResources(Request request, Predicate predicate)
throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
throw new SystemException("The request is not supported");
}
@Override
protected Set<String> getPKPropertyIds() {
return pkPropertyIds;
}
}