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
