Repository: ambari Updated Branches: refs/heads/trunk f71f175e2 -> 2f2e37267
AMBARI-10407. Create API endpoint for widgets. Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2f2e3726 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2f2e3726 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2f2e3726 Branch: refs/heads/trunk Commit: 2f2e372672e908628de5e0dbd40d0b491bee4eb6 Parents: f71f175 Author: Siddharth Wagle <[email protected]> Authored: Thu Apr 9 12:37:35 2015 -0700 Committer: Jaimin Jetly <[email protected]> Committed: Fri Apr 10 12:49:15 2015 -0700 ---------------------------------------------------------------------- .../server/api/services/ClusterService.java | 10 + .../server/api/services/WidgetService.java | 131 ++++++ .../AbstractControllerResourceProvider.java | 2 + .../internal/WidgetResourceProvider.java | 383 +++++++++++++++ .../server/orm/entities/WidgetEntity.java | 11 +- .../entities/WidgetLayoutUserWidgetEntity.java | 4 +- .../WidgetLayoutUserWidgetEntityPK.java | 2 +- .../server/upgrade/UpgradeCatalog210.java | 14 +- .../main/resources/Ambari-DDL-MySQL-CREATE.sql | 14 +- .../main/resources/Ambari-DDL-Oracle-CREATE.sql | 14 +- .../resources/Ambari-DDL-Postgres-CREATE.sql | 14 +- .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 16 +- .../internal/WidgetResourceProviderTest.java | 465 +++++++++++++++++++ .../server/upgrade/UpgradeCatalog210Test.java | 14 +- 14 files changed, 1044 insertions(+), 50 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java index 87a4f7f..be40bc4 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java @@ -644,6 +644,16 @@ public class ClusterService extends BaseService { return new WidgetLayoutService(clusterName); } + /** + * Gets the widget service + */ + @Path("{clusterName}/widgets") + public WidgetService getWidgetService(@Context javax.ws.rs.core.Request request, + @PathParam ("clusterName") String clusterName) { + + return new WidgetService(clusterName); + } + // ----- helper methods ---------------------------------------------------- /** http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetService.java new file mode 100644 index 0000000..ead0985 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetService.java @@ -0,0 +1,131 @@ +/** + * 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.api.services; + +import com.sun.jersey.core.util.Base64; +import org.apache.ambari.server.api.resources.ResourceInstance; +import org.apache.ambari.server.controller.spi.Resource; + +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; + +/** + * Widget Service + */ +public class WidgetService extends BaseService { + + private final String clusterName; + + public WidgetService(String clusterName) { + this.clusterName = clusterName; + } + + @GET + @Path("{widgetId}") + @Produces("text/plain") + public Response getService(String body, @Context HttpHeaders headers, @Context UriInfo ui, + @PathParam("widgetId") String widgetId) { + + return handleRequest(headers, body, ui, Request.Type.GET, + createResource(getUserName(headers), widgetId)); + } + + /** + * Handles URL: /widget + * Get all instances for a view. + * + * @param headers http headers + * @param ui uri info + * + * @return instance collection resource representation + */ + @GET + @Produces("text/plain") + public Response getServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) { + + return handleRequest(headers, body, ui, Request.Type.GET, + createResource(getUserName(headers), null)); + } + + @POST + @Path("{widgetId}") + @Produces("text/plain") + public Response createService(String body, @Context HttpHeaders headers, @Context UriInfo ui, + @PathParam("widgetId") String widgetId) { + return handleRequest(headers, body, ui, Request.Type.POST, + createResource(getUserName(headers), widgetId)); + } + + @POST + @Produces("text/plain") + public Response createServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) { + + return handleRequest(headers, body, ui, Request.Type.POST, + createResource(getUserName(headers), null)); + } + + @PUT + @Path("{widgetId}") + @Produces("text/plain") + public Response updateService(String body, @Context HttpHeaders headers, @Context UriInfo ui, + @PathParam("widgetId") String widgetId) { + + return handleRequest(headers, body, ui, Request.Type.PUT, createResource(getUserName(headers), widgetId)); + } + + @PUT + @Produces("text/plain") + public Response updateServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) { + + return handleRequest(headers, body, ui, Request.Type.PUT, createResource(getUserName(headers), null)); + } + + @DELETE + @Path("{widgetId}") + @Produces("text/plain") + public Response deleteService(@Context HttpHeaders headers, @Context UriInfo ui, + @PathParam("widgetId") String widgetId) { + + return handleRequest(headers, null, ui, Request.Type.DELETE, createResource(getUserName(headers), widgetId)); + } + + private ResourceInstance createResource(String userName, String widgetId) { + Map<Resource.Type,String> mapIds = new HashMap<Resource.Type, String>(); + mapIds.put(Resource.Type.Cluster, clusterName); + mapIds.put(Resource.Type.Widget, widgetId); + mapIds.put(Resource.Type.User, userName); + return createResource(Resource.Type.Widget, mapIds); + } + + private String getUserName(HttpHeaders headers) { + String authorizationString = headers.getRequestHeaders().get("Authorization").get(0); + if (authorizationString != null && authorizationString.startsWith("Basic")) { + String base64Credentials = authorizationString.substring("Basic".length()).trim(); + String clearCredentials = new String(Base64.decode(base64Credentials), Charset.forName("UTF-8")); + return clearCredentials.split(":", 2)[0]; + } else { + return null; + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java index 2c3f0b0..eb1a818 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java @@ -159,6 +159,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractResourc return new ThemeArtifactResourceProvider(managementController); case WidgetLayout: return new WidgetLayoutResourceProvider(managementController); + case Widget: + return new WidgetResourceProvider(managementController); default: throw new IllegalArgumentException("Unknown type " + type); http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/WidgetResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/WidgetResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/WidgetResourceProvider.java new file mode 100644 index 0000000..87ae723 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/WidgetResourceProvider.java @@ -0,0 +1,383 @@ +/** + * 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 com.google.gson.Gson; +import com.google.inject.Inject; +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.ObjectNotFoundException; +import org.apache.ambari.server.StaticallyInject; +import org.apache.ambari.server.controller.AmbariManagementController; +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.WidgetDAO; +import org.apache.ambari.server.orm.entities.PermissionEntity; +import org.apache.ambari.server.orm.entities.WidgetEntity; +import org.apache.ambari.server.security.authorization.AmbariGrantedAuthority; +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.lang.StringUtils; +import org.springframework.dao.PermissionDeniedDataAccessException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Resource provider for repository versions resources. + */ +@StaticallyInject +public class WidgetResourceProvider extends AbstractControllerResourceProvider { + + // ----- Property ID constants --------------------------------------------- + + public static final String WIDGET_ID_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "id"); + public static final String WIDGET_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "cluster_name"); + public static final String WIDGET_WIDGET_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "widget_name"); + public static final String WIDGET_DISPLAY_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "display_name"); + public static final String WIDGET_WIDGET_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "widget_type"); + public static final String WIDGET_TIME_CREATED_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "time_created"); + public static final String WIDGET_AUTHOR_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "author"); + public static final String WIDGET_DESCRIPTION_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "description"); + public static final String WIDGET_SCOPE_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "scope"); + public static final String WIDGET_METRICS_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "metrics"); + public static final String WIDGET_VALUES_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "values"); + public static final String WIDGET_PROPERTIES_PROPERTY_ID = PropertyHelper.getPropertyId("Widgets", "properties"); + + @SuppressWarnings("serial") + private static Set<String> pkPropertyIds = new HashSet<String>() { + { + add(WIDGET_ID_PROPERTY_ID); + } + }; + + @SuppressWarnings("serial") + public static Set<String> propertyIds = new HashSet<String>() { + { + add(WIDGET_ID_PROPERTY_ID); + add(WIDGET_WIDGET_NAME_PROPERTY_ID); + add(WIDGET_DISPLAY_NAME_PROPERTY_ID); + add(WIDGET_WIDGET_TYPE_PROPERTY_ID); + add(WIDGET_TIME_CREATED_PROPERTY_ID); + add(WIDGET_CLUSTER_NAME_PROPERTY_ID); + add(WIDGET_AUTHOR_PROPERTY_ID); + add(WIDGET_DESCRIPTION_PROPERTY_ID); + add(WIDGET_SCOPE_PROPERTY_ID); + add(WIDGET_METRICS_PROPERTY_ID); + add(WIDGET_VALUES_PROPERTY_ID); + add(WIDGET_PROPERTIES_PROPERTY_ID); + } + }; + + @SuppressWarnings("serial") + public static Map<Type, String> keyPropertyIds = new HashMap<Type, String>() { + { + put(Type.Widget, WIDGET_ID_PROPERTY_ID); + put(Type.Cluster, WIDGET_CLUSTER_NAME_PROPERTY_ID); + put(Type.User, WIDGET_AUTHOR_PROPERTY_ID); + } + }; + + @Inject + private static WidgetDAO widgetDAO; + + @Inject + private static Gson gson; + + /** + * Create a new resource provider. + * + */ + public WidgetResourceProvider(AmbariManagementController managementController) { + super(propertyIds, keyPropertyIds, managementController); + } + + @Override + public RequestStatus createResources(final Request request) + throws SystemException, + UnsupportedPropertyException, + ResourceAlreadyExistsException, + NoSuchParentResourceException { + + for (final Map<String, Object> properties : request.getProperties()) { + createResources(new Command<Void>() { + + @Override + public Void invoke() throws AmbariException { + final String[] requiredProperties = { + WIDGET_CLUSTER_NAME_PROPERTY_ID, + WIDGET_WIDGET_NAME_PROPERTY_ID, + WIDGET_DISPLAY_NAME_PROPERTY_ID, + WIDGET_WIDGET_TYPE_PROPERTY_ID, + WIDGET_SCOPE_PROPERTY_ID + }; + for (String propertyName: requiredProperties) { + if (properties.get(propertyName) == null) { + throw new AmbariException("Property " + propertyName + " should be provided"); + } + } + final WidgetEntity entity = new WidgetEntity(); + String clusterName = properties.get(WIDGET_CLUSTER_NAME_PROPERTY_ID).toString(); + String userName = properties.get(WIDGET_AUTHOR_PROPERTY_ID).toString(); + String scope = properties.get(WIDGET_SCOPE_PROPERTY_ID).toString(); + + if (!isScopeAllowedForUser(scope)) { + throw new AmbariException("Only cluster operator can create widgets with cluster scope"); + } + + entity.setDisplayName(properties.get(WIDGET_DISPLAY_NAME_PROPERTY_ID).toString()); + entity.setWidgetName(properties.get(WIDGET_WIDGET_NAME_PROPERTY_ID).toString()); + entity.setWidgetType(properties.get(WIDGET_WIDGET_TYPE_PROPERTY_ID).toString()); + entity.setClusterId(getManagementController().getClusters().getCluster(clusterName).getClusterId()); + entity.setDisplayName(properties.get(WIDGET_DISPLAY_NAME_PROPERTY_ID).toString()); + entity.setScope(scope); + + String metrics = (properties.containsKey(WIDGET_METRICS_PROPERTY_ID)) ? + gson.toJson(properties.get(WIDGET_METRICS_PROPERTY_ID)) : null; + entity.setMetrics(metrics); + + entity.setAuthor(userName); + + String description = (properties.containsKey(WIDGET_DESCRIPTION_PROPERTY_ID)) ? + properties.get(WIDGET_DESCRIPTION_PROPERTY_ID).toString() : null; + entity.setDescription(description); + + String values = (properties.containsKey(WIDGET_VALUES_PROPERTY_ID)) ? + gson.toJson(properties.get(WIDGET_VALUES_PROPERTY_ID)) : null; + entity.setWidgetValues(values); + + Map<String, Object> widgetPropertiesMap = new HashMap<String, Object>(); + for (Map.Entry<String, Object> entry : properties.entrySet()) { + if (PropertyHelper.getPropertyCategory(entry.getKey()).equals(WIDGET_PROPERTIES_PROPERTY_ID)) { + widgetPropertiesMap.put(PropertyHelper.getPropertyName(entry.getKey()), entry.getValue()); + } + } + + String widgetProperties = (widgetPropertiesMap.isEmpty()) ? + null : gson.toJson(widgetPropertiesMap); + entity.setProperties(widgetProperties); + + widgetDAO.create(entity); + notifyCreate(Type.Widget, request); + return null; + } + }); + } + + return getRequestStatus(null); + } + + @Override + public Set<Resource> getResources(Request request, Predicate predicate) + throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException { + final Set<Resource> resources = new HashSet<Resource>(); + final Set<String> requestedIds = getRequestPropertyIds(request, predicate); + final Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate); + + List<WidgetEntity> requestedEntities = new ArrayList<WidgetEntity>(); + + for (Map<String, Object> propertyMap: propertyMaps) { + if (propertyMap.get(WIDGET_ID_PROPERTY_ID) != null) { + final Long id; + try { + id = Long.parseLong(propertyMap.get(WIDGET_ID_PROPERTY_ID).toString()); + } catch (Exception ex) { + throw new SystemException("WidgetLayout should have numerical id"); + } + final WidgetEntity entity = widgetDAO.findById(id); + if (entity == null) { + throw new NoSuchResourceException("WidgetLayout with id " + id + " does not exists"); + } + requestedEntities.add(entity); + } else { + requestedEntities.addAll(widgetDAO.findAll()); + } + } + + for (WidgetEntity entity: requestedEntities) { + final Resource resource = new ResourceImpl(Type.Widget); + resource.setProperty(WIDGET_ID_PROPERTY_ID, entity.getId()); + resource.setProperty(WIDGET_WIDGET_NAME_PROPERTY_ID, entity.getWidgetName()); + resource.setProperty(WIDGET_WIDGET_TYPE_PROPERTY_ID, entity.getWidgetType()); + setResourceProperty(resource, WIDGET_METRICS_PROPERTY_ID, gson.fromJson(entity.getMetrics(), ArrayList.class), requestedIds); + setResourceProperty(resource, WIDGET_TIME_CREATED_PROPERTY_ID, entity.getTimeCreated(), requestedIds); + resource.setProperty(WIDGET_AUTHOR_PROPERTY_ID, entity.getAuthor()); + setResourceProperty(resource, WIDGET_DESCRIPTION_PROPERTY_ID, entity.getDescription(), requestedIds); + resource.setProperty(WIDGET_DISPLAY_NAME_PROPERTY_ID, entity.getDisplayName()); + resource.setProperty(WIDGET_SCOPE_PROPERTY_ID, entity.getScope()); + setResourceProperty(resource, WIDGET_VALUES_PROPERTY_ID, gson.fromJson(entity.getWidgetValues(), ArrayList.class), requestedIds); + setResourceProperty(resource, WIDGET_PROPERTIES_PROPERTY_ID, gson.fromJson(entity.getProperties(), Map.class), requestedIds); + + String clusterName = null; + try { + clusterName = getManagementController().getClusters().getClusterById(entity.getClusterId()).getClusterName(); + } catch (AmbariException e) { + throw new SystemException(e.getMessage()); + } + setResourceProperty(resource, WIDGET_CLUSTER_NAME_PROPERTY_ID, clusterName, requestedIds); + + 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 { + for (Map<String, Object> propertyMap : propertyMaps) { + final Long id; + try { + id = Long.parseLong(propertyMap.get(WIDGET_ID_PROPERTY_ID).toString()); + } catch (Exception ex) { + throw new AmbariException("Widget should have numerical id"); + } + + final WidgetEntity entity = widgetDAO.findById(id); + if (entity == null) { + throw new ObjectNotFoundException("There is no widget with id " + id); + } + + if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(WIDGET_WIDGET_NAME_PROPERTY_ID)))) { + entity.setWidgetName(propertyMap.get(WIDGET_WIDGET_NAME_PROPERTY_ID).toString()); + } + + if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(WIDGET_WIDGET_TYPE_PROPERTY_ID)))) { + entity.setWidgetType(propertyMap.get(WIDGET_WIDGET_TYPE_PROPERTY_ID).toString()); + } + + if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(WIDGET_METRICS_PROPERTY_ID)))) { + entity.setMetrics(gson.toJson(propertyMap.get(WIDGET_METRICS_PROPERTY_ID))); + } + + if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(WIDGET_AUTHOR_PROPERTY_ID)))) { + entity.setAuthor(propertyMap.get(WIDGET_AUTHOR_PROPERTY_ID).toString()); + } + + if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(WIDGET_DESCRIPTION_PROPERTY_ID)))) { + entity.setDescription(propertyMap.get(WIDGET_DESCRIPTION_PROPERTY_ID).toString()); + } + + if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(WIDGET_SCOPE_PROPERTY_ID)))) { + String scope = propertyMap.get(WIDGET_SCOPE_PROPERTY_ID).toString(); + if (!isScopeAllowedForUser(scope)) { + throw new AmbariException("Only cluster operator can create widgets with cluster scope"); + } + entity.setScope(scope); + } + + if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(WIDGET_VALUES_PROPERTY_ID)))) { + entity.setWidgetValues(gson.toJson(propertyMap.get(WIDGET_VALUES_PROPERTY_ID))); + } + + Map<String, Object> widgetPropertiesMap = new HashMap<String, Object>(); + for (Map.Entry<String, Object> entry : propertyMap.entrySet()) { + if (PropertyHelper.getPropertyCategory(entry.getKey()).equals(WIDGET_PROPERTIES_PROPERTY_ID)) { + widgetPropertiesMap.put(PropertyHelper.getPropertyName(entry.getKey()), entry.getValue()); + } + } + + if (!widgetPropertiesMap.isEmpty()) { + entity.setProperties(gson.toJson(widgetPropertiesMap)); + } + + widgetDAO.merge(entity); + } + return null; + } + }); + + return getRequestStatus(null); + } + + @Override + public RequestStatus deleteResources(Predicate predicate) + throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException { + final Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate); + + final List<WidgetEntity> entitiesToBeRemoved = new ArrayList<WidgetEntity>(); + for (Map<String, Object> propertyMap : propertyMaps) { + final Long id; + try { + id = Long.parseLong(propertyMap.get(WIDGET_ID_PROPERTY_ID).toString()); + } catch (Exception ex) { + throw new SystemException("Widget should have numerical id"); + } + final WidgetEntity entity = widgetDAO.findById(id); + if (entity == null) { + throw new NoSuchResourceException("There is no widget with id " + id); + } + entitiesToBeRemoved.add(entity); + } + + for (WidgetEntity entity: entitiesToBeRemoved) { + widgetDAO.remove(entity); + } + + return getRequestStatus(null); + } + + @Override + protected Set<String> getPKPropertyIds() { + return pkPropertyIds; + } + + private boolean isScopeAllowedForUser(String scope) { + if (scope.equals(WidgetEntity.USER_SCOPE)) { + return true; + } + + // Only cluster operators are allowed to create widgets with cluster scope + SecurityContext securityContext = SecurityContextHolder.getContext(); + securityContext.getAuthentication().getAuthorities(); + boolean hasPermissionForClusterScope = false; + for (GrantedAuthority grantedAuthority : securityContext.getAuthentication().getAuthorities()) { + if (((AmbariGrantedAuthority) grantedAuthority).getPrivilegeEntity().getPermission().getId() + == PermissionEntity.AMBARI_ADMIN_PERMISSION || + ((AmbariGrantedAuthority) grantedAuthority).getPrivilegeEntity().getPermission().getId() + == PermissionEntity.CLUSTER_OPERATE_PERMISSION) { + hasPermissionForClusterScope = true; + } + } + if (hasPermissionForClusterScope) { + return true; + } else { + return false; + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetEntity.java index 4fd6fbf..d383a62 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetEntity.java @@ -33,7 +33,7 @@ import javax.persistence.TableGenerator; import java.util.List; @Entity -@Table(name = "user_widget") +@Table(name = "widget") @TableGenerator(name = "widget_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", @@ -53,15 +53,18 @@ import java.util.List; }) public class WidgetEntity { + public static final String CLUSTER_SCOPE = "CLUSTER"; + public static final String USER_SCOPE = "USER"; + @Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "widget_id_generator") @Column(name = "id", nullable = false, updatable = false) private Long id; - @Column(name = "user_widget_name", nullable = false, length = 255) + @Column(name = "widget_name", nullable = false, length = 255) private String widgetName; - @Column(name = "user_widget_type", nullable = false, length = 255) + @Column(name = "widget_type", nullable = false, length = 255) private String widgetType; @Column(name = "metrics", length = 32672) @@ -95,7 +98,7 @@ public class WidgetEntity { @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false, updatable = false, insertable = false) private ClusterEntity clusterEntity; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "widget") + @OneToMany(cascade = CascadeType.ALL, mappedBy = "widget", orphanRemoval = true) private List<WidgetLayoutUserWidgetEntity> listWidgetLayoutUserWidgetEntity; public Long getId() { http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetLayoutUserWidgetEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetLayoutUserWidgetEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetLayoutUserWidgetEntity.java index df00eb3..1d6e1b5 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetLayoutUserWidgetEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetLayoutUserWidgetEntity.java @@ -36,7 +36,7 @@ public class WidgetLayoutUserWidgetEntity { private Long widgetLayoutId; @Id - @Column(name = "user_widget_id", nullable = false, updatable = false, insertable = false) + @Column(name = "widget_id", nullable = false, updatable = false, insertable = false) private Long userWidgetId; @ManyToOne @@ -44,7 +44,7 @@ public class WidgetLayoutUserWidgetEntity { private WidgetLayoutEntity widgetLayout; @ManyToOne - @JoinColumn(name = "user_widget_id", referencedColumnName = "id") + @JoinColumn(name = "widget_id", referencedColumnName = "id") private WidgetEntity widget; @Column(name = "widget_order") http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetLayoutUserWidgetEntityPK.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetLayoutUserWidgetEntityPK.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetLayoutUserWidgetEntityPK.java index 4fdd977..386870f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetLayoutUserWidgetEntityPK.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetLayoutUserWidgetEntityPK.java @@ -39,7 +39,7 @@ public class WidgetLayoutUserWidgetEntityPK implements Serializable { private Long userWidgetId; @Id - @Column(name = "user_widget_id", nullable = false, updatable = false) + @Column(name = "widget_id", nullable = false, updatable = false) public Long getUserWidgetId() { return userWidgetId; } http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java index 1518811..e94d5f4 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java @@ -51,7 +51,7 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog { private static final String CONFIG_GROUP_HOST_MAPPING_TABLE = "configgrouphostmapping"; private static final String KERBEROS_PRINCIPAL_HOST_TABLE = "kerberos_principal_host"; private static final String CLUSTER_HOST_MAPPING_TABLE = "ClusterHostMapping"; - private static final String USER_WIDGET_TABLE = "user_widget"; + private static final String WIDGET_TABLE = "widget"; private static final String WIDGET_LAYOUT_TABLE = "widget_layout"; private static final String WIDGET_LAYOUT_USER_WIDGET_TABLE = "widget_layout_user_widget"; private static final String VIEW_INSTANCE_TABLE = "viewinstance"; @@ -303,8 +303,8 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog { List<DBColumnInfo> columns = new ArrayList<DBColumnInfo>(); columns.add(new DBColumnInfo("id", Long.class, null, null, false)); - columns.add(new DBColumnInfo("user_widget_name", String.class, 255, null, false)); - columns.add(new DBColumnInfo("user_widget_type", String.class, 255, null, false)); + columns.add(new DBColumnInfo("widget_name", String.class, 255, null, false)); + columns.add(new DBColumnInfo("widget_type", String.class, 255, null, false)); columns.add(new DBColumnInfo("metrics", String.class, 32672, null, true)); columns.add(new DBColumnInfo("time_created", Long.class, 255, null, false)); columns.add(new DBColumnInfo("author", String.class, 255, null, true)); @@ -314,7 +314,7 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog { columns.add(new DBColumnInfo("widget_values", String.class, 255, null, true)); columns.add(new DBColumnInfo("properties", String.class, 255, null, true)); columns.add(new DBColumnInfo("cluster_id", Long.class, 255, null, false)); - dbAccessor.createTable(USER_WIDGET_TABLE, columns, "id"); + dbAccessor.createTable(WIDGET_TABLE, columns, "id"); columns = new ArrayList<DBColumnInfo>(); columns.add(new DBColumnInfo("id", Long.class, null, null, false)); @@ -329,11 +329,11 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog { columns = new ArrayList<DBColumnInfo>(); columns.add(new DBColumnInfo("widget_layout_id", Long.class, null, null, false)); - columns.add(new DBColumnInfo("user_widget_id", Long.class, null, null, false)); + columns.add(new DBColumnInfo("widget_id", Long.class, null, null, false)); columns.add(new DBColumnInfo("widget_order", Integer.class, null, null, false)); - dbAccessor.createTable(WIDGET_LAYOUT_USER_WIDGET_TABLE, columns, "widget_layout_id", "user_widget_id"); + dbAccessor.createTable(WIDGET_LAYOUT_USER_WIDGET_TABLE, columns, "widget_layout_id", "widget_id"); dbAccessor.addFKConstraint(WIDGET_LAYOUT_USER_WIDGET_TABLE, "FK_widget_layout_id", "widget_layout_id", "widget_layout", "id", true, false); - dbAccessor.addFKConstraint(WIDGET_LAYOUT_USER_WIDGET_TABLE, "FK_user_widget_id", "user_widget_id", "user_widget", "id", true, false); + dbAccessor.addFKConstraint(WIDGET_LAYOUT_USER_WIDGET_TABLE, "FK_widget_id", "widget_id", "widget", "id", true, false); } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql index d947a1b..2ae970c 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql @@ -534,12 +534,12 @@ CREATE TABLE repo_version ( PRIMARY KEY(repo_version_id) ); -CREATE TABLE user_widget ( +CREATE TABLE widget ( id BIGINT NOT NULL, - user_widget_name VARCHAR(255) NOT NULL, - user_widget_type VARCHAR(255) NOT NULL, + widget_name VARCHAR(255) NOT NULL, + widget_type VARCHAR(255) NOT NULL, metrics LONGTEXT, - time_created TIMESTAMP DEFAULT NOW(), + time_created BIGINT NOT NULL, author VARCHAR(255), description VARCHAR(255), display_name VARCHAR(255) NOT NULL, @@ -563,9 +563,9 @@ CREATE TABLE widget_layout ( CREATE TABLE widget_layout_user_widget ( widget_layout_id BIGINT NOT NULL, - user_widget_id BIGINT NOT NULL, + widget_id BIGINT NOT NULL, widget_order smallint, - PRIMARY KEY(widget_layout_id, user_widget_id) + PRIMARY KEY(widget_layout_id, widget_id) ); CREATE TABLE artifact ( @@ -653,7 +653,7 @@ ALTER TABLE users ADD CONSTRAINT FK_users_principal_id FOREIGN KEY (principal_id ALTER TABLE groups ADD CONSTRAINT FK_groups_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); ALTER TABLE clusters ADD CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES adminresource(resource_id); ALTER TABLE widget_layout_user_widget ADD CONSTRAINT FK_widget_layout_id FOREIGN KEY (widget_layout_id) REFERENCES widget_layout(id); -ALTER TABLE widget_layout_user_widget ADD CONSTRAINT FK_user_widget_id FOREIGN KEY (user_widget_id) REFERENCES user_widget(id); +ALTER TABLE widget_layout_user_widget ADD CONSTRAINT FK_widget_id FOREIGN KEY (widget_id) REFERENCES widget(id); -- Kerberos CREATE TABLE kerberos_principal ( http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql index a1b22d4..8db0e32 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql @@ -522,12 +522,12 @@ CREATE TABLE repo_version ( PRIMARY KEY(repo_version_id) ); -CREATE TABLE user_widget ( +CREATE TABLE widget ( id NUMBER(19) NOT NULL, - user_widget_name VARCHAR2(255) NOT NULL, - user_widget_type VARCHAR2(255) NOT NULL, + widget_name VARCHAR2(255) NOT NULL, + widget_type VARCHAR2(255) NOT NULL, metrics CLOB, - time_created TIMESTAMP DEFAULT NOW(), + time_created NUMBER(19) NOT NULL, author VARCHAR2(255), description VARCHAR2(255), display_name VARCHAR2(255) NOT NULL, @@ -551,9 +551,9 @@ CREATE TABLE widget_layout ( CREATE TABLE widget_layout_user_widget ( widget_layout_id NUMBER(19) NOT NULL, - user_widget_id NUMBER(19) NOT NULL, + widget_id NUMBER(19) NOT NULL, widget_order smallint, - PRIMARY KEY(widget_layout_id, user_widget_id) + PRIMARY KEY(widget_layout_id, widget_id) ); CREATE TABLE artifact ( @@ -641,7 +641,7 @@ ALTER TABLE users ADD CONSTRAINT FK_users_principal_id FOREIGN KEY (principal_id ALTER TABLE groups ADD CONSTRAINT FK_groups_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); ALTER TABLE clusters ADD CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES adminresource(resource_id); ALTER TABLE widget_layout_user_widget ADD CONSTRAINT FK_widget_layout_id FOREIGN KEY (widget_layout_id) REFERENCES widget_layout(id); -ALTER TABLE widget_layout_user_widget ADD CONSTRAINT FK_user_widget_id FOREIGN KEY (user_widget_id) REFERENCES user_widget(id); +ALTER TABLE widget_layout_user_widget ADD CONSTRAINT FK_widget_id FOREIGN KEY (widget_id) REFERENCES widget(id); -- Kerberos CREATE TABLE kerberos_principal ( http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql index 66e3117..ca27989 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql @@ -527,12 +527,12 @@ CREATE TABLE repo_version ( PRIMARY KEY(repo_version_id) ); -CREATE TABLE user_widget ( +CREATE TABLE widget ( id BIGINT NOT NULL, - user_widget_name VARCHAR(255) NOT NULL, - user_widget_type VARCHAR(255) NOT NULL, + widget_name VARCHAR(255) NOT NULL, + widget_type VARCHAR(255) NOT NULL, metrics TEXT, - time_created TIMESTAMP DEFAULT NOW(), + time_created BIGINT NOT NULL, author VARCHAR(255), description VARCHAR(255), display_name VARCHAR(255) NOT NULL, @@ -556,9 +556,9 @@ CREATE TABLE widget_layout ( CREATE TABLE widget_layout_user_widget ( widget_layout_id BIGINT NOT NULL, - user_widget_id BIGINT NOT NULL, + widget_id BIGINT NOT NULL, widget_order smallint, - PRIMARY KEY(widget_layout_id, user_widget_id) + PRIMARY KEY(widget_layout_id, widget_id) ); CREATE TABLE artifact ( @@ -643,7 +643,7 @@ ALTER TABLE serviceconfigmapping ADD CONSTRAINT FK_scvm_config FOREIGN KEY (conf ALTER TABLE serviceconfighosts ADD CONSTRAINT FK_scvhosts_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id); ALTER TABLE clusters ADD CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES adminresource(resource_id); ALTER TABLE widget_layout_user_widget ADD CONSTRAINT FK_widget_layout_id FOREIGN KEY (widget_layout_id) REFERENCES widget_layout(id); -ALTER TABLE widget_layout_user_widget ADD CONSTRAINT FK_user_widget_id FOREIGN KEY (user_widget_id) REFERENCES user_widget(id); +ALTER TABLE widget_layout_user_widget ADD CONSTRAINT FK_widget_id FOREIGN KEY (widget_id) REFERENCES widget(id); -- Kerberos CREATE TABLE kerberos_principal ( http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql index e944ebb..e1f9d6c 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql @@ -602,12 +602,12 @@ CREATE TABLE ambari.artifact ( PRIMARY KEY (artifact_name, foreign_keys)); GRANT ALL PRIVILEGES ON TABLE ambari.artifact TO :username; -CREATE TABLE ambari.user_widget ( +CREATE TABLE ambari.widget ( id BIGINT NOT NULL, - user_widget_name VARCHAR(255) NOT NULL, - user_widget_type VARCHAR(255) NOT NULL, + widget_name VARCHAR(255) NOT NULL, + widget_type VARCHAR(255) NOT NULL, metrics TEXT, - time_created TIMESTAMP DEFAULT NOW(), + time_created BIGINT NOT NULL, author VARCHAR(255), description VARCHAR(255), display_name VARCHAR(255) NOT NULL, @@ -617,7 +617,7 @@ CREATE TABLE ambari.user_widget ( cluster_id BIGINT NOT NULL, PRIMARY KEY(id) ); -GRANT ALL PRIVILEGES ON TABLE ambari.user_widget TO :username; +GRANT ALL PRIVILEGES ON TABLE ambari.widget TO :username; CREATE TABLE ambari.widget_layout ( id BIGINT NOT NULL, @@ -633,9 +633,9 @@ GRANT ALL PRIVILEGES ON TABLE ambari.widget_layout TO :username; CREATE TABLE ambari.widget_layout_user_widget ( widget_layout_id BIGINT NOT NULL, - user_widget_id BIGINT NOT NULL, + widget_id BIGINT NOT NULL, widget_order smallint, - PRIMARY KEY(widget_layout_id, user_widget_id) + PRIMARY KEY(widget_layout_id, widget_id) ); GRANT ALL PRIVILEGES ON TABLE ambari.widget_layout_user_widget TO :username; @@ -715,7 +715,7 @@ ALTER TABLE ambari.users ADD CONSTRAINT FK_users_principal_id FOREIGN KEY (princ ALTER TABLE ambari.groups ADD CONSTRAINT FK_groups_principal_id FOREIGN KEY (principal_id) REFERENCES ambari.adminprincipal(principal_id); ALTER TABLE ambari.clusters ADD CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES ambari.adminresource(resource_id); ALTER TABLE ambari.widget_layout_user_widget ADD CONSTRAINT FK_widget_layout_id FOREIGN KEY (widget_layout_id) REFERENCES ambari.widget_layout(id); -ALTER TABLE ambari.widget_layout_user_widget ADD CONSTRAINT FK_user_widget_id FOREIGN KEY (user_widget_id) REFERENCES ambari.user_widget(id); +ALTER TABLE ambari.widget_layout_user_widget ADD CONSTRAINT FK_widget_id FOREIGN KEY (widget_id) REFERENCES ambari.widget(id); -- Kerberos CREATE TABLE ambari.kerberos_principal ( http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/WidgetResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/WidgetResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/WidgetResourceProviderTest.java new file mode 100644 index 0000000..568a89c --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/WidgetResourceProviderTest.java @@ -0,0 +1,465 @@ +/** + * 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 com.google.inject.Binder; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Module; +import com.google.inject.util.Modules; +import org.apache.ambari.server.controller.AmbariManagementController; +import org.apache.ambari.server.controller.spi.Predicate; +import org.apache.ambari.server.controller.spi.Request; +import org.apache.ambari.server.controller.spi.Resource; +import org.apache.ambari.server.controller.spi.SystemException; +import org.apache.ambari.server.controller.utilities.PredicateBuilder; +import org.apache.ambari.server.controller.utilities.PropertyHelper; +import org.apache.ambari.server.orm.InMemoryDefaultTestModule; +import org.apache.ambari.server.orm.dao.WidgetDAO; +import org.apache.ambari.server.orm.entities.WidgetEntity; +import org.apache.ambari.server.state.Cluster; +import org.apache.ambari.server.state.Clusters; +import org.easymock.Capture; +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.easymock.PowerMock; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.security.core.context.SecurityContextHolder; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.capture; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.resetToStrict; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; + +/** + * Widget tests + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest( {WidgetResourceProvider.class, SecurityContextHolder.class} ) +@PowerMockIgnore( {"javax.management.*"} ) +public class WidgetResourceProviderTest { + + private WidgetDAO dao = null; + private Injector m_injector; + + @Before + public void before() { + dao = createStrictMock(WidgetDAO.class); + + m_injector = Guice.createInjector(Modules.override( + new InMemoryDefaultTestModule()).with(new MockModule())); + } + + /** + * @throws Exception + */ + @Test + public void testGetResourcesNoPredicate() throws Exception { + WidgetResourceProvider provider = createProvider(null); + + Request request = PropertyHelper.getReadRequest("Widgets/id"); + + Set<Resource> results = provider.getResources(request, null); + + assertEquals(0, results.size()); + } + + /** + * @throws Exception + */ + @Test + public void testGetSingleResource() throws Exception { + Request request = PropertyHelper.getReadRequest( + WidgetResourceProvider.WIDGET_ID_PROPERTY_ID, + WidgetResourceProvider.WIDGET_WIDGET_NAME_PROPERTY_ID, + WidgetResourceProvider.WIDGET_DISPLAY_NAME_PROPERTY_ID, + WidgetResourceProvider.WIDGET_WIDGET_TYPE_PROPERTY_ID, + WidgetResourceProvider.WIDGET_TIME_CREATED_PROPERTY_ID, + WidgetResourceProvider.WIDGET_CLUSTER_NAME_PROPERTY_ID, + WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID, + WidgetResourceProvider.WIDGET_DESCRIPTION_PROPERTY_ID, + WidgetResourceProvider.WIDGET_SCOPE_PROPERTY_ID, + WidgetResourceProvider.WIDGET_METRICS_PROPERTY_ID, + WidgetResourceProvider.WIDGET_VALUES_PROPERTY_ID, + WidgetResourceProvider.WIDGET_PROPERTIES_PROPERTY_ID); + + AmbariManagementController amc = createMock(AmbariManagementController.class); + Clusters clusters = createMock(Clusters.class); + Cluster cluster = createMock(Cluster.class); + expect(amc.getClusters()).andReturn(clusters).atLeastOnce(); + expect(clusters.getClusterById(1L)).andReturn(cluster).atLeastOnce(); + expect(cluster.getClusterName()).andReturn("c1").anyTimes(); + + Predicate predicate = new PredicateBuilder().property( + WidgetResourceProvider.WIDGET_CLUSTER_NAME_PROPERTY_ID).equals("c1") + .and().property(WidgetResourceProvider.WIDGET_ID_PROPERTY_ID).equals("1") + .and().property(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID).equals("username").toPredicate(); + + expect(dao.findById(1L)).andReturn(getMockEntities().get(0)); + + replay(amc, clusters, cluster, dao); + + WidgetResourceProvider provider = createProvider(amc); + Set<Resource> results = provider.getResources(request, predicate); + + assertEquals(1, results.size()); + + Resource r = results.iterator().next(); + Assert.assertEquals("GAUGE", r.getPropertyValue(WidgetResourceProvider.WIDGET_WIDGET_TYPE_PROPERTY_ID)); + Assert.assertEquals("USER", r.getPropertyValue(WidgetResourceProvider.WIDGET_SCOPE_PROPERTY_ID)); + Assert.assertEquals("username", r.getPropertyValue(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID)); + Assert.assertEquals("displ_name", r.getPropertyValue(WidgetResourceProvider.WIDGET_DISPLAY_NAME_PROPERTY_ID)); + Assert.assertEquals("widget name", r.getPropertyValue(WidgetResourceProvider.WIDGET_WIDGET_NAME_PROPERTY_ID)); + Object metrics = r.getPropertyValue(WidgetResourceProvider.WIDGET_METRICS_PROPERTY_ID); + Assert.assertTrue(metrics instanceof List); + Assert.assertEquals(2, ((List) metrics).size()); + Object values = r.getPropertyValue(WidgetResourceProvider.WIDGET_VALUES_PROPERTY_ID); + Assert.assertTrue(values instanceof List); + Assert.assertEquals(1, ((List) values).size()); + } + + + /** + * @throws Exception + */ + + @Test + public void testCreateResources() throws Exception { + AmbariManagementController amc = createMock(AmbariManagementController.class); + Clusters clusters = createMock(Clusters.class); + Cluster cluster = createMock(Cluster.class); + expect(amc.getClusters()).andReturn(clusters).atLeastOnce(); + expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce(); + expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes(); + + Capture<WidgetEntity> entityCapture = new Capture<WidgetEntity>(); + dao.create(capture(entityCapture)); + expectLastCall(); + + replay(amc, clusters, cluster, dao); + + WidgetResourceProvider provider = createProvider(amc); + + Map<String, Object> requestProps = new HashMap<String, Object>(); + requestProps.put(WidgetResourceProvider.WIDGET_CLUSTER_NAME_PROPERTY_ID, "c1"); + requestProps.put(WidgetResourceProvider.WIDGET_WIDGET_NAME_PROPERTY_ID, "widget name"); + requestProps.put(WidgetResourceProvider.WIDGET_DISPLAY_NAME_PROPERTY_ID, "display_name"); + requestProps.put(WidgetResourceProvider.WIDGET_WIDGET_TYPE_PROPERTY_ID, "GAUGE"); + requestProps.put(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID, "admin"); + requestProps.put(WidgetResourceProvider.WIDGET_SCOPE_PROPERTY_ID, "USER"); + Set testSet = new LinkedHashSet(); + HashMap testMap = new HashMap(); + testMap.put("name","value"); + testMap.put("name2","value2"); + testSet.add(testMap); + requestProps.put(WidgetResourceProvider.WIDGET_METRICS_PROPERTY_ID, testSet); + requestProps.put(WidgetResourceProvider.WIDGET_VALUES_PROPERTY_ID, testSet); + requestProps.put(WidgetResourceProvider.WIDGET_PROPERTIES_PROPERTY_ID+"/property1", "value1"); + requestProps.put(WidgetResourceProvider.WIDGET_PROPERTIES_PROPERTY_ID+"/property2", "value2"); + + Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null); + provider.createResources(request); + + Assert.assertTrue(entityCapture.hasCaptured()); + WidgetEntity entity = entityCapture.getValue(); + Assert.assertNotNull(entity); + + Assert.assertEquals(Long.valueOf(1), entity.getClusterId()); + Assert.assertEquals("USER", entity.getScope()); + Assert.assertEquals("widget name", entity.getWidgetName()); + Assert.assertEquals("display_name", entity.getDisplayName()); + Assert.assertEquals("GAUGE", entity.getWidgetType()); + Assert.assertEquals("admin", entity.getAuthor()); + Assert.assertEquals("[{\"name\":\"value\",\"name2\":\"value2\"}]", entity.getMetrics()); + Assert.assertEquals("[{\"name\":\"value\",\"name2\":\"value2\"}]", entity.getWidgetValues()); + Assert.assertEquals("{\"property2\":\"value2\",\"property1\":\"value1\"}", entity.getProperties()); + + verify(amc, clusters, cluster, dao); + } + + /** + * @throws Exception + */ + @Test + public void testUpdateResources() throws Exception { + AmbariManagementController amc = createMock(AmbariManagementController.class); + Clusters clusters = createMock(Clusters.class); + Cluster cluster = createMock(Cluster.class); + expect(amc.getClusters()).andReturn(clusters).atLeastOnce(); + expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce(); + expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).atLeastOnce(); + + Capture<WidgetEntity> entityCapture = new Capture<WidgetEntity>(); + dao.create(capture(entityCapture)); + expectLastCall(); + + replay(amc, clusters, cluster, dao); + + Map<String, Object> requestProps = new HashMap<String, Object>(); + requestProps.put(WidgetResourceProvider.WIDGET_CLUSTER_NAME_PROPERTY_ID, "c1"); + requestProps.put(WidgetResourceProvider.WIDGET_WIDGET_NAME_PROPERTY_ID, "widget name"); + requestProps.put(WidgetResourceProvider.WIDGET_DISPLAY_NAME_PROPERTY_ID, "display_name"); + requestProps.put(WidgetResourceProvider.WIDGET_WIDGET_TYPE_PROPERTY_ID, "GAUGE"); + requestProps.put(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID, "admin"); + requestProps.put(WidgetResourceProvider.WIDGET_SCOPE_PROPERTY_ID, "USER"); + Set testSet = new LinkedHashSet(); + HashMap testMap = new HashMap(); + testMap.put("name","value"); + testMap.put("name2","value2"); + testSet.add(testMap); + requestProps.put(WidgetResourceProvider.WIDGET_METRICS_PROPERTY_ID, testSet); + requestProps.put(WidgetResourceProvider.WIDGET_VALUES_PROPERTY_ID, testSet); + requestProps.put(WidgetResourceProvider.WIDGET_PROPERTIES_PROPERTY_ID+"/property1", "value1"); + requestProps.put(WidgetResourceProvider.WIDGET_PROPERTIES_PROPERTY_ID+"/property2", "value2"); + + Request request = PropertyHelper.getCreateRequest( + Collections.singleton(requestProps), null); + + WidgetResourceProvider provider = createProvider(amc); + + provider.createResources(request); + + Assert.assertTrue(entityCapture.hasCaptured()); + WidgetEntity entity = entityCapture.getValue(); + Assert.assertNotNull(entity); + + Predicate predicate = new PredicateBuilder().property( + WidgetResourceProvider.WIDGET_CLUSTER_NAME_PROPERTY_ID).equals("c1") + .and().property(WidgetResourceProvider.WIDGET_ID_PROPERTY_ID).equals("1") + .and().property(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID).equals("username").toPredicate(); + + // everything is mocked, there is no DB + entity.setId(Long.valueOf(1)); + + String oldMetrics = entity.getMetrics(); + String oldProperties = entity.getProperties(); + String oldName = entity.getWidgetName(); + + resetToStrict(dao); + expect(dao.findById(1L)).andReturn(entity).anyTimes(); + expect(dao.merge((WidgetEntity) anyObject())).andReturn(entity).anyTimes(); + replay(dao); + + requestProps = new HashMap<String, Object>(); + requestProps.put(WidgetResourceProvider.WIDGET_ID_PROPERTY_ID, "1"); + requestProps.put(WidgetResourceProvider.WIDGET_CLUSTER_NAME_PROPERTY_ID, "c1"); + requestProps.put(WidgetResourceProvider.WIDGET_WIDGET_NAME_PROPERTY_ID, "widget name2"); + requestProps.put(WidgetResourceProvider.WIDGET_DISPLAY_NAME_PROPERTY_ID, "display_name"); + requestProps.put(WidgetResourceProvider.WIDGET_WIDGET_TYPE_PROPERTY_ID, "GAUGE"); + requestProps.put(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID, "admin"); + requestProps.put(WidgetResourceProvider.WIDGET_SCOPE_PROPERTY_ID, "USER"); + testSet = new LinkedHashSet(); + testMap = new HashMap(); + testMap.put("name","new_value"); + testMap.put("new_name","new_value2"); + testSet.add(testMap); + requestProps.put(WidgetResourceProvider.WIDGET_METRICS_PROPERTY_ID, testSet); + requestProps.put(WidgetResourceProvider.WIDGET_VALUES_PROPERTY_ID, testSet); + requestProps.put(WidgetResourceProvider.WIDGET_PROPERTIES_PROPERTY_ID+"/property1", "new_value1"); + requestProps.put(WidgetResourceProvider.WIDGET_PROPERTIES_PROPERTY_ID+"/new_property", "new_value2"); + + request = PropertyHelper.getUpdateRequest(requestProps, null); + + provider.updateResources(request, predicate); + + Assert.assertFalse(oldName.equals(entity.getWidgetName())); + Assert.assertFalse(oldMetrics.equals(entity.getMetrics())); + Assert.assertFalse(oldProperties.equals(entity.getProperties())); + Assert.assertEquals("[{\"name\":\"new_value\",\"new_name\":\"new_value2\"}]",entity.getMetrics()); + Assert.assertEquals("{\"new_property\":\"new_value2\",\"property1\":\"new_value1\"}",entity.getProperties()); + Assert.assertEquals("widget name2",entity.getWidgetName()); + Assert.assertEquals("display_name",entity.getDisplayName()); + + verify(amc, clusters, cluster, dao); + } + + /** + * @throws Exception + */ + @Test + public void testDeleteResources() throws Exception { + AmbariManagementController amc = createMock(AmbariManagementController.class); + Clusters clusters = createMock(Clusters.class); + Cluster cluster = createMock(Cluster.class); + expect(amc.getClusters()).andReturn(clusters).atLeastOnce(); + expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce(); + expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes(); + + Capture<WidgetEntity> entityCapture = new Capture<WidgetEntity>(); + dao.create(capture(entityCapture)); + expectLastCall(); + + replay(amc, clusters, cluster, dao); + + WidgetResourceProvider provider = createProvider(amc); + + Map<String, Object> requestProps = new HashMap<String, Object>(); + requestProps.put(WidgetResourceProvider.WIDGET_CLUSTER_NAME_PROPERTY_ID, "c1"); + requestProps.put(WidgetResourceProvider.WIDGET_WIDGET_NAME_PROPERTY_ID, "widget name"); + requestProps.put(WidgetResourceProvider.WIDGET_DISPLAY_NAME_PROPERTY_ID, "display_name"); + requestProps.put(WidgetResourceProvider.WIDGET_WIDGET_TYPE_PROPERTY_ID, "GAUGE"); + requestProps.put(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID, "admin"); + requestProps.put(WidgetResourceProvider.WIDGET_SCOPE_PROPERTY_ID, "USER"); + Set testSet = new LinkedHashSet(); + HashMap testMap = new HashMap(); + testMap.put("name","value"); + testMap.put("name2","value2"); + testSet.add(testMap); + requestProps.put(WidgetResourceProvider.WIDGET_METRICS_PROPERTY_ID, testSet); + requestProps.put(WidgetResourceProvider.WIDGET_VALUES_PROPERTY_ID, testSet); + requestProps.put(WidgetResourceProvider.WIDGET_PROPERTIES_PROPERTY_ID+"/property1", "value1"); + requestProps.put(WidgetResourceProvider.WIDGET_PROPERTIES_PROPERTY_ID+"/property2", "value2"); + + Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null); + + provider.createResources(request); + + Assert.assertTrue(entityCapture.hasCaptured()); + WidgetEntity entity = entityCapture.getValue(); + Assert.assertNotNull(entity); + + Predicate predicate = new PredicateBuilder().property( + WidgetResourceProvider.WIDGET_CLUSTER_NAME_PROPERTY_ID).equals("c1") + .and().property(WidgetResourceProvider.WIDGET_ID_PROPERTY_ID).equals("1") + .and().property(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID).equals("username").toPredicate(); + + // everything is mocked, there is no DB + entity.setId(Long.valueOf(1)); + + resetToStrict(dao); + expect(dao.findById(1L)).andReturn(entity).anyTimes(); + dao.remove(capture(entityCapture)); + expectLastCall(); + replay(dao); + + provider.deleteResources(predicate); + + WidgetEntity entity1 = entityCapture.getValue(); + Assert.assertEquals(Long.valueOf(1), entity1.getId()); + + verify(amc, clusters, cluster, dao); + } + + @Test + public void testScopePrivilegeCheck() throws Exception { + AmbariManagementController amc = createMock(AmbariManagementController.class); + Clusters clusters = createMock(Clusters.class); + Cluster cluster = createMock(Cluster.class); + expect(amc.getClusters()).andReturn(clusters).atLeastOnce(); + expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce(); + expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).atLeastOnce(); + WidgetResourceProvider widgetResourceProvider = PowerMock.createPartialMock(WidgetResourceProvider.class, "isScopeAllowedForUser"); + PowerMock.expectPrivate(widgetResourceProvider, "isScopeAllowedForUser", "CLUSTER").andReturn(false); + + Capture<WidgetEntity> entityCapture = new Capture<WidgetEntity>(); + dao.create(capture(entityCapture)); + expectLastCall(); + + replay(amc, clusters, cluster, dao); + PowerMock.replayAll(); + + Map<String, Object> requestProps = new HashMap<String, Object>(); + requestProps.put(WidgetResourceProvider.WIDGET_CLUSTER_NAME_PROPERTY_ID, "c1"); + requestProps.put(WidgetResourceProvider.WIDGET_WIDGET_NAME_PROPERTY_ID, "widget name"); + requestProps.put(WidgetResourceProvider.WIDGET_DISPLAY_NAME_PROPERTY_ID, "display_name"); + requestProps.put(WidgetResourceProvider.WIDGET_WIDGET_TYPE_PROPERTY_ID, "GAUGE"); + requestProps.put(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID, "admin"); + requestProps.put(WidgetResourceProvider.WIDGET_SCOPE_PROPERTY_ID, "CLUSTER"); + Request request = PropertyHelper.getCreateRequest( + Collections.singleton(requestProps), null); + + try { + widgetResourceProvider.createResources(request); + } catch (SystemException ex) { + //Expected exception + } + + } + + /** + * @param amc + * @return + */ + private WidgetResourceProvider createProvider(AmbariManagementController amc) { + return new WidgetResourceProvider(amc); + } + + /** + * @return + */ + private List<WidgetEntity> getMockEntities() throws Exception { + + WidgetEntity widgetEntity = new WidgetEntity(); + widgetEntity.setClusterId(Long.valueOf(1L)); + widgetEntity.setWidgetName("widget name"); + widgetEntity.setWidgetType("GAUGE"); + widgetEntity.setAuthor("username"); + widgetEntity.setScope("USER"); + widgetEntity.setDisplayName("displ_name"); + widgetEntity.setDescription("Description"); + widgetEntity.setMetrics("[{\"widget_id\":\"metrics/jvm/HeapMemoryUsed\"," + + "\"host_component_criteria\":\"host_components/metrics/dfs/FSNamesystem/HAState\\u003dactive\"," + + "\"service_name\":\"HDFS\",\"component_na\n" + + "me\":\"NAMENODE\",\"name\":\"java.lang:type\\u003dMemory.HeapMemoryUsage[used]\",\"category\":\"\"}," + + "{\"widget_id\":\"metrics/jvm/HeapMemoryMax\",\"host_component_criteria\":\"host_compone\n" + + "nts/metrics/dfs/FSNamesystem/HAState\\u003dactive\",\"service_name\":\"HDFS\"," + + "\"component_name\":\"NAMENODE\",\"name\":\"java.lang:type\\u003dMemory.HeapMemoryUsage[max]\"," + + "\"category\":\n\"\"}]"); + widgetEntity.setWidgetValues("[{\"name\":\"NameNode Heap\"," + + "\"value\":\"${java.lang:type\\u003dMemory.HeapMemoryUsage[used] / " + + "java.lang:type\\u003dMemory.HeapMemoryUsage[max]}\"}]"); + widgetEntity.setProperties("{\"name\":\"value\"}"); + return Arrays.asList(widgetEntity); + } + + /** + * + */ + private class MockModule implements Module { + /** + * + */ + @Override + public void configure(Binder binder) { + binder.bind(WidgetDAO.class).toInstance(dao); + binder.bind(Clusters.class).toInstance( + EasyMock.createNiceMock(Clusters.class)); + binder.bind(Cluster.class).toInstance( + EasyMock.createNiceMock(Cluster.class)); + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/2f2e3726/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java index 9d068f8..af9dcda 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java @@ -217,7 +217,7 @@ public class UpgradeCatalog210Test { } /** - * Verify that the user_widget, widget_layout, and widget_layout_user_widget tables are created correctly. + * Verify that the widget, widget_layout, and widget_layout_user_widget tables are created correctly. */ class WidgetSectionDDL implements SectionDDL { @@ -230,7 +230,7 @@ public class UpgradeCatalog210Test { Capture<List<DBColumnInfo>> widgetLayoutColumnsCapture = new Capture<List<DBColumnInfo>>(); Capture<List<DBColumnInfo>> widgetLayoutUserWidgetColumnsCapture = new Capture<List<DBColumnInfo>>(); - captures.put("user_widget", userWidgetColumnsCapture); + captures.put("widget", userWidgetColumnsCapture); captures.put("widget_layout", widgetLayoutColumnsCapture); captures.put("widget_layout_user_widget", widgetLayoutUserWidgetColumnsCapture); } @@ -240,12 +240,12 @@ public class UpgradeCatalog210Test { */ @Override public void execute(DBAccessor dbAccessor) throws SQLException { - Capture<List<DBColumnInfo>> userWidgetColumnsCapture = captures.get("user_widget"); + Capture<List<DBColumnInfo>> userWidgetColumnsCapture = captures.get("widget"); Capture<List<DBColumnInfo>> widgetLayoutColumnsCapture = captures.get("widget_layout"); Capture<List<DBColumnInfo>> widgetLayoutUserWidgetColumnsCapture = captures.get("widget_layout_user_widget"); // User Widget - dbAccessor.createTable(eq("user_widget"), + dbAccessor.createTable(eq("widget"), capture(userWidgetColumnsCapture), eq("id")); // Widget Layout @@ -254,7 +254,7 @@ public class UpgradeCatalog210Test { // Widget Layout User Widget dbAccessor.createTable(eq("widget_layout_user_widget"), - capture(widgetLayoutUserWidgetColumnsCapture), eq("widget_layout_id"), eq("user_widget_id")); + capture(widgetLayoutUserWidgetColumnsCapture), eq("widget_layout_id"), eq("widget_id")); } /** @@ -262,12 +262,12 @@ public class UpgradeCatalog210Test { */ @Override public void verify(DBAccessor dbAccessor) throws SQLException { - Capture<List<DBColumnInfo>> userWidgetColumnsCapture = captures.get("user_widget"); + Capture<List<DBColumnInfo>> widgetColumnsCapture = captures.get("widget"); Capture<List<DBColumnInfo>> widgetLayoutColumnsCapture = captures.get("widget_layout"); Capture<List<DBColumnInfo>> widgetLayoutUserWidgetColumnsCapture = captures.get("widget_layout_user_widget"); // Verify widget tables - assertEquals(12, userWidgetColumnsCapture.getValue().size()); + assertEquals(12, widgetColumnsCapture.getValue().size()); assertEquals(7, widgetLayoutColumnsCapture.getValue().size()); assertEquals(3, widgetLayoutUserWidgetColumnsCapture.getValue().size()); }
