Juan Hernandez has uploaded a new change for review.

Change subject: restapi: Fix prefix in RSDL
......................................................................

restapi: Fix prefix in RSDL

Currently during the build process we generate a RSDL document that
contains "href" attributes including the prefix "/ovirt-engine/api". But
the application is deployed twice, once for "/api" and another for
"/ovirt-engine/api", thus the RSDL document presented by "/api" isn't
valid. To avoid this issue this patch changes the build process so that
it will generate a RSDL document that doesn't contain any prefix. The
correct prefix will be added during runtime by each deployment of the
application.

Change-Id: If5fadb92b6f3a6b06e44729c967289c5917f9a25
Bug-Url: https://bugzilla.redhat.com/1102772
Signed-off-by: Juan Hernandez <[email protected]>
---
M 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/rsdl/RsdlBuilder.java
M 
backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/rsdl/RsdlManager.java
M 
backend/manager/modules/restapi/jaxrs/src/main/java/org/ovirt/engine/api/restapi/resource/BackendApiResource.java
3 files changed, 66 insertions(+), 43 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/18/30018/1

diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/rsdl/RsdlBuilder.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/rsdl/RsdlBuilder.java
index d2b9e63..df96597 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/rsdl/RsdlBuilder.java
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/rsdl/RsdlBuilder.java
@@ -66,7 +66,6 @@
     private Schema schema;
     private GeneralMetadata generalMetadata;
     private String description;
-    private String baseUri;
     private List<String> rels;
     private MetaData metadata;
 
@@ -78,17 +77,7 @@
 
     private static final String RESOURCES_PACKAGE = 
"org.ovirt.engine.api.resource";
 
-    public RsdlBuilder(String baseUri, List<String> rels, MetaData metadata) {
-        /**
-         * uriInfo.getBaseUri().getPath() might be: /ovirt-engine/api/ (with 
trailing '/') or: /ovirt-engine/api
-         * (without trailing '/') - depending on the context of the request. 
The reason for this variability is not
-         * clear. In any case - we assume no trailing '/' when creating the 
action name, so we add a check and eliminate
-         * the trailing slash if necessary.
-         */
-        if (baseUri.endsWith("/")) {
-            baseUri = baseUri.substring(0, baseUri.length() - 1);
-        }
-        this.baseUri = baseUri;
+    public RsdlBuilder(List<String> rels, MetaData metadata) {
         this.rels = rels;
         this.metadata = metadata;
         this.parametersMetaData = addParametersMetaData();
@@ -97,7 +86,7 @@
     public Map<String, Action> addParametersMetaData() {
         parametersMetaData = new HashMap<String, Action>();
         for (Action action : metadata.getActions()) {
-            parametersMetaData.put(baseUri + action.getName(), action);
+            parametersMetaData.put(action.getName(), action);
         }
         return parametersMetaData;
     }
@@ -233,8 +222,7 @@
         List<Class<?>> classes = 
ReflectionHelper.getClasses(RESOURCES_PACKAGE);
         for (String path : rels) {
             Class<?> resource = findResource(path, classes);
-            String prefix = baseUri + "/" + path;
-            results.addAll(describe(resource, prefix, new HashMap<String, 
Type>()));
+            results.addAll(describe(resource, path, new HashMap<String, 
Type>()));
         }
         return results;
     }
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/rsdl/RsdlManager.java
 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/rsdl/RsdlManager.java
index f770d62..7cb4417 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/rsdl/RsdlManager.java
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/java/org/ovirt/engine/api/rsdl/RsdlManager.java
@@ -7,11 +7,22 @@
 import java.util.List;
 
 import javax.xml.bind.JAXB;
+import javax.xml.bind.JAXBElement;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
 
 import org.apache.commons.lang.StringUtils;
+import org.ovirt.engine.api.model.ObjectFactory;
 import org.ovirt.engine.api.model.RSDL;
 import org.ovirt.engine.api.utils.ApiRootLinksCreator;
 import org.ovirt.engine.core.common.mode.ApplicationMode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 import org.yaml.snakeyaml.Yaml;
 import org.yaml.snakeyaml.constructor.Constructor;
 import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;
@@ -41,8 +52,8 @@
 
         MetaData metadata = loadMetaData();
         validateActionLinksFormat(metadata);
-        generateRsdlFile(metadata, baseUri, outputFileName, 
ApiRootLinksCreator.getAllRels(baseUri));
-        generateRsdlFile(metadata, baseUri, outputFileNameGluster, 
ApiRootLinksCreator.getGlusterRels(baseUri));
+        generateRsdlFile(metadata, outputFileName, 
ApiRootLinksCreator.getAllRels(baseUri));
+        generateRsdlFile(metadata, outputFileNameGluster, 
ApiRootLinksCreator.getGlusterRels(baseUri));
 
         System.out.println("The following files have been generated: \n" + 
outputFileName + "\n"
                 + outputFileNameGluster);
@@ -62,51 +73,72 @@
         }
     }
 
-    private static void generateRsdlFile(MetaData metadata, String baseUri, 
String outputFileName, List<String> rels)
+    private static void generateRsdlFile(MetaData metadata, String 
outputFileName, List<String> rels)
             throws IOException, ClassNotFoundException {
-        RSDL rsdl = buildRsdl(metadata, rels, baseUri);
+        RSDL rsdl = buildRsdl(metadata, rels);
         serializeRsdl(rsdl, outputFileName);
     }
 
-    public static RSDL loadRsdl(ApplicationMode applicationMode) throws 
IOException {
+    public static RSDL loadRsdl(ApplicationMode applicationMode, String 
prefix) throws IOException {
+        // Decide what version of the RSDL document to load:
         String fileName =
                 applicationMode == ApplicationMode.GlusterOnly ? ("/" + 
RsdlIOManager.GLUSTER_RSDL_RESOURCE_NAME)
                         : ("/" + RsdlIOManager.RSDL_RESOURCE_NAME);
-        InputStream rsdlAsStrem = null;
+
+        // Load the RSDL document into a DOM tree and then modify all the 
"href" attributes to include the prefix given
+        // as parameter:
+        Document document;
         try {
-            rsdlAsStrem = RsdlIOManager.loadAsStream(fileName);
-            return JAXB.unmarshal(rsdlAsStrem, RSDL.class);
-        } finally {
-            if (rsdlAsStrem != null) {
-                rsdlAsStrem.close();
+            DocumentBuilder parser = 
DocumentBuilderFactory.newInstance().newDocumentBuilder();
+            try (InputStream in = RsdlIOManager.loadAsStream(fileName)) {
+                document = parser.parse(in);
+            }
+            XPath xpath = XPathFactory.newInstance().newXPath();
+            NodeList nodes = (NodeList) xpath.evaluate("//@href", document, 
XPathConstants.NODESET);
+            for (int i = 0; i < nodes.getLength(); i++) {
+                Node node = nodes.item(i);
+                String href = node.getNodeValue();
+                if (href.startsWith(QUERY_PARAMETER)) {
+                    href = prefix + href;
+                }
+                else {
+                    href = prefix + "/" + href;
+                }
+                node.setNodeValue(href);
             }
         }
+        catch (Exception exception) {
+            throw new IOException(exception);
+        }
 
+        // Convert the modified DOM tree to the RSDL object:
+        return JAXB.unmarshal(new DOMSource(document), RSDL.class);
     }
 
     private static void serializeRsdl(RSDL rsdl, String rsdlLocation) {
-        JAXB.marshal(rsdl, new File(rsdlLocation));
+        ObjectFactory factory = new ObjectFactory();
+        JAXBElement<RSDL> element = factory.createRsdl(rsdl);
+        JAXB.marshal(element, new File(rsdlLocation));
     }
 
-    private static RSDL buildRsdl(MetaData metadata, List<String> rels, String 
baseUri) throws IOException,
+    private static RSDL buildRsdl(MetaData metadata, List<String> rels) throws 
IOException,
             ClassNotFoundException {
-        RsdlBuilder builder = new RsdlBuilder(baseUri, rels, metadata)
+        RsdlBuilder builder = new RsdlBuilder(rels, metadata)
         .description(RSDL_DESCRIPTION)
         .rel(RSDL_REL)
-                .href(baseUri + QUERY_PARAMETER + RSDL_CONSTRAINT_PARAMETER)
+                .href(QUERY_PARAMETER + RSDL_CONSTRAINT_PARAMETER)
         .schema(new SchemaBuilder()
-                .rel(SCHEMA_REL)
-                        .href(baseUri +
-                        QUERY_PARAMETER + SCHEMA_CONSTRAINT_PARAMETER)
-                .name(SCHEMA_NAME)
-                .description(SCHEMA_DESCRIPTION)
-                .build())
+            .rel(SCHEMA_REL)
+            .href(QUERY_PARAMETER + SCHEMA_CONSTRAINT_PARAMETER)
+            .name(SCHEMA_NAME)
+            .description(SCHEMA_DESCRIPTION)
+            .build())
         .generalMetadata(new GeneralMetadataBuilder()
-                .rel(GENERAL_METADATA_REL)
-                        .href(baseUri.replace("api", "*"))
-                .name(GENERAL_METADATA_NAME)
-                .description(GENERAL_METADATA_DESCRIPTION)
-                        .build());
+            .rel(GENERAL_METADATA_REL)
+            .href("*")
+            .name(GENERAL_METADATA_NAME)
+            .description(GENERAL_METADATA_DESCRIPTION)
+            .build());
         RSDL rsdl = builder.build();
         return rsdl;
     }
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 5740da3..daaa28d 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
@@ -74,7 +74,7 @@
     private static final String SCHEMA_CONSTRAINT_PARAMETER = "schema";
     private static final String SCHEMA_NAME = "ovirt-engine-api-schema.xsd";
 
-    private static RSDL rsdl = null;
+    private RSDL rsdl = null;
 
     protected final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
     ApplicationMode appMode = ApplicationMode.AllModes;
@@ -272,7 +272,10 @@
 
     public synchronized RSDL getRSDL() throws ClassNotFoundException, 
IOException {
         if (rsdl == null) {
-            rsdl = 
RsdlManager.loadRsdl(getCurrent().get(ApplicationMode.class));
+            rsdl = RsdlManager.loadRsdl(
+                getCurrent().get(ApplicationMode.class),
+                getUriInfo().getBaseUri().getPath()
+            );
         }
         return rsdl;
     }


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

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

Reply via email to