Shubhendu Tripathi has uploaded a new change for review. Change subject: restapi: REST apis for gluster SWIFT maintenance ......................................................................
restapi: REST apis for gluster SWIFT maintenance REST APIs for gluster SWIFT maitenance Change-Id: I87cb354e10fed21cbd18b874595b726d3ac018a6 Signed-off-by: Shubhendu Tripathi <[email protected]> --- M backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/LinkHelper.java M backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/HostResource.java A backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterServiceResource.java A backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterServicesResource.java M backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostResource.java M backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostsResource.java A backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServiceResource.java A backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServicesResource.java A backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServiceResourceTest.java A backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServicesResourceTest.java A backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/GlusterServiceMapper.java 12 files changed, 708 insertions(+), 35 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/91/16691/1 diff --git a/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/LinkHelper.java b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/LinkHelper.java index 8c33f3b..deaf5eb 100644 --- a/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/LinkHelper.java +++ b/backend/manager/modules/restapi/interface/common/jaxrs/src/main/java/org/ovirt/engine/api/common/util/LinkHelper.java @@ -40,6 +40,7 @@ import org.ovirt.engine.api.model.Event; import org.ovirt.engine.api.model.File; import org.ovirt.engine.api.model.GlusterBrick; +import org.ovirt.engine.api.model.GlusterService; import org.ovirt.engine.api.model.GlusterVolume; import org.ovirt.engine.api.model.Group; import org.ovirt.engine.api.model.Hook; @@ -146,6 +147,8 @@ import org.ovirt.engine.api.resource.VmsResource; import org.ovirt.engine.api.resource.gluster.GlusterBrickResource; import org.ovirt.engine.api.resource.gluster.GlusterBricksResource; +import org.ovirt.engine.api.resource.gluster.GlusterServiceResource; +import org.ovirt.engine.api.resource.gluster.GlusterServicesResource; import org.ovirt.engine.api.resource.gluster.GlusterVolumeResource; import org.ovirt.engine.api.resource.gluster.GlusterVolumesResource; @@ -316,6 +319,9 @@ map = new ParentToCollectionMap(CapabiliyResource.class, CapabilitiesResource.class); TYPES.put(VersionCaps.class, map); + + map = new ParentToCollectionMap(GlusterServiceResource.class, GlusterServicesResource.class, Host.class); + TYPES.put(GlusterService.class, map); } /** diff --git a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/HostResource.java b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/HostResource.java index c833c22..6681b06 100644 --- a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/HostResource.java +++ b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/HostResource.java @@ -16,22 +16,24 @@ package org.ovirt.engine.api.resource; -import javax.ws.rs.Path; +import javax.ws.rs.Consumes; import javax.ws.rs.POST; +import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; -import org.jboss.resteasy.annotations.providers.jaxb.Formatted; +import org.jboss.resteasy.annotations.providers.jaxb.Formatted; import org.ovirt.engine.api.model.Action; import org.ovirt.engine.api.model.Actionable; import org.ovirt.engine.api.model.Host; +import org.ovirt.engine.api.resource.gluster.GlusterServicesResource; @Produces({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, ApiMediaType.APPLICATION_X_YAML}) public interface HostResource extends UpdatableResource<Host>, MeasurableResource { - @Path("{action: (approve|install|fence|activate|deactivate|commitnetconfig|iscsidiscover|iscsilogin)}/{oid}") + @Path("{action: (approve|install|fence|activate|deactivate|commitnetconfig|iscsidiscover|iscsilogin|glusterservicestart|glusterservicestop|glusterservicerestart)}/{oid}") public ActionResource getActionSubresource(@PathParam("action")String action, @PathParam("oid")String oid); @POST @@ -82,6 +84,27 @@ @Path("iscsilogin") public Response iscsiLogin(Action action); + @POST + @Formatted + @Consumes({ ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, ApiMediaType.APPLICATION_X_YAML }) + @Actionable + @Path("glusterservicestart") + public Response glusterServiceStart(Action action); + + @POST + @Formatted + @Consumes({ ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, ApiMediaType.APPLICATION_X_YAML }) + @Actionable + @Path("glusterservicestop") + public Response glusterServiceStop(Action action); + + @POST + @Formatted + @Consumes({ ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, ApiMediaType.APPLICATION_X_YAML }) + @Actionable + @Path("glusterservicerestart") + public Response glusterServiceReStart(Action action); + @Path("nics") public HostNicsResource getHostNicsResource(); @@ -96,4 +119,7 @@ @Path("permissions") public AssignedPermissionsResource getPermissionsResource(); + + @Path("glusterservices") + public GlusterServicesResource getGlusterServicesResource(); } diff --git a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterServiceResource.java b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterServiceResource.java new file mode 100644 index 0000000..d1a7116 --- /dev/null +++ b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterServiceResource.java @@ -0,0 +1,18 @@ +package org.ovirt.engine.api.resource.gluster; + +import javax.ws.rs.GET; +import javax.ws.rs.Produces; + +import org.jboss.resteasy.annotations.providers.jaxb.Formatted; +import org.ovirt.engine.api.model.GlusterService; +import org.ovirt.engine.api.resource.ApiMediaType; + +/** + * Resource interface for the "hosts/{host_id}/glusterservices/{service_id}" resource + */ +@Produces({ ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, ApiMediaType.APPLICATION_X_YAML }) +public interface GlusterServiceResource { + @GET + @Formatted + public GlusterService get(); +} diff --git a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterServicesResource.java b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterServicesResource.java new file mode 100644 index 0000000..1c9a005 --- /dev/null +++ b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/resource/gluster/GlusterServicesResource.java @@ -0,0 +1,34 @@ +/** + * + */ +package org.ovirt.engine.api.resource.gluster; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; + +import org.jboss.resteasy.annotations.providers.jaxb.Formatted; +import org.ovirt.engine.api.model.GlusterServices; +import org.ovirt.engine.api.resource.ApiMediaType; + +/** + * Resource interface for the "hosts/{host_id}/glusterservices" resource + */ +@Produces({ ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON, ApiMediaType.APPLICATION_X_YAML }) +public interface GlusterServicesResource { + @GET + @Formatted + public GlusterServices list(); + + /** + * Sub-resource locator method, returns individual GlusterServiceResource on which the remainder of the URI is + * dispatched. + * + * @param service_id + * the service id + * @return matching subresource if found + */ + @Path("{service_id}") + public GlusterServiceResource getGlusterServiceSubResource(@PathParam("service_id") String id); +} diff --git a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd index 108bca9..91237d6 100644 --- a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd +++ b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd @@ -179,6 +179,8 @@ <xs:element name="detach" type="xs:boolean" minOccurs="0"/> <!-- import Vm/Template as new entity --> <xs:element name="clone" type="xs:boolean" minOccurs="0" maxOccurs="1"/> + <!-- In gluster service start/stop/restart needs type of services --> + <xs:element name="gluster_service_type" type="xs:string" minOccurs="0" maxOccurs="1"/> <!-- ... etc., explicitly enumerate all the parameter types --> </xs:sequence> </xs:group> @@ -1281,6 +1283,7 @@ <xs:element name="libvirt_version" type="Version" minOccurs="0" maxOccurs="1"/> <!-- Optionally specify the display address of this host explicitly --> <xs:element ref="display" minOccurs="0"/> + <xs:element ref="glusterservices" minOccurs="0"/> </xs:sequence> </xs:extension> </xs:complexContent> @@ -1673,6 +1676,41 @@ </xs:complexContent> </xs:complexType> + <xs:element name="glusterservice" type="GlusterService"/> + + <xs:element name="glusterservices" type="GlusterServices"/> + + <xs:complexType name="GlusterService"> + <xs:annotation> + <xs:appinfo> + <jaxb:class name="GlusterService"/> + </xs:appinfo> + </xs:annotation> + <xs:complexContent> + <xs:extension base="BaseResource"> + <xs:sequence> + <xs:element ref="host" minOccurs="0"/> + <xs:element name="status" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:complexType name="GlusterServices"> + <xs:complexContent> + <xs:extension base="BaseResources"> + <xs:sequence> + <xs:annotation> + <xs:appinfo> + <jaxb:property name="GlusterServices"/> + </xs:appinfo> + </xs:annotation> + <xs:element ref="glusterservice" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <!-- Networks --> <xs:element name="ip" type="IP"/> diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostResource.java index 9918efa..34bc17f 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostResource.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostResource.java @@ -25,6 +25,7 @@ import org.ovirt.engine.api.resource.HostResource; import org.ovirt.engine.api.resource.HostStorageResource; import org.ovirt.engine.api.resource.StatisticsResource; +import org.ovirt.engine.api.restapi.resource.gluster.BackendGlusterServicesResource; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.ApproveVdsParameters; import org.ovirt.engine.core.common.action.ChangeVDSClusterParameters; @@ -36,6 +37,7 @@ import org.ovirt.engine.core.common.action.VdcActionParametersBase; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdsActionParameters; +import org.ovirt.engine.core.common.action.gluster.GlusterServiceParameters; import org.ovirt.engine.core.common.businessentities.FenceActionType; import org.ovirt.engine.core.common.businessentities.FenceStatusReturnValue; import org.ovirt.engine.core.common.businessentities.StorageServerConnections; @@ -43,6 +45,7 @@ import org.ovirt.engine.core.common.businessentities.VDSGroup; import org.ovirt.engine.core.common.businessentities.VDSType; import org.ovirt.engine.core.common.businessentities.VdsStatic; +import org.ovirt.engine.core.common.businessentities.gluster.ServiceType; import org.ovirt.engine.core.common.interfaces.SearchType; import org.ovirt.engine.core.common.queries.DiscoverSendTargetsQueryParameters; import org.ovirt.engine.core.common.queries.GetPermissionsForObjectParameters; @@ -51,13 +54,12 @@ import org.ovirt.engine.core.common.queries.VdsIdParametersBase; import org.ovirt.engine.core.compat.Guid; - public class BackendHostResource extends AbstractBackendActionableResource<Host, VDS> implements HostResource { private static final String DEFAULT_ISCSI_PORT = "3260"; - private BackendHostsResource parent; + private final BackendHostsResource parent; public BackendHostResource(String id, BackendHostsResource parent) { super(id, Host.class, VDS.class, SUB_COLLECTIONS); @@ -77,7 +79,8 @@ @Override public Host update(Host incoming) { validateEnums(Host.class, incoming); - QueryIdResolver<Guid> hostResolver = new QueryIdResolver<Guid>(VdcQueryType.GetVdsByVdsId, IdQueryParameters.class); + QueryIdResolver<Guid> hostResolver = + new QueryIdResolver<Guid>(VdcQueryType.GetVdsByVdsId, IdQueryParameters.class); VDS entity = getEntity(hostResolver, true); if (incoming.isSetCluster() && (incoming.getCluster().isSetId() || incoming.getCluster().isSetName())) { Guid clusterId = lookupClusterId(incoming); @@ -87,19 +90,20 @@ } } return performUpdate(incoming, - entity, - map(entity), - hostResolver, - VdcActionType.UpdateVds, - new UpdateParametersProvider()); + entity, + map(entity), + hostResolver, + VdcActionType.UpdateVds, + new UpdateParametersProvider()); } @Override public Response install(Action action) { // REVISIT fencing options VDS vds = getEntity(); - UpdateVdsActionParameters params = new UpdateVdsActionParameters(vds.getStaticData(), action.getRootPassword(), true); - if (vds.getVdsType()==VDSType.oVirtNode) { + UpdateVdsActionParameters params = + new UpdateVdsActionParameters(vds.getStaticData(), action.getRootPassword(), true); + if (vds.getVdsType() == VDSType.oVirtNode) { params.setIsReinstallOrUpgrade(true); if (action.isSetImage()) { params.setoVirtIsoFile(action.getImage()); @@ -108,15 +112,15 @@ validateParameters(action, "rootPassword"); } return doAction(VdcActionType.UpdateVds, - params, - action); + params, + action); } @Override public Response activate(Action action) { return doAction(VdcActionType.ActivateVds, - new VdsActionParameters(guid), - action); + new VdsActionParameters(guid), + action); } @Override @@ -127,8 +131,8 @@ } return doAction(VdcActionType.ApproveVds, - new ApproveVdsParameters(guid), - action); + new ApproveVdsParameters(guid), + action); } private Host setCluster(Host host, Cluster cluster) { @@ -143,8 +147,8 @@ protected Guid lookupClusterId(Host host) { return host.getCluster().isSetId() ? asGuid(host.getCluster().getId()) - : - lookupClusterByName(host.getCluster().getName()).getId(); + : + lookupClusterByName(host.getCluster().getName()).getId(); } protected VDSGroup lookupClusterByName(String name) { @@ -154,8 +158,8 @@ @Override public Response deactivate(Action action) { return doAction(VdcActionType.MaintenanceNumberOfVdss, - new MaintenanceNumberOfVdssParameters(asList(guid), false), - action); + new MaintenanceNumberOfVdssParameters(asList(guid), false), + action); } @Override @@ -177,7 +181,8 @@ if (iscsiDetails.isSetPassword()) { cnx.setpassword(iscsiDetails.getPassword()); } - cnx.setportal("0");//TODO: when VSDM and Backend will support this, we will need to externalize this parameter to the user + cnx.setportal("0");// TODO: when VSDM and Backend will support this, we will need to externalize this parameter + // to the user StorageServerConnectionParametersBase connectionParms = new StorageServerConnectionParametersBase(cnx, guid); return doAction(VdcActionType.ConnectStorageToVds, connectionParms, action); } @@ -187,8 +192,8 @@ validateParameters(action, "iscsi.address"); List<StorageServerConnections> result = getBackendCollection(StorageServerConnections.class, - VdcQueryType.DiscoverSendTargets, - createDiscoveryQueryParams(action)); + VdcQueryType.DiscoverSendTargets, + createDiscoveryQueryParams(action)); return actionSuccess(mapTargets(action, result)); } @@ -200,6 +205,30 @@ } } return action; + } + + @Override + public Response glusterServiceStart(Action action) { + return doAction(VdcActionType.ManageGlusterService, new GlusterServiceParameters(null, + guid, + ServiceType.valueOf(action.getGlusterServiceType()), + "start"), action); + } + + @Override + public Response glusterServiceStop(Action action) { + return doAction(VdcActionType.ManageGlusterService, new GlusterServiceParameters(null, + guid, + ServiceType.valueOf(action.getGlusterServiceType()), + "stop"), action); + } + + @Override + public Response glusterServiceReStart(Action action) { + return doAction(VdcActionType.ManageGlusterService, new GlusterServiceParameters(null, + guid, + ServiceType.valueOf(action.getGlusterServiceType()), + "restart"), action); } protected LogicalUnit map(StorageServerConnections cnx) { @@ -228,8 +257,8 @@ @Override public Response commitNetConfig(Action action) { return doAction(VdcActionType.CommitNetworkChanges, - new VdsActionParameters(guid), - action); + new VdsActionParameters(guid), + action); } @Override @@ -255,7 +284,11 @@ } private Response getFencingStatus(Action action) { - FenceStatusReturnValue result = getEntity(FenceStatusReturnValue.class, VdcQueryType.GetVdsFenceStatus, new VdsIdParametersBase(guid), guid.toString()); + FenceStatusReturnValue result = + getEntity(FenceStatusReturnValue.class, + VdcQueryType.GetVdsFenceStatus, + new VdsIdParametersBase(guid), + guid.toString()); if (result.getIsSucceeded()) { PowerManagement pm = new PowerManagement(); pm.setStatus(result.getStatus().toLowerCase().equals("on") ? StatusUtils.create(PowerManagementStatus.ON) @@ -305,15 +338,16 @@ @Override public AssignedPermissionsResource getPermissionsResource() { return inject(new BackendAssignedPermissionsResource(guid, - VdcQueryType.GetPermissionsForObject, - new GetPermissionsForObjectParameters(guid), - Host.class, - VdcObjectType.VDS)); + VdcQueryType.GetPermissionsForObject, + new GetPermissionsForObjectParameters(guid), + Host.class, + VdcObjectType.VDS)); } @Override public StatisticsResource getStatisticsResource() { - EntityIdResolver<Guid> resolver = new QueryIdResolver<Guid>(VdcQueryType.GetVdsByVdsId, IdQueryParameters.class); + EntityIdResolver<Guid> resolver = + new QueryIdResolver<Guid>(VdcQueryType.GetVdsByVdsId, IdQueryParameters.class); HostStatisticalQuery query = new HostStatisticalQuery(resolver, newModel(id)); return inject(new BackendStatisticsResource<Host, VDS>(entityType, guid, query)); } @@ -362,4 +396,10 @@ public BackendHostHooksResource getHooksResource() { return inject(new BackendHostHooksResource(id)); } + + @Override + @Path("glusterservices") + public BackendGlusterServicesResource getGlusterServicesResource() { + return inject(new BackendGlusterServicesResource(this, id)); + } } diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostsResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostsResource.java index 0310821..5f2a176 100644 --- a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostsResource.java +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostsResource.java @@ -33,7 +33,7 @@ public class BackendHostsResource extends AbstractBackendCollectionResource<Host, VDS> implements HostsResource { - static final String[] SUB_COLLECTIONS = { "storage", "nics", "tags", "permissions", "statistics", "hooks" }; + static final String[] SUB_COLLECTIONS = { "storage", "nics", "tags", "permissions", "statistics", "hooks", "glusterservices" }; static final String GLUSTERONLY_MODE_COLLECTIONS_TO_HIDE = "storage"; public BackendHostsResource() { diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServiceResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServiceResource.java new file mode 100644 index 0000000..91dabd0 --- /dev/null +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServiceResource.java @@ -0,0 +1,72 @@ +package org.ovirt.engine.api.restapi.resource.gluster; + +import org.ovirt.engine.api.model.GlusterService; +import org.ovirt.engine.api.model.GlusterServices; +import org.ovirt.engine.api.resource.gluster.GlusterServiceResource; +import org.ovirt.engine.api.restapi.resource.AbstractBackendActionableResource; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterServerService; + +/** + * Implementation of the "glusterservices/{service_id}" resource + */ +public class BackendGlusterServiceResource + extends AbstractBackendActionableResource<GlusterService, GlusterServerService> + implements GlusterServiceResource { + + private BackendGlusterServicesResource parent; + + public BackendGlusterServiceResource(String id) { + super(id, GlusterService.class, GlusterServerService.class); + } + + public BackendGlusterServiceResource(String id, BackendGlusterServicesResource parent) { + this(id); + this.parent = parent; + } + + @Override + protected GlusterService addParents(GlusterService model) { + model.setId(id); + parent.addParents(model); + return model; + } + + @Override + public GlusterService get() { + GlusterServices serviceRes = getParent().list(); + if (serviceRes != null) { + for (GlusterService srvc : serviceRes.getGlusterServices()) { + if (srvc.getId().equals(id)) { + return srvc; + } + } + } + return notFound(); + } + + public GlusterService getGlusterService(GlusterServices services) { + for (GlusterService srvc : services.getGlusterServices()) { + if (srvc.getId().equals(id)) { + return srvc; + } + } + return notFound(); + } + + public BackendGlusterServicesResource getParent() { + return parent; + } + + public void setParent(BackendGlusterServicesResource parent) { + this.parent = parent; + } + + @Override + protected GlusterService doPopulate(GlusterService model, GlusterServerService entity) { + return model; + } + + public String getId() { + return this.id; + } +} diff --git a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServicesResource.java b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServicesResource.java new file mode 100644 index 0000000..71fb5ac --- /dev/null +++ b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServicesResource.java @@ -0,0 +1,83 @@ +package org.ovirt.engine.api.restapi.resource.gluster; + +import java.util.List; + +import javax.ws.rs.core.Response; + +import org.ovirt.engine.api.model.GlusterService; +import org.ovirt.engine.api.model.GlusterServices; +import org.ovirt.engine.api.model.Host; +import org.ovirt.engine.api.resource.gluster.GlusterServiceResource; +import org.ovirt.engine.api.resource.gluster.GlusterServicesResource; +import org.ovirt.engine.api.restapi.resource.AbstractBackendCollectionResource; +import org.ovirt.engine.api.restapi.resource.BackendHostResource; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterServerService; +import org.ovirt.engine.core.common.queries.VdcQueryType; +import org.ovirt.engine.core.common.queries.gluster.GlusterServiceQueryParameters; + +/** + * Implementation of the "glusterservices" resource + */ +public class BackendGlusterServicesResource + extends AbstractBackendCollectionResource<GlusterService, GlusterServerService> + implements GlusterServicesResource { + + private BackendHostResource parent; + private String serverId; + + public BackendGlusterServicesResource() { + super(GlusterService.class, GlusterServerService.class, new String[0]); + } + + public BackendGlusterServicesResource(BackendHostResource parent, String serverId) { + this(); + this.serverId = serverId; + setParent(parent); + } + + public BackendHostResource getParent() { + return parent; + } + + public void setParent(BackendHostResource parent) { + this.parent = parent; + } + + @Override + public GlusterServices list() { + List<GlusterServerService> services = + getBackendCollection(VdcQueryType.GetGlusterServerServicesByServerId, + new GlusterServiceQueryParameters(asGuid(serverId))); + return mapCollection(services); + } + + private GlusterServices mapCollection(List<GlusterServerService> entities) { + GlusterServices collection = new GlusterServices(); + for (GlusterServerService entity : entities) { + collection.getGlusterServices().add(addLinks(populate(map(entity), entity))); + } + return collection; + } + + @Override + protected GlusterService addParents(GlusterService service) { + service.setHost(new Host()); + service.getHost().setId(serverId); + return service; + } + + @Override + public GlusterServiceResource getGlusterServiceSubResource(String id) { + return inject(new BackendGlusterServiceResource(id, this)); + } + + @Override + protected GlusterService doPopulate(GlusterService model, GlusterServerService entity) { + return model; + } + + @Override + protected Response performRemove(String id) { + return null; + } +} diff --git a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServiceResourceTest.java b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServiceResourceTest.java new file mode 100644 index 0000000..ce3e804 --- /dev/null +++ b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServiceResourceTest.java @@ -0,0 +1,143 @@ +package org.ovirt.engine.api.restapi.resource.gluster; + +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.isA; +import static org.ovirt.engine.api.restapi.resource.gluster.BackendGlusterServicesResourceTest.setUpEntityExpectations; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.UriInfo; + +import org.junit.Test; +import org.ovirt.engine.api.model.GlusterService; +import org.ovirt.engine.api.model.GlusterServices; +import org.ovirt.engine.api.model.Host; +import org.ovirt.engine.api.restapi.resource.AbstractBackendSubResourceTest; +import org.ovirt.engine.api.restapi.resource.BackendHostResource; +import org.ovirt.engine.core.common.action.VdcActionParametersBase; +import org.ovirt.engine.core.common.action.VdcActionType; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterServerService; +import org.ovirt.engine.core.common.queries.VdcQueryType; +import org.ovirt.engine.core.common.queries.gluster.GlusterServiceQueryParameters; +import org.ovirt.engine.core.compat.Guid; + +public class BackendGlusterServiceResourceTest extends AbstractBackendSubResourceTest<GlusterService, GlusterServerService, BackendGlusterServiceResource> { + private static final Guid serverId = GUIDS[0]; + private static final String defaultServerName = "Default"; + private BackendHostResource hostResourceMock; + private BackendGlusterServicesResource servicesResourceMock1; + private BackendGlusterServicesResource servicesResourceMock2; + + public BackendGlusterServiceResourceTest() { + super(new BackendGlusterServiceResource(GUIDS[0].toString())); + } + + @Test + public void testGet() throws Exception { + setupParentExpectations(); + setUriInfo(setUpBasicUriExpectations()); + setUpGetEntityExpectations(0); + resource.setParent(servicesResourceMock1); + control.replay(); + + verifyModel(resource.get(), 0); + } + + @Test + public void testGetNotFound() throws Exception { + setupParentExpectations(); + setUriInfo(setUpBasicUriExpectations()); + setUpGetEntityExpectations(0); + resource.setParent(servicesResourceMock2); + control.replay(); + try { + resource.get(); + fail("expected WebApplicationException"); + } catch (WebApplicationException wae) { + verifyNotFoundException(wae); + } + } + + protected UriInfo setUpActionExpectations(VdcActionType task, + Class<? extends VdcActionParametersBase> clz, + String[] names, + Object[] values) { + return setUpActionExpectations(task, clz, names, values, true, true, null, null, true); + } + + @Override + protected GlusterServerService getEntity(int index) { + return setUpEntityExpectations(control.createMock(GlusterServerService.class), index); + } + + /** + * Overridden as {@link GlusterServerService} does not have description field + */ + @Override + protected void verifyModel(GlusterService model, int index) { + assertEquals(GUIDS[index].toString(), model.getId()); + assertEquals(NAMES[index], model.getName()); + assertEquals(serverId.toString(), model.getHost().getId()); + verifyLinks(model); + } + + protected void setUpGetEntityExpectations(int times) throws Exception { + setUpGetEntityExpectations(times, false); + } + + protected void setUpGetEntityExpectations(int times, boolean notFound) throws Exception { + while (times-- > 0) { + setUpGetEntityExpectations(VdcQueryType.GetGlusterServerServicesByServerId, + GlusterServiceQueryParameters.class, + new String[] { "Id" }, + new Object[] { serverId }, + notFound ? null : getEntity(0)); + } + } + + private void setupParentExpectations() { + Host host = new Host(); + host.setName(defaultServerName); + host.setId(serverId.toString()); + + hostResourceMock = control.createMock(BackendHostResource.class); + expect(hostResourceMock.get()).andReturn(host).anyTimes(); + + servicesResourceMock1 = control.createMock(BackendGlusterServicesResource.class); + servicesResourceMock2 = control.createMock(BackendGlusterServicesResource.class); + expect(servicesResourceMock1.getParent()).andReturn(hostResourceMock).anyTimes(); + expect(servicesResourceMock2.getParent()).andReturn(hostResourceMock).anyTimes(); + expect(servicesResourceMock1.list()).andDelegateTo( + new BackendGlusterServicesResource() { + @Override + public GlusterServices list() { + Host host = new Host(); + host.setId(serverId.toString()); + GlusterService srvc = new GlusterService(); + srvc.setId(GUIDS[0].toString()); + srvc.setName(NAMES[0]); + srvc.setHost(host); + srvc.setHref("/api/hosts/" + serverId.toString() + "/glusterservices/" + GUIDS[0].toString()); + GlusterServices srvcs = new GlusterServices(); + srvcs.getGlusterServices().add(srvc); + return srvcs; + } + }).anyTimes(); + expect(servicesResourceMock2.list()).andDelegateTo( + new BackendGlusterServicesResource() { + @Override + public GlusterServices list() { + return null; + } + }).anyTimes(); + expect(servicesResourceMock1.addParents(isA(GlusterService.class))).andDelegateTo( + new BackendGlusterServicesResource() { + @Override + protected GlusterService addParents(GlusterService model) { + Host host = new Host(); + host.setId(serverId.toString()); + model.setHost(host); + return model; + } + }).anyTimes(); + } +} diff --git a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServicesResourceTest.java b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServicesResourceTest.java new file mode 100644 index 0000000..2c24cf6 --- /dev/null +++ b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/gluster/BackendGlusterServicesResourceTest.java @@ -0,0 +1,181 @@ +package org.ovirt.engine.api.restapi.resource.gluster; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expect; + +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.UriInfo; + +import org.junit.Test; +import org.ovirt.engine.api.model.Fault; +import org.ovirt.engine.api.model.GlusterService; +import org.ovirt.engine.api.model.Host; +import org.ovirt.engine.api.restapi.resource.AbstractBackendCollectionResourceTest; +import org.ovirt.engine.api.restapi.resource.BackendHostResource; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterServerService; +import org.ovirt.engine.core.common.queries.VdcQueryReturnValue; +import org.ovirt.engine.core.common.queries.VdcQueryType; +import org.ovirt.engine.core.common.queries.gluster.GlusterParameters; +import org.ovirt.engine.core.compat.Guid; + +public class BackendGlusterServicesResourceTest extends AbstractBackendCollectionResourceTest<GlusterService, GlusterServerService, BackendGlusterServicesResource> { + private static final Guid serverId = GUIDS[0]; + private static final String defaultServerName = "Default"; + private static BackendHostResource parentMock; + + public BackendGlusterServicesResourceTest() { + super(new BackendGlusterServicesResource(parentMock, serverId.toString()), null, null); + } + + /** + * Override init to perform additional mocking required for the "list" method of the collection resource. + */ + @Override + protected void init() { + super.init(); + parentMock = control.createMock(BackendHostResource.class); + collection.setParent(parentMock); + setupListExpectations(); + } + + @Override + public void testList() throws Exception { + setUpGlusterServicesQueryExpectations(null); + UriInfo uriInfo = setUpUriExpectations(null); + collection.setUriInfo(uriInfo); + control.replay(); + + verifyCollection(getCollection()); + } + + @Override + public void testListCrash() throws Exception { + UriInfo uriInfo = setUpUriExpectations(null); + collection.setUriInfo(uriInfo); + + Throwable t = new RuntimeException(FAILURE); + setUpGlusterServicesQueryExpectations(t); + control.replay(); + + try { + getCollection(); + fail("expected WebApplicationException"); + } catch (WebApplicationException wae) { + verifyFault(wae, BACKEND_FAILED_SERVER_LOCALE, t); + } + } + + /** + * Overriding this as gluster hooks collection doesn't support search queries + */ + @Override + @Test + public void testQuery() throws Exception { + testList(); + } + + @Override + public void testListCrashClientLocale() throws Exception { + collection.setUriInfo(setUpUriExpectations(null)); + locales.add(CLIENT_LOCALE); + + Throwable t = new RuntimeException(FAILURE); + setUpGlusterServicesQueryExpectations(t); + control.replay(); + + try { + getCollection(); + fail("expected WebApplicationException"); + } catch (WebApplicationException wae) { + verifyFault(wae, BACKEND_FAILED_CLIENT_LOCALE, t); + } finally { + locales.clear(); + } + } + + @Override + public void testListFailure() throws Exception { + collection.setUriInfo(setUpUriExpectations(null)); + + setUpGlusterServicesQueryExpectations(FAILURE); + control.replay(); + + try { + getCollection(); + fail("expected WebApplicationException"); + } catch (WebApplicationException wae) { + assertTrue(wae.getResponse().getEntity() instanceof Fault); + assertEquals(mockl10n(FAILURE), ((Fault) wae.getResponse().getEntity()).getDetail()); + } + } + + @Override + protected List<GlusterService> getCollection() { + return collection.list().getGlusterServices(); + } + + @Override + protected GlusterServerService getEntity(int index) { + return setUpEntityExpectations( + control.createMock(GlusterServerService.class), + index); + } + + /** + * Overridden as {@link GlusterServerService} does not have description field + */ + @Override + protected void verifyModel(GlusterService model, int index) { + assertEquals(GUIDS[index].toString(), model.getId()); + assertEquals(NAMES[index], model.getName()); + assertEquals(serverId.toString(), model.getHost().getId()); + verifyLinks(model); + } + + static GlusterServerService setUpEntityExpectations(GlusterServerService entity, int index) { + expect(entity.getId()).andReturn(GUIDS[index]).anyTimes(); + expect(entity.getServiceName()).andReturn(NAMES[index]).anyTimes(); + expect(entity.getServerId()).andReturn(serverId).anyTimes(); + return entity; + } + + private void setupListExpectations() { + Host host = new Host(); + host.setName(defaultServerName); + host.setId(serverId.toString()); + + parentMock = control.createMock(BackendHostResource.class); + expect(parentMock.get()).andReturn(host).anyTimes(); + } + + private void setUpGlusterServicesQueryExpectations(Object failure) { + VdcQueryReturnValue queryResult = control.createMock(VdcQueryReturnValue.class); + expect(queryResult.getSucceeded()).andReturn(failure == null).anyTimes(); + List<GlusterServerService> entities = new ArrayList<GlusterServerService>(); + + if (failure == null) { + for (int i = 0; i < NAMES.length; i++) { + entities.add(getEntity(i)); + } + expect(queryResult.getReturnValue()).andReturn(entities).anyTimes(); + } else { + if (failure instanceof String) { + expect(queryResult.getExceptionString()).andReturn((String) failure).anyTimes(); + setUpL10nExpectations((String) failure); + } else if (failure instanceof Exception) { + expect(backend.RunQuery(eq(VdcQueryType.GetGlusterServerServicesByServerId), + anyObject(GlusterParameters.class))).andThrow((Exception) failure).anyTimes(); + return; + } + } + expect(backend.RunQuery(eq(VdcQueryType.GetGlusterServerServicesByServerId), anyObject(GlusterParameters.class))).andReturn( + queryResult) + .anyTimes(); + + } + +} diff --git a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/GlusterServiceMapper.java b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/GlusterServiceMapper.java new file mode 100644 index 0000000..e2527e3 --- /dev/null +++ b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/GlusterServiceMapper.java @@ -0,0 +1,32 @@ +package org.ovirt.engine.api.restapi.types; + +import org.ovirt.engine.api.model.GlusterService; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterServerService; + +/** + * Mapper for mapping between the REST model class {@link GlusterService} and the business entity class + * {@link GlusterServerService} + * + * @see GlusterService + * @see GlusterServerService + */ +public class GlusterServiceMapper { + @Mapping(from = GlusterServerService.class, to = GlusterService.class) + public static GlusterService map(GlusterServerService fromService, GlusterService toService) { + GlusterService service = (toService == null) ? new GlusterService() : toService; + + if(fromService.getId() != null) { + service.setId(fromService.getId().toString()); + } + + if(fromService.getServiceName() != null) { + service.setName(fromService.getServiceName()); + } + + if(fromService.getStatus() != null) { + service.setStatus(fromService.getStatus().name()); + } + + return service; + } +} -- To view, visit http://gerrit.ovirt.org/16691 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I87cb354e10fed21cbd18b874595b726d3ac018a6 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Shubhendu Tripathi <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
