Michael Pasternak has uploaded a new change for review.

Change subject: restapi: SetupNetworks missing action link #806916
......................................................................

restapi: SetupNetworks missing action link #806916

This patch adds generic support for actionin links
generation under collection context

https://bugzilla.redhat.com/show_bug.cgi?id=806916

Change-Id: Iea197cc0c6219061a3b83b5aa8fccbf18de29802
Signed-off-by: Michael Pasternak <[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/model/ActionsBuilder.java
A 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/ArrayUtils.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/AbstractBackendCollectionResource.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostNicsResource.java
M 
backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostNicsResourceTest.java
7 files changed, 129 insertions(+), 26 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/61/7461/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 f0f32cb..7b45418 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
@@ -26,6 +26,7 @@
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 
+import org.ovirt.engine.api.model.ActionableResource;
 import org.ovirt.engine.api.model.ActionsBuilder;
 import org.ovirt.engine.api.model.BaseResource;
 import org.ovirt.engine.api.model.CdRom;
@@ -591,6 +592,21 @@
     }
 
     /**
+     * Adds the set of action links for an object
+     *
+     * @param uriInfo the URI info
+     * @param model the object to add actions to
+     * @param collection the object to get implemented methods from
+     * @return the object, including its set of action links
+     */
+    public static <R extends ActionableResource> void addActions(UriInfo 
uriInfo, R model, Object collection) {
+        if (uriInfo != null) {
+            ActionsBuilder actionsBuilder = new ActionsBuilder(uriInfo, 
model.getClass(), collection.getClass());
+            model.setActions(actionsBuilder.build());
+        }
+    }
+
+    /**
      * Set the href attribute on the object (and its inline objects)
      * and construct its set of action links
      *
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/model/ActionsBuilder.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/model/ActionsBuilder.java
index 5fc16c0..8c15e18 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/model/ActionsBuilder.java
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/model/ActionsBuilder.java
@@ -21,31 +21,45 @@
 
 import javax.ws.rs.Path;
 import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
+import org.ovirt.engine.api.utils.ArrayUtils;
+
 
 public class ActionsBuilder {
 
     private UriBuilder uriBuilder;
     private Class<?> service;
+    UriInfo uriInfo;
+    Class<?> collection;
 
     public ActionsBuilder(UriBuilder uriBuilder, Class<?> service) {
         this.uriBuilder = uriBuilder;
         this.service = service;
     }
 
+    public ActionsBuilder(UriInfo uriInfo, Class<?> service, Class<?> 
collection) {
+        this.uriInfo = uriInfo;
+        this.service = service;
+        this.collection = collection;
+    }
+
     public Actions build() {
         Actions actions = null;
 
-        for (Method method : service.getMethods()) {
+        for (Method method : ArrayUtils.concat(service.getMethods(), 
getInterfaceSignatures(collection))) {
             Path path = method.getAnnotation(Path.class);
             Actionable actionable = method.getAnnotation(Actionable.class);
 
             if (actionable != null && path != null) {
-                URI uri = uriBuilder.clone().path(path.value()).build();
-
                 Link link = new Link();
                 link.setRel(path.value());
-                link.setHref(uri.toString());
-
+                if (uriBuilder != null) {
+                    URI uri = uriBuilder.clone().path(path.value()).build();
+                    link.setHref(uri.toString());
+                } else {
+                    link.setHref(this.uriInfo.getPath()+'/'+link.getRel());
+                }
                 if (actions == null) {
                     actions = new Actions();
                 }
@@ -55,4 +69,14 @@
 
         return actions;
     }
+
+    private Method[] getInterfaceSignatures(Class<?> collection) {
+        Method[] methods = new Method[0];
+        if (collection != null){
+            for (Class<?> inter : collection.getInterfaces()){
+                methods = ArrayUtils.concat(methods, inter.getMethods());
+            }
+        }
+        return methods;
+    }
 }
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/ArrayUtils.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/ArrayUtils.java
new file mode 100644
index 0000000..0354e53
--- /dev/null
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/utils/ArrayUtils.java
@@ -0,0 +1,11 @@
+package org.ovirt.engine.api.utils;
+
+import java.util.Arrays;
+
+public class ArrayUtils {
+    public static <T> T[] concat(T[] first, T[] second) {
+        T[] result = Arrays.copyOf(first, first.length + second.length);
+        System.arraycopy(second, 0, result, first.length, second.length);
+        return result;
+      }
+}
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 96f32ba..5dfd307 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
@@ -810,33 +810,46 @@
 
   <!-- Common to all resources -->
 
-  <xs:complexType name="BaseResource">
+  <xs:complexType name="ActionableResource">
     <xs:sequence>
-      <xs:element name="name" type="xs:string" minOccurs="0"/>
-      <xs:element name="description" type="xs:string" minOccurs="0"/>
       <xs:element name="actions" type="Actions" minOccurs="0"/>
-      <xs:element name="creation_status" type="Status" minOccurs="0"/>      
-      <!-- also rel="creation_status" link for monitoring async creation -->
-      <!-- further link relation types may be defined by specific resources -->
-      <xs:element ref="link" minOccurs="0" maxOccurs="unbounded">
-        <xs:annotation>
-          <xs:appinfo>
-            <jaxb:property name="Links"/>
-          </xs:appinfo>
-        </xs:annotation>
-      </xs:element>
     </xs:sequence>
-    <xs:attribute name="href" type="xs:string"/>
-    <xs:attribute name="id" type="xs:string"/>
+  </xs:complexType>
+
+  <xs:complexType name="BaseResource">
+    <xs:complexContent>
+      <xs:extension base="ActionableResource">
+        <xs:sequence>
+          <xs:element name="name" type="xs:string" minOccurs="0"/>
+          <xs:element name="description" type="xs:string" minOccurs="0"/>
+          <xs:element name="creation_status" type="Status" minOccurs="0"/>
+          <!-- also rel="creation_status" link for monitoring async creation 
-->
+          <!-- further link relation types may be defined by specific 
resources -->
+          <xs:element ref="link" minOccurs="0" maxOccurs="unbounded">
+            <xs:annotation>
+              <xs:appinfo>
+                <jaxb:property name="Links"/>
+              </xs:appinfo>
+            </xs:annotation>
+          </xs:element>
+        </xs:sequence>
+        <xs:attribute name="href" type="xs:string"/>
+        <xs:attribute name="id" type="xs:string"/>
+      </xs:extension>
+    </xs:complexContent>
   </xs:complexType>
 
   <xs:complexType name="BaseResources">
-    <xs:sequence>
-      <xs:element name="total" type="xs:unsignedInt" minOccurs="0"/>
-      <xs:element name="active" type="xs:unsignedInt" minOccurs="0"/>
-    </xs:sequence>
+     <xs:complexContent>
+      <xs:extension base="ActionableResource">
+        <xs:sequence>
+          <xs:element name="total" type="xs:unsignedInt" minOccurs="0"/>
+          <xs:element name="active" type="xs:unsignedInt" minOccurs="0"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
   </xs:complexType>
-  
+
   <xs:complexType name="Option">
     <xs:attribute name="name" type="xs:string"/>
     <xs:attribute name="value" type="xs:string"/>
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/AbstractBackendCollectionResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/AbstractBackendCollectionResource.java
index 0fe8b39..ab5566e 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/AbstractBackendCollectionResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/AbstractBackendCollectionResource.java
@@ -9,8 +9,10 @@
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
 
+import org.ovirt.engine.api.common.util.LinkHelper;
 import org.ovirt.engine.api.common.util.QueryHelper;
 import org.ovirt.engine.api.common.util.StatusUtils;
+import org.ovirt.engine.api.model.ActionableResource;
 import org.ovirt.engine.api.model.BaseResource;
 import org.ovirt.engine.core.common.action.VdcActionParametersBase;
 import org.ovirt.engine.core.common.action.VdcActionType;
@@ -224,4 +226,14 @@
         }
         return null;
     }
+
+    /**
+     *
+     * @param model the resource to add actions to
+     * @return collection with action links
+     */
+    protected <C extends ActionableResource> C addActions(C model) {
+        LinkHelper.addActions(getUriInfo(), model, this);
+        return model;
+    }
 }
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostNicsResource.java
 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostNicsResource.java
index faed271..023c543 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostNicsResource.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendHostNicsResource.java
@@ -72,7 +72,7 @@
             }
             ret.getHostNics().add(addLinks(hostNic));
         }
-        return ret;
+        return addActions(ret);
     }
 
     @SuppressWarnings("serial")
diff --git 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostNicsResourceTest.java
 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostNicsResourceTest.java
index e19be91..c163123 100644
--- 
a/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostNicsResourceTest.java
+++ 
b/backend/manager/modules/restapi/jaxrs/src/test/java/org/ovirt/engine/api/restapi/resource/BackendHostNicsResourceTest.java
@@ -3,6 +3,7 @@
 import static org.easymock.EasyMock.expect;
 import static org.junit.Assert.*;
 
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedList;
@@ -52,6 +53,8 @@
     private static final Integer NIC_SPEED = 100;
     private static final InterfaceStatus NIC_STATUS = InterfaceStatus.Up;
     private static final NetworkBootProtocol BOOT_PROTOCOL = 
NetworkBootProtocol.StaticIp;
+    private static final String SETUPNETWORKS_ACTION_BASE_URL = 
"/hosts/00000000-0000-0000-0000-000000000000/nics";
+    private static final String SETUPNETWORKS_ACTION_URL = 
"/hosts/00000000-0000-0000-0000-000000000000/nics/setupnetworks@SLTests";
 
     public BackendHostNicsResourceTest() {
         super(new BackendHostNicsResource(PARENT_GUID.toString()), null, null);
@@ -274,6 +277,30 @@
         verifyCollection(getCollection());
     }
 
+    @Test
+    public void testActionsInList() throws Exception {
+        UriInfo uriInfo = setUpActionsUriExpectations();
+        setGetVdsQueryExpectations(1);
+        setGetNetworksQueryExpectations(1);
+        setUpQueryExpectations("");
+        collection.setUriInfo(uriInfo);
+        verifyActions(collection.list());
+    }
+
+    private UriInfo setUpActionsUriExpectations() {
+        UriInfo uriInfo = control.createMock(UriInfo.class);
+        
expect(uriInfo.getBaseUri()).andReturn(URI.create(BASE_PATH)).anyTimes();
+        
expect(uriInfo.getPath()).andReturn(SETUPNETWORKS_ACTION_BASE_URL).anyTimes();
+        return uriInfo;
+    }
+
+    private void verifyActions(HostNics list) {
+        assertNotNull(list.getActions());
+        assertNotNull(list.getActions().getLinks());
+        assertNotNull(list.getActions().getLinks().get(0));
+        assertEquals(list.getActions().getLinks().get(0).getHref(), 
SETUPNETWORKS_ACTION_URL);
+    }
+
     protected void doTestBadRemove(boolean canDo, boolean success, String 
detail) throws Exception {
         setGetVdsQueryExpectations(1);
         setGetNetworksQueryExpectations(1);


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iea197cc0c6219061a3b83b5aa8fccbf18de29802
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Michael Pasternak <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to