Ori Liel has uploaded a new change for review.

Change subject: restapi: Return Additional Info For 400 Messages (#867794)
......................................................................

restapi: Return Additional Info For 400 Messages (#867794)

When user issues a POST or PUT request, and the body is malformed,
the application will identify, according to the context, what the user
was trying to do, and return the correct usage from RSDL.

This patch includes work to make RsdlBuilder a stand-alone tool
which does not require the application server. The solution does
not require this direcly, but it is better structured this way.

Right now the solution does not apply for YAML format, because of
other issues we have with Yaml format, but it can very easily be
used also for Yaml in the future.

Bug-Url: http://bugzilla.redhat.com/867794
Change-Id: Ic7a6da4fbb00ea5f1e6919ddfe21dd7b3dd126fd
Signed-off-by: Ori Liel <ol...@redhat.com>
---
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/BackendApplication.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendApiResource.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/JaxbExceptionMapper.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/JsonExceptionMapper.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/UsageFinder.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/rsdl/RsdlBuilder.java
A 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/util/ApiUtils.java
8 files changed, 280 insertions(+), 96 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/17/23017/1

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 a88507b..4cf9e15 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
@@ -117,6 +117,16 @@
     </xs:sequence>
   </xs:complexType>
 
+
+<xs:element name="usage_message" type="UsageMessage"/>
+
+  <xs:complexType name="UsageMessage">
+    <xs:sequence>
+      <xs:element name="message" type="xs:string"/>
+      <xs:element ref="detailedLink" minOccurs="0" maxOccurs="1"/>
+    </xs:sequence>
+  </xs:complexType>
+  
   <!-- Actions -->
 
   <xs:complexType name="GracePeriod">
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/BackendApplication.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/BackendApplication.java
index 8dea70d..fb0a3fe 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/BackendApplication.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/BackendApplication.java
@@ -58,6 +58,8 @@
 import org.ovirt.engine.api.restapi.resource.BackendVmPoolsResource;
 import org.ovirt.engine.api.restapi.resource.BackendVmsResource;
 import org.ovirt.engine.api.restapi.resource.BackendVnicProfilesResource;
+import org.ovirt.engine.api.restapi.resource.validation.JaxbExceptionMapper;
+import org.ovirt.engine.api.restapi.resource.validation.JsonExceptionMapper;
 import 
org.ovirt.engine.api.restapi.resource.validation.MalformedIdExceptionMapper;
 import org.ovirt.engine.api.restapi.resource.validation.ValidatorLocator;
 import org.ovirt.engine.api.restapi.security.auth.LoginValidator;
@@ -162,6 +164,8 @@
 
         // Intercepter that maps exceptions cause by illegal guid string to 
400 status (BAD_REQUEST).
         singletons.add(new MalformedIdExceptionMapper());
+        singletons.add(new JaxbExceptionMapper());
+        singletons.add(new JsonExceptionMapper());
     }
 
     private void addResource(final BackendResource resource) {
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendApiResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendApiResource.java
index 1da5f88..74f85ed 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendApiResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendApiResource.java
@@ -19,12 +19,9 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
 
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
@@ -34,7 +31,6 @@
 import org.ovirt.engine.api.common.util.FileUtils;
 import org.ovirt.engine.api.common.util.JAXBHelper;
 import org.ovirt.engine.api.common.util.LinkHelper;
-import org.ovirt.engine.api.common.util.LinkHelper.LinkFlags;
 import org.ovirt.engine.api.common.util.QueryHelper;
 import org.ovirt.engine.api.model.API;
 import org.ovirt.engine.api.model.Action;
@@ -45,8 +41,6 @@
 import org.ovirt.engine.api.model.Link;
 import org.ovirt.engine.api.model.LinkHeader;
 import org.ovirt.engine.api.model.ObjectFactory;
-import org.ovirt.engine.api.model.Parameter;
-import org.ovirt.engine.api.model.ParametersSet;
 import org.ovirt.engine.api.model.ProductInfo;
 import org.ovirt.engine.api.model.RSDL;
 import org.ovirt.engine.api.model.SpecialObjects;
@@ -58,6 +52,7 @@
 import org.ovirt.engine.api.restapi.rsdl.RsdlBuilder;
 import org.ovirt.engine.api.restapi.rsdl.SchemaBuilder;
 import org.ovirt.engine.api.restapi.types.DateMapper;
+import org.ovirt.engine.api.restapi.util.ApiUtils;
 import org.ovirt.engine.api.restapi.util.ErrorMessageHelper;
 import org.ovirt.engine.api.restapi.util.VersionHelper;
 import org.ovirt.engine.core.common.action.VdcActionParametersBase;
@@ -100,43 +95,11 @@
     }
 
     private Collection<DetailedLink> getLinks() {
-        Collection<DetailedLink> links = new LinkedList<DetailedLink>();
-        links.add(createLink("capabilities"));
-        links.add(createLink("clusters", LinkFlags.SEARCHABLE));
-        links.add(createLink("datacenters", LinkFlags.SEARCHABLE));
-        links.add(createLink("events", LinkFlags.SEARCHABLE, 
getEventParams()));
-        links.add(createLink("hosts", LinkFlags.SEARCHABLE));
-        links.add(createLink("networks", LinkFlags.SEARCHABLE));
-        links.add(createLink("roles"));
-        links.add(createLink("storagedomains", LinkFlags.SEARCHABLE));
-        links.add(createLink("tags"));
-        links.add(createLink("templates", LinkFlags.SEARCHABLE));
-        links.add(createLink("users", LinkFlags.SEARCHABLE));
-        links.add(createLink("groups", LinkFlags.SEARCHABLE));
-        links.add(createLink("domains"));
-        links.add(createLink("vmpools", LinkFlags.SEARCHABLE));
-        links.add(createLink("vms", LinkFlags.SEARCHABLE));
-        links.add(createLink("disks", LinkFlags.SEARCHABLE));
-        links.add(createLink("jobs"));
-        links.add(createLink("storageconnections"));
-        links.add(createLink("vnicprofiles"));
-        links.add(createLink("permissions"));
-        return links;
+        return ApiUtils.getLinks(getUriInfo());
     }
 
     private Collection<DetailedLink> getGlusterLinks() {
-        Collection<DetailedLink> links = new LinkedList<DetailedLink>();
-        links.add(createLink("capabilities"));
-        links.add(createLink("clusters", LinkFlags.SEARCHABLE));
-        links.add(createLink("events", LinkFlags.SEARCHABLE, 
getEventParams()));
-        links.add(createLink("hosts", LinkFlags.SEARCHABLE));
-        links.add(createLink("networks", LinkFlags.SEARCHABLE));
-        links.add(createLink("roles"));
-        links.add(createLink("tags"));
-        links.add(createLink("users", LinkFlags.SEARCHABLE));
-        links.add(createLink("groups", LinkFlags.SEARCHABLE));
-        links.add(createLink("domains"));
-        return links;
+        return ApiUtils.getGlusterLinks(getUriInfo());
     }
 
     private Link createBlankTemplateLink() {
@@ -191,58 +154,12 @@
         return api;
     }
 
-    private ParametersSet getEventParams() {
-        ParametersSet ps = new ParametersSet();
-        Parameter param = new Parameter();
-        param.setName("from");
-        param.setValue("event_id");
-        ps.getParameters().add(param);
-        return ps;
-    }
-
-    public List<String> getRels() {
-        appMode = getCurrent().get(ApplicationMode.class);
-        if (appMode == ApplicationMode.GlusterOnly)
-        {
-            return getGlusterRels();
-        }
-        return getAllRels();
-    }
-
-    public List<String> getAllRels() {
-        List<String> rels = new ArrayList<String>();
-        for (Link link : getLinks()) {
-            rels.add(link.getRel());
-        }
-        return rels;
-    }
-
-    public List<String> getGlusterRels() {
-        List<String> rels = new ArrayList<String>();
-        for (Link link : getGlusterLinks()) {
-            rels.add(link.getRel());
-        }
-        return rels;
-    }
-
     private String getTagRootUri() {
         return LinkHelper.combine(getUriInfo().getBaseUri().getPath(), 
"tags/00000000-0000-0000-0000-000000000000");
     }
 
     private String getTemplateBlankUri() {
         return LinkHelper.combine(getUriInfo().getBaseUri().getPath(), 
"templates/00000000-0000-0000-0000-000000000000");
-    }
-
-    private DetailedLink createLink(String rel, LinkFlags flags) {
-        return LinkHelper.createLink(getUriInfo().getBaseUri().getPath(), rel, 
flags);
-    }
-
-    private DetailedLink createLink(String rel, LinkFlags flags, ParametersSet 
params) {
-        return LinkHelper.createLink(getUriInfo().getBaseUri().getPath(), rel, 
flags, params);
-    }
-
-    private DetailedLink createLink(String rel) {
-        return LinkHelper.createLink(getUriInfo().getBaseUri().getPath(), rel, 
LinkFlags.NONE);
     }
 
     private String addPath(UriBuilder uriBuilder, Link link) {
@@ -361,9 +278,9 @@
             return rsdl;
     }
 
-    private synchronized RSDL getRSDL() {
+    public synchronized RSDL getRSDL() {
         if (rsdl == null) {
-            rsdl = new RsdlBuilder(this).description(RSDL_DESCRIPTION)
+            rsdl = new RsdlBuilder(getUriInfo(), 
getCurrent().get(ApplicationMode.class)).description(RSDL_DESCRIPTION)
                     .rel(RSDL_REL)
                     .href(getUriInfo().getBaseUri().getPath() +
                             QUERY_PARAMETER + RSDL_CONSTRAINT_PARAMETER)
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/JaxbExceptionMapper.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/JaxbExceptionMapper.java
new file mode 100644
index 0000000..d41bd20
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/JaxbExceptionMapper.java
@@ -0,0 +1,32 @@
+package org.ovirt.engine.api.restapi.resource.validation;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import javax.xml.bind.JAXBException;
+
+import org.jboss.resteasy.annotations.interception.ServerInterceptor;
+
+@Provider
+@ServerInterceptor
+public class JaxbExceptionMapper implements ExceptionMapper<JAXBException> {
+
+    @Context
+    protected UriInfo uriInfo;
+    @Context
+    protected Request request;
+    @Context
+    protected Application application;
+
+    @Override
+    public Response toResponse(JAXBException exception) {
+        return Response.status(Status.BAD_REQUEST)
+                .entity(new UsageFinder().getUsageMessage(application, 
uriInfo, request))
+                .build();
+    }
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/JsonExceptionMapper.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/JsonExceptionMapper.java
new file mode 100644
index 0000000..851c16d
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/JsonExceptionMapper.java
@@ -0,0 +1,33 @@
+package org.ovirt.engine.api.restapi.resource.validation;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import org.codehaus.jackson.JsonProcessingException;
+import org.jboss.resteasy.annotations.interception.ServerInterceptor;
+
+@Provider
+@ServerInterceptor
+public class JsonExceptionMapper implements 
ExceptionMapper<JsonProcessingException> {
+
+    @Context
+    protected UriInfo uriInfo;
+    @Context
+    protected Request request;
+    @Context
+    protected Application application;
+
+    @Override
+    public Response toResponse(JsonProcessingException exception) {
+        return Response.status(Status.BAD_REQUEST)
+                .entity(new UsageFinder().getUsageMessage(application, 
uriInfo, request))
+                .build();
+    }
+
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/UsageFinder.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/UsageFinder.java
new file mode 100644
index 0000000..9335379
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/validation/UsageFinder.java
@@ -0,0 +1,86 @@
+package org.ovirt.engine.api.restapi.resource.validation;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.UriInfo;
+
+import org.ovirt.engine.api.model.DetailedLink;
+import org.ovirt.engine.api.model.RSDL;
+import org.ovirt.engine.api.model.UsageMessage;
+import org.ovirt.engine.api.restapi.resource.BackendApiResource;
+
+public class UsageFinder {
+
+    private static final String RESPONSE = "Request Syntactically Incorrect. 
Correct Usage:";
+    private static final String UUID_REGEX =
+            
"^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}";
+
+    public UsageMessage getUsageMessage(Application application, UriInfo 
uriInfo, Request request) {
+        UsageMessage usage = new UsageMessage();
+        usage.setMessage(RESPONSE);
+        usage.setDetailedLink(findUsage(getRSDL(application), uriInfo, 
request.getMethod()));
+        return usage;
+    }
+
+    private DetailedLink findUsage(RSDL rsdl, UriInfo uriInfo, String 
httpMethod) {
+        for (DetailedLink link : rsdl.getLinks().getLinks()) {
+            if (isMatch(link, uriInfo, httpMethod)) {
+                return link;
+            }
+        }
+        return null; // should never happen
+    }
+
+    private RSDL getRSDL(Application application) {
+        for (Object obj : application.getSingletons()) {
+            if (obj instanceof BackendApiResource) {
+                BackendApiResource resource = (BackendApiResource) obj;
+                return resource.getRSDL();
+            }
+        }
+        return null; // should never happen
+    }
+
+    private boolean isMatch(DetailedLink link, UriInfo uriInfo, String 
httpMethod) {
+        int baseUriLength = uriInfo.getBaseUri().getPath().length();
+        // e.g: [vms, {vm:id}, start]
+        String[] linkPathSegments = 
link.getHref().substring(baseUriLength).split("/");
+        // e.g: [vms, f26b0918-8e16-4915-b1c2-7f39e568de23, start]
+        List<PathSegment> uriPathSegments = uriInfo.getPathSegments();
+        return isMatchLength(linkPathSegments, uriPathSegments) &&
+                isMatchePath(linkPathSegments, uriPathSegments) &&
+                isMatchRel(link.getRel(), httpMethod);
+    }
+
+    private boolean isMatchLength(String[] linkPathSegments, List<PathSegment> 
uriPathSegments) {
+        return linkPathSegments.length == uriPathSegments.size();
+    }
+
+    private boolean isMatchePath(String[] linkPathSegments, List<PathSegment> 
uriPathSegments) {
+        for (int i = 0; i < linkPathSegments.length; i++) {
+            String uriPathSegment = uriPathSegments.get(i).getPath();
+            if (isUUID(uriPathSegment) || 
uriPathSegment.equals(linkPathSegments[i])) {
+                continue;
+            } else {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean isMatchRel(String rel, String httpMethod) {
+        return ((rel.equals("get") && httpMethod.equals("GET")))
+                || ((rel.equals("add") && httpMethod.equals("POST")))
+                || ((rel.equals("update") && httpMethod.equals("PUT")))
+                || httpMethod.equals("POST") ? true : false;
+    }
+
+    private boolean isUUID(String uriPathSegment) {
+        return Pattern.matches(UUID_REGEX, uriPathSegment);
+    }
+
+}
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/rsdl/RsdlBuilder.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/rsdl/RsdlBuilder.java
index dd8d672..a187147 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/rsdl/RsdlBuilder.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/rsdl/RsdlBuilder.java
@@ -36,6 +36,7 @@
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
+import javax.ws.rs.core.UriInfo;
 
 import org.ovirt.engine.api.common.util.FileUtils;
 import org.ovirt.engine.api.common.util.ReflectionHelper;
@@ -56,7 +57,8 @@
 import org.ovirt.engine.api.model.Url;
 import org.ovirt.engine.api.resource.CreationResource;
 import org.ovirt.engine.api.resource.RsdlIgnore;
-import org.ovirt.engine.api.restapi.resource.BackendApiResource;
+import org.ovirt.engine.api.restapi.util.ApiUtils;
+import org.ovirt.engine.core.common.mode.ApplicationMode;
 import org.ovirt.engine.core.utils.log.Log;
 import org.ovirt.engine.core.utils.log.LogFactory;
 import org.yaml.snakeyaml.Yaml;
@@ -69,14 +71,14 @@
     private static final String COLLECTION_PARAMETER_YAML = "--COLLECTION";
     private static final String DEPRECATED_PARAMETER_YAML = "--DEPRECATED";
     private RSDL rsdl;
-    private String entryPointPath;
-    private BackendApiResource apiResource;
     private Map<String, Action> parametersMetaData;
     private String rel;
     private String href;
     private Schema schema;
     private GeneralMetadata generalMetadata;
     private String description;
+    private UriInfo uriInfo;
+    private ApplicationMode applicationMode;
 
     private static final String ACTION = "Action";
     private static final String DELETE = "delete";
@@ -89,9 +91,9 @@
     private static final String RESOURCES_PACKAGE = 
"org.ovirt.engine.api.resource";
     private static final String PARAMS_METADATA = "rsdl_metadata.yaml";
 
-    public RsdlBuilder(BackendApiResource apiResource) {
-        this.apiResource = apiResource;
-        this.entryPointPath = apiResource.getUriInfo().getBaseUri().getPath();
+    public RsdlBuilder(UriInfo uriInfo, ApplicationMode applicationMode) {
+        this.uriInfo = uriInfo;
+        this.applicationMode = applicationMode;
         this.parametersMetaData = loadParametersMetaData();
     }
 
@@ -103,7 +105,7 @@
                  Constructor constructor = new 
CustomClassLoaderConstructor(Thread.currentThread().getContextClassLoader());
                  Object result = new Yaml(constructor).load(stream);
                  for (Action action : ((MetaData)result).getActions()) {
-                    
parametersMetaData.put(apiResource.getUriInfo().getBaseUri().getPath() + 
action.getName(), action);
+                    parametersMetaData.put(uriInfo.getBaseUri().getPath() + 
action.getName(), action);
                  }
             } else {
                 LOG.error("Parameters metatdata file not found.");
@@ -243,8 +245,12 @@
         //SortedSet<Link> results = new TreeSet<Link>();
         List<DetailedLink> results = new ArrayList<DetailedLink>();
         List<Class<?>> classes = 
ReflectionHelper.getClasses(RESOURCES_PACKAGE);
-        for (String path : apiResource.getRels()) {
+        List<String> paths =
+                applicationMode == ApplicationMode.GlusterOnly ? 
ApiUtils.getGlusterRels(uriInfo)
+                        : ApiUtils.getAllRels(uriInfo);
+        for (String path : paths) {
             Class<?> resource = findResource(path, classes);
+            String entryPointPath = uriInfo.getBaseUri().getPath();
             String prefix = entryPointPath.endsWith("/") ? entryPointPath + 
path : entryPointPath + "/" + path;
             results.addAll(describe(resource, prefix, new HashMap<String, 
Type>()));
         }
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/util/ApiUtils.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/util/ApiUtils.java
new file mode 100644
index 0000000..3d08b36
--- /dev/null
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/util/ApiUtils.java
@@ -0,0 +1,96 @@
+package org.ovirt.engine.api.restapi.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.ws.rs.core.UriInfo;
+
+import org.ovirt.engine.api.common.util.LinkHelper;
+import org.ovirt.engine.api.common.util.LinkHelper.LinkFlags;
+import org.ovirt.engine.api.model.DetailedLink;
+import org.ovirt.engine.api.model.Link;
+import org.ovirt.engine.api.model.Parameter;
+import org.ovirt.engine.api.model.ParametersSet;
+
+public class ApiUtils {
+
+    public static Collection<DetailedLink> getLinks(UriInfo uriInfo) {
+        Collection<DetailedLink> links = new LinkedList<DetailedLink>();
+        links.add(createLink("capabilities", uriInfo));
+        links.add(createLink("clusters", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("datacenters", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("events", LinkFlags.SEARCHABLE, getEventParams(), 
uriInfo));
+        links.add(createLink("hosts", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("networks", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("roles", uriInfo));
+        links.add(createLink("storagedomains", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("tags", uriInfo));
+        links.add(createLink("templates", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("users", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("groups", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("domains", uriInfo));
+        links.add(createLink("vmpools", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("vms", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("disks", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("jobs", uriInfo));
+        links.add(createLink("storageconnections", uriInfo));
+        links.add(createLink("vnicprofiles", uriInfo));
+        links.add(createLink("permissions", uriInfo));
+        return links;
+    }
+
+    public static Collection<DetailedLink> getGlusterLinks(UriInfo uriInfo) {
+        Collection<DetailedLink> links = new LinkedList<DetailedLink>();
+        links.add(createLink("capabilities", uriInfo));
+        links.add(createLink("clusters", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("events", LinkFlags.SEARCHABLE, getEventParams(), 
uriInfo));
+        links.add(createLink("hosts", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("networks", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("roles", uriInfo));
+        links.add(createLink("tags", uriInfo));
+        links.add(createLink("users", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("groups", LinkFlags.SEARCHABLE, uriInfo));
+        links.add(createLink("domains", uriInfo));
+        return links;
+    }
+
+    public static List<String> getAllRels(UriInfo uriInfo) {
+        List<String> rels = new ArrayList<String>();
+        for (Link link : getLinks(uriInfo)) {
+            rels.add(link.getRel());
+        }
+        return rels;
+    }
+
+    public static List<String> getGlusterRels(UriInfo uriInfo) {
+        List<String> rels = new ArrayList<String>();
+        for (Link link : getGlusterLinks(uriInfo)) {
+            rels.add(link.getRel());
+        }
+        return rels;
+    }
+
+    private static DetailedLink createLink(String rel, LinkFlags flags, 
UriInfo uriInfo) {
+        return LinkHelper.createLink(uriInfo.getBaseUri().getPath(), rel, 
flags);
+    }
+
+    private static DetailedLink createLink(String rel, LinkFlags flags, 
ParametersSet params, UriInfo uriInfo) {
+        return LinkHelper.createLink(uriInfo.getBaseUri().getPath(), rel, 
flags, params);
+    }
+
+    private static DetailedLink createLink(String rel, UriInfo uriInfo) {
+        return LinkHelper.createLink(uriInfo.getBaseUri().getPath(), rel, 
LinkFlags.NONE);
+    }
+
+    private static ParametersSet getEventParams() {
+        ParametersSet ps = new ParametersSet();
+        Parameter param = new Parameter();
+        param.setName("from");
+        param.setValue("event_id");
+        ps.getParameters().add(param);
+        return ps;
+    }
+
+}


-- 
To view, visit http://gerrit.ovirt.org/23017
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic7a6da4fbb00ea5f1e6919ddfe21dd7b3dd126fd
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Ori Liel <ol...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to