Juan Hernandez has uploaded a new change for review.

Change subject: codegen: Sort and remember header parameters
......................................................................

codegen: Sort and remember header parameters

Currently the order of parameters corresponding to headers in generated
code is the same that the order of those parameters in the RSDL
metadata. This means that adding new parameters or reordering them in
the RSDL metadata produces the same reordering in the parameters of the
methods of the generated code. For example, one of the methods to add a
cluster has currently the following signature:

  Cluster add(Cluster cluster, String expect, String correlationId)

The order is "expect" and then "correlation-id" because that is the
order in the RSDL.

If the RSDL changes in such a way that the parameters have a different
order (because a new parameter is added, or just because the RSDL is
generated with a different algorithm) then the method could become
something like this:

  Cluster add(Cluster cluster, String correlationId, String expect)

This is extremelly dangerous, as it it is swapping the parameters but it
will compile just fine.

To avoid this issue this patch changes the generator so that the
parameters are always sorted by name before generating the code. This is
not enough, as it doesn't solve the issue when new parameters are added.
To solve that as well this patch introduces a "memory" (stored in a
properties file) where the generator remembers what was the order of the
previous execution. That order will be respected regardless of changes
in the RSDL.

Change-Id: I4a3916a04e8475f105099836de67ab85d3fb3feb
Signed-off-by: Juan Hernandez <[email protected]>
---
M generator/pom.xml
A generator/src/main/java/org/ovirt/engine/sdk/generator/Memory.java
M generator/src/main/java/org/ovirt/engine/sdk/generator/java/Main.java
A 
generator/src/main/java/org/ovirt/engine/sdk/generator/java/utils/ExceptionsAwareComparator.java
M 
generator/src/main/java/org/ovirt/engine/sdk/generator/java/utils/LinkUtils.java
A generator/src/main/resources/README.md
A generator/src/main/resources/memory.properties
M sdk/README.md
8 files changed, 688 insertions(+), 5 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine-sdk-java 
refs/changes/59/39459/1

diff --git a/generator/pom.xml b/generator/pom.xml
index 3b5d6df..7b01211 100644
--- a/generator/pom.xml
+++ b/generator/pom.xml
@@ -180,6 +180,8 @@
                 <configuration>
                   
<mainClass>org.ovirt.engine.sdk.generator.java.Main</mainClass>
                   <arguments>
+                    <argument>--memory</argument>
+                    
<argument>${basedir}/src/main/resources/memory.properties</argument>
                     <argument>--xsd</argument>
                     <argument>${basedir}/src/main/resources/api.xsd</argument>
                     <argument>--xjb</argument>
diff --git a/generator/src/main/java/org/ovirt/engine/sdk/generator/Memory.java 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/Memory.java
new file mode 100644
index 0000000..3cc7a66
--- /dev/null
+++ b/generator/src/main/java/org/ovirt/engine/sdk/generator/Memory.java
@@ -0,0 +1,189 @@
+//
+// Copyright (c) 2015 Red Hat, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package org.ovirt.engine.sdk.generator;
+
+import org.ovirt.engine.sdk.entities.DetailedLink;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+public class Memory {
+    /**
+     * This is a singleton, and this is the reference to the instance.
+     */
+    private static final Memory instance = new Memory();
+
+    /**
+     * Get the reference to the instance of this singleton.
+     */
+    public static Memory getInstance() {
+        return instance;
+    }
+
+    /**
+     * The properties stored in the memory.
+     */
+    private Properties properties = new Properties();
+
+    /**
+     * Loads the contents of the memory.
+     *
+     * @param file the file that contains the memory
+     * @throws IOException if something fails while loading the memory
+     */
+    public void load(File file) throws IOException {
+        try (InputStream in = new FileInputStream(file)) {
+            properties.load(in);
+        }
+    }
+
+    /**
+     * Saves the contents of the memory.
+     *
+     * @param file the file that will contain the memory
+     * @throws IOException if something fails while saving the memory
+     */
+    public void save(File file) throws IOException {
+        // We need to write the properties sorted by key, to make sure that 
the order is predictable and that the result
+        // is diff friendly:
+        try (PrintWriter writer = new PrintWriter(file)) {
+            List<String> keys = new 
ArrayList<>(properties.stringPropertyNames());
+            Collections.sort(keys);
+            for (String key : keys) {
+                String value = properties.getProperty(key);
+                writer.printf("%s=%s\n", key, value);
+            }
+        }
+    }
+
+    /**
+     * Clears the contents of the memory.
+     */
+    public void clear() {
+        properties.clear();
+    }
+
+    /**
+     * Returns the value associated with the given key.
+     *
+     * @param key the key
+     * @return the value associated with the given key, or {@code null} if 
there is no value associated with that key
+     */
+    public String get(String key) {
+        return properties.getProperty(key);
+    }
+
+    /**
+     * Associates a value with a key. If the key was associated with another 
value before, that value will be replaced
+     * with the new one.
+     *
+     * @param key the key
+     * @param value the value
+     */
+    public void put(String key, String value) {
+        properties.setProperty(key, value);
+    }
+
+    /**
+     * Returns the value associated with the given prefix and link. This is 
intended to store multiple items related
+     * to a link, for example, to store the order of header parameters for a 
link the file will contain the following
+     * properties:
+     *
+     * <pre>
+     * link.vms.vm_id..get.headers=Expect Correlation-Id
+     * </pre>
+     *
+     * Then the caller will be able to retrieve this as follows:
+     *
+     * <pre>
+     * DetailedLink link = ...;
+     * Memory memory = Memory.getInstance();
+     * String headers = memory.get(link, "headers");
+     * </pre>
+     *
+     * @param link the link
+     * @param key the prefix
+     * @return value associated with the given link and key, or {@code null} 
if there is no such value
+     */
+    public String get(DetailedLink link, String key) {
+        return get(makeKey(link, key));
+    }
+
+    /**
+     * Associates a value to a given link and key.
+     *
+     * @param link the link
+     * @param key the key
+     * @param value the new value
+     */
+    public void put(DetailedLink link, String key, String value) {
+        put(makeKey(link, key), value);
+    }
+
+    /**
+     * Returns the list of values associated with a given link and key.
+     *
+     * @param link the link
+     * @param key the key
+     * @return the list of values associated with the given link and key, or 
an empty list if no such key exists or
+     *     the list of values is empty, will never return {@code null}
+     */
+    public List<String> getList(DetailedLink link, String key) {
+        String value = get(link, key);
+        if (value == null || value.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return Arrays.asList(value.split("\\s"));
+    }
+
+    /**
+     * Associates a list of values associated with the given link and key.
+     *
+     * @param link the link
+     * @param key the key
+     */
+    public void putList(DetailedLink link, String key, List<String> values) {
+        if (values == null) {
+            values = Collections.emptyList();
+        }
+        String value = String.join(" ", values);
+        put(link, key, value);
+    }
+
+    /**
+     * Generates a unique key for a link and a non-unique key.
+     *
+     * @param link the link
+     * @param key the key
+     * @returns the unique key
+     */
+    private String makeKey(DetailedLink link, String key) {
+        String href = link.getHref();
+        href = href.replaceAll("/", ".");
+        href = href.replaceAll("[{}]", "");
+        href = href.replaceAll(":", "_");
+        return "link." + href + "." + link.getRel() + "." + key;
+    }
+}
diff --git 
a/generator/src/main/java/org/ovirt/engine/sdk/generator/java/Main.java 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/java/Main.java
index f73d8d5..a29f021 100644
--- a/generator/src/main/java/org/ovirt/engine/sdk/generator/java/Main.java
+++ b/generator/src/main/java/org/ovirt/engine/sdk/generator/java/Main.java
@@ -21,6 +21,7 @@
 
 import javax.xml.bind.JAXBException;
 
+import org.ovirt.engine.sdk.generator.Memory;
 import org.ovirt.engine.sdk.generator.RsdlData;
 import org.ovirt.engine.sdk.generator.XsdData;
 
@@ -29,11 +30,18 @@
 
     public static void main(String[] args) throws IOException, JAXBException {
         // Parse the command line parameters:
+        File memoryFile = null;
         File xsdFile = null;
         File xjbFile = null;
         File rsdlFile = null;
         for (int i = 0; i < args.length; i++) {
             switch (args[i]) {
+            case "--memory":
+                i++;
+                if (i < args.length) {
+                    memoryFile = new File(args[i]);
+                }
+                break;
             case "--xsd":
                 i++;
                 if (i < args.length) {
@@ -57,13 +65,17 @@
                 System.exit(1);
             }
         }
-        if (xsdFile == null || xjbFile == null || rsdlFile == null) {
+        if (xsdFile == null || xjbFile == null || rsdlFile == null || 
memoryFile == null) {
             System.err.println("Missing required parameters.");
             System.exit(1);
         }
 
         // Adjust the destination path to the platform:
         String distPath = DIST_PATH.replace('/', File.separatorChar);
+
+        // Load the memory:
+        Memory memory = Memory.getInstance();
+        memory.load(memoryFile);
 
         // Load the XML schema and the RSDL metadata:
         XsdData.getInstance().load(xsdFile);
@@ -74,5 +86,8 @@
 
         // Generate decorator classes:
         new RsdlCodegen().generate(distPath);
+
+        // Save the memory:
+        memory.save(memoryFile);
     }
 }
diff --git 
a/generator/src/main/java/org/ovirt/engine/sdk/generator/java/utils/ExceptionsAwareComparator.java
 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/java/utils/ExceptionsAwareComparator.java
new file mode 100644
index 0000000..7780a39
--- /dev/null
+++ 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/java/utils/ExceptionsAwareComparator.java
@@ -0,0 +1,95 @@
+//
+// Copyright (c) 2015 Red Hat, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package org.ovirt.engine.sdk.generator.java.utils;
+
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * This class is a comparator that takes into account exceptional ordering. 
For example, lets say that we need to sort
+ * a list of strings but we need to make sure that the strings {@code mary} 
and {@code joe} are always the first
+ * elements of the list, and they appear exactly in that order. To do so we 
could use this comparator as follows:
+ *
+ * <pre>
+ * List<String> names = ...;
+ * List<String> exceptions = Arrays.asList("mary", "joe");
+ * names.sort(new ExceptionsComparator<>(Person::getName, String::compareTo, 
exceptions);
+ * </pre>
+ *
+ * @param <T> the type of the objects to compare
+ */
+public class ExceptionsAwareComparator<T> implements Comparator<T> {
+    /**
+     * The comparator used to compare normal (non exceptional) objects.
+     */
+    private Comparator<? super T> normal;
+
+    /**
+     * The list of objects whose order must be preserved.
+     */
+    private List<? super T> exceptions;
+
+    /**
+     * Creates a new comparator that supports exceptions.
+     *
+     * @param normal the normal comparator to use for objects that aren't 
exceptions
+     * @param exceptions the exceptions that will always be put at the very 
beginning of the result
+     */
+    public ExceptionsAwareComparator(Comparator<? super T> normal, List<? 
super T> exceptions) {
+        this.normal = normal;
+        this.exceptions = exceptions;
+    }
+
+    @Override
+    public int compare(T left, T right) {
+        // Check if the objects to compare are exceptions:
+        int leftIndex = exceptions.indexOf(left);
+        int rightIndex = exceptions.indexOf(right);
+
+        // If both keys are exceptions then sort them according to their index 
in the exceptions list:
+        if (leftIndex != -1 && rightIndex != -1) {
+            return Integer.compare(leftIndex, rightIndex);
+        }
+
+        // If no key is an exception then just compare them as usual:
+        if (leftIndex == -1 && rightIndex == -1) {
+            return normal.compare(left, right);
+        }
+
+        // If one key is an exception and the other isn't, then the one that 
is an exception should always go first:
+        if (leftIndex != -1) {
+            return -1;
+        }
+        if (rightIndex != -1) {
+            return 1;
+        }
+        return 0;
+    }
+
+    /**
+     * This is a convenience method to avoid using directly the constructor, 
so that the resulting code looks more
+     * 8-ish.
+     *
+     * @param normal the normal comparator to use for objects that aren't 
exceptions
+     * @param exceptions the exceptions that will always be put at the very 
beginning of the result
+     * @param <T> the type of the objects to compare
+     * @return a comparator that takes into account the given exceptions
+     */
+    public static <T> Comparator<T> exceptions(Comparator<? super T> normal, 
List<? super T> exceptions) {
+        return new ExceptionsAwareComparator<T>(normal ,exceptions);
+    }
+}
diff --git 
a/generator/src/main/java/org/ovirt/engine/sdk/generator/java/utils/LinkUtils.java
 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/java/utils/LinkUtils.java
index 5c8ce96..eafa9a0 100644
--- 
a/generator/src/main/java/org/ovirt/engine/sdk/generator/java/utils/LinkUtils.java
+++ 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/java/utils/LinkUtils.java
@@ -16,11 +16,12 @@
 
 package org.ovirt.engine.sdk.generator.java.utils;
 
-
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.ovirt.engine.sdk.entities.DetailedLink;
 import org.ovirt.engine.sdk.entities.Header;
@@ -28,6 +29,13 @@
 import org.ovirt.engine.sdk.entities.Parameter;
 import org.ovirt.engine.sdk.entities.ParametersSet;
 import org.ovirt.engine.sdk.entities.Request;
+import org.ovirt.engine.sdk.generator.Memory;
+
+import static java.util.Arrays.asList;
+import static java.util.Comparator.comparing;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toList;
+import static 
org.ovirt.engine.sdk.generator.java.utils.ExceptionsAwareComparator.exceptions;
 
 public class LinkUtils {
     /**
@@ -39,6 +47,43 @@
         HEADERS_EXCEPTIONS.add("Content-Type");
         HEADERS_EXCEPTIONS.add("Filter");
     }
+
+    /**
+     * Key used to store the order of header parameters in the memory.
+     */
+    private static final String HEADERS_ORDER_KEY = "headers.order";
+
+    /**
+     * Some headers need to have an exceptional sorting (instead of just 
alphabetical) because that is how they used
+     * to be in the RSDL document, and the order of the corresponding method 
parameters can't be changed as it would
+     * break backwards compatibility. For example, the RSDL used to list the 
headers for operation to add a cluster in
+     * the following order:
+     *
+     * <pre>
+     * Expect
+     * Correlation-Id
+     * </pre>
+     *
+     * This means that the generated {@code add} method looks like this:
+     *
+     * <pre>
+     * Cluster add(Cluster cluster, String expect, String correlationId)
+     * </pre>
+     *
+     * If the RSDL changes and returns the headers in a different order then 
the generated code will also change, in
+     * a way that makes compilation fail, or even worse, in such a way that 
compilation still works but the meaning
+     * changes, like in this case:
+     *
+     * <pre>
+     * Cluster add(Cluster cluster, String correlationId, String except)
+     * </pre>
+     *
+     * In this example the caller will still compile correctly, but the 
arguments will be swapped.
+     */
+    private static List<String> HEADER_ORDER_EXCEPTIONS = asList(
+        "Expect",
+        "Correlation-Id"
+    );
 
     /**
      * Get the list of URL parameters that are available in the given link.
@@ -59,6 +104,7 @@
      * Get the list of headers available in the given link, filtering out the 
ones that should be ignored.
      */
     public static List<Header> getHeaders(DetailedLink dl) {
+        // Extract the header definitions from the link:
         List<Header> result = new ArrayList<>();
         Request request = dl.getRequest();
         if (request != null) {
@@ -71,6 +117,20 @@
                 }
             }
         }
+
+        // Get the order of the headers from the memory:
+        Memory memory = Memory.getInstance();
+        List<String> oldOrder = memory.getList(dl, HEADERS_ORDER_KEY);
+
+        // Sort the headers by name, taking into account the exceptions:
+        result.sort(comparing(Header::getName, exceptions(String::compareTo, 
oldOrder)));
+
+        // Make sure that we remember the new order for the next execution:
+        List<String> newOrder = 
result.stream().map(Header::getName).collect(toList());
+        if (!newOrder.isEmpty()) {
+            memory.putList(dl, HEADERS_ORDER_KEY, newOrder);
+        }
+
         return result;
     }
 }
diff --git a/generator/src/main/resources/README.md 
b/generator/src/main/resources/README.md
new file mode 100644
index 0000000..89582a0
--- /dev/null
+++ b/generator/src/main/resources/README.md
@@ -0,0 +1,39 @@
+Waht is this?
+=============
+
+The files in this directory are resources used by the code generator.
+
+`rsdl.xml` This file contains the RSDL metadata. It is extracted from the
+engine artifacts using the `update-metadata` profile and stored in the
+repository in order to simplify regeneration of the SDK.
+
+`api.xsd` This file contains the XML schema. Like the RSDL metadata it is
+extracted from the engine artifacts using the `update-metadata` profile.
+
+`api.xjb` This file contains the binding definitions used by the XJC
+compiler when generating the Java source code for the entities. It
+itsn't extracted from the engine, and it is necessary because the SDK
+uses different bindings than the engine.
+
+`memory.properties` This file stores information that the code generator needs 
to
+remember from one run to the next. For example, it needs to remember
+the order of the headers that were used to generate a method, as
+otherwise adding new headers (or changing the order in the RSDL)
+would produce serious backwards compatibility issues. For example,
+currently the order of the headers for the method to add a cluster
+is `Expect` and then `Correlation-Id`, so the generated code for one
+of the `add` methods of the `Clusters` class looks like this:
+
+    public Cluster add(Cluster cluster, String expect, String correlationId)
+    
+If this order changes, because new headers are added, or simply the RSDL
+is generated in a different way then the generated code could become
+like this:
+
+    public Cluster add(Cluster cluster, String correlationId, String expect)
+    
+That is extremelly dangerous, as it would change the meaning of the method
+but would still compile fine. To avoid this situation the memory file is
+used to remember, for example, the order of headers.
+
+    
diff --git a/generator/src/main/resources/memory.properties 
b/generator/src/main/resources/memory.properties
new file mode 100644
index 0000000..ec78919
--- /dev/null
+++ b/generator/src/main/resources/memory.properties
@@ -0,0 +1,278 @@
+link.clusters.add.headers.order=Expect Correlation-Id
+link.clusters.cluster_id.affinitygroups.add.headers.order=Expect
+link.clusters.cluster_id.affinitygroups.affinitygroup_id.vms.add.headers.order=Expect
+link.clusters.cluster_id.cpuprofiles.add.headers.order=Expect Correlation-Id
+link.clusters.cluster_id.cpuprofiles.cpuprofile_id.delete.headers.order=Correlation-Id
+link.clusters.cluster_id.delete.headers.order=Correlation-Id
+link.clusters.cluster_id.glusterhooks.glusterhook_id.delete.headers.order=Correlation-Id
+link.clusters.cluster_id.glusterhooks.glusterhook_id.disable.disable.headers.order=Correlation-Id
+link.clusters.cluster_id.glusterhooks.glusterhook_id.enable.enable.headers.order=Correlation-Id
+link.clusters.cluster_id.glusterhooks.glusterhook_id.resolve.resolve.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.add.headers.order=Expect Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.bricks.activate.activate.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.bricks.add.headers.order=Expect
 Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.bricks.brick_id.replace.replace.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.bricks.get.headers.order=All-Content
+link.clusters.cluster_id.glustervolumes.glustervolume_id.bricks.migrate.migrate.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.bricks.stopmigrate.stopmigrate.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.rebalance.rebalance.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.resetalloptions.resetalloptions.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.resetoption.resetoption.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.setoption.setoption.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.start.start.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.startprofile.startprofile.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.stop.stop.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.stopprofile.stopprofile.headers.order=Correlation-Id
+link.clusters.cluster_id.glustervolumes.glustervolume_id.stoprebalance.stoprebalance.headers.order=Correlation-Id
+link.clusters.cluster_id.networks.add.headers.order=Expect Correlation-Id
+link.clusters.cluster_id.networks.network_id.delete.headers.order=Correlation-Id
+link.clusters.cluster_id.networks.network_id.update.headers.order=Correlation-Id
+link.clusters.cluster_id.permissions.add.headers.order=Expect Correlation-Id
+link.clusters.cluster_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.clusters.cluster_id.update.headers.order=Correlation-Id
+link.cpuprofiles.add.headers.order=Expect Correlation-Id
+link.cpuprofiles.cpuprofile_id.delete.headers.order=Correlation-Id
+link.cpuprofiles.cpuprofile_id.permissions.add.headers.order=Expect 
Correlation-Id
+link.cpuprofiles.cpuprofile_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.cpuprofiles.cpuprofile_id.update.headers.order=Correlation-Id
+link.datacenters.add.headers.order=Expect Correlation-Id
+link.datacenters.datacenter_id.clusters.add.headers.order=Expect Correlation-Id
+link.datacenters.datacenter_id.clusters.cluster_id.delete.headers.order=Correlation-Id
+link.datacenters.datacenter_id.clusters.cluster_id.networks.add.headers.order=Expect
 Correlation-Id
+link.datacenters.datacenter_id.clusters.cluster_id.networks.network_id.delete.headers.order=Correlation-Id
+link.datacenters.datacenter_id.clusters.cluster_id.networks.network_id.update.headers.order=Correlation-Id
+link.datacenters.datacenter_id.clusters.cluster_id.permissions.add.headers.order=Expect
 Correlation-Id
+link.datacenters.datacenter_id.clusters.cluster_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.datacenters.datacenter_id.clusters.cluster_id.update.headers.order=Correlation-Id
+link.datacenters.datacenter_id.delete.headers.order=Correlation-Id
+link.datacenters.datacenter_id.iscsibonds.add.headers.order=Expect
+link.datacenters.datacenter_id.iscsibonds.iscsibond_id.update.headers.order=Expect
+link.datacenters.datacenter_id.networks.add.headers.order=Expect Correlation-Id
+link.datacenters.datacenter_id.networks.network_id.delete.headers.order=Correlation-Id
+link.datacenters.datacenter_id.networks.network_id.labels.add.headers.order=Expect
 Correlation-Id
+link.datacenters.datacenter_id.networks.network_id.labels.label_id.delete.headers.order=Correlation-Id
+link.datacenters.datacenter_id.networks.network_id.update.headers.order=Correlation-Id
+link.datacenters.datacenter_id.permissions.add.headers.order=Expect 
Correlation-Id
+link.datacenters.datacenter_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.datacenters.datacenter_id.qoss.add.headers.order=Expect Correlation-Id
+link.datacenters.datacenter_id.qoss.qos_id.delete.headers.order=Correlation-Id
+link.datacenters.datacenter_id.qoss.qos_id.update.headers.order=Correlation-Id
+link.datacenters.datacenter_id.storagedomains.add.headers.order=Expect 
Correlation-Id
+link.datacenters.datacenter_id.storagedomains.storagedomain_id.activate.activate.headers.order=Correlation-Id
+link.datacenters.datacenter_id.storagedomains.storagedomain_id.deactivate.deactivate.headers.order=Correlation-Id
+link.datacenters.datacenter_id.storagedomains.storagedomain_id.delete.headers.order=Correlation-Id
+link.datacenters.datacenter_id.storagedomains.storagedomain_id.disks.add.headers.order=Expect
 Correlation-Id
+link.datacenters.datacenter_id.storagedomains.storagedomain_id.disks.disk_id.delete.headers.order=Correlation-Id
+link.datacenters.datacenter_id.storagedomains.storagedomain_id.disks.disk_id.export.export.headers.order=Correlation-Id
+link.datacenters.datacenter_id.update.headers.order=Correlation-Id
+link.diskprofiles.add.headers.order=Expect Correlation-Id
+link.diskprofiles.diskprofile_id.delete.headers.order=Correlation-Id
+link.diskprofiles.diskprofile_id.permissions.add.headers.order=Expect 
Correlation-Id
+link.diskprofiles.diskprofile_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.diskprofiles.diskprofile_id.update.headers.order=Correlation-Id
+link.disks.add.headers.order=Expect Correlation-Id
+link.disks.disk_id.copy.copy.headers.order=Correlation-Id
+link.disks.disk_id.delete.headers.order=Correlation-Id
+link.disks.disk_id.export.export.headers.order=Correlation-Id
+link.disks.disk_id.move.move.headers.order=Correlation-Id
+link.events.add.headers.order=Expect Correlation-Id
+link.externalhostproviders.add.headers.order=Expect Correlation-Id
+link.externalhostproviders.externalhostprovider_id.delete.headers.order=Correlation-Id
+link.externalhostproviders.externalhostprovider_id.importcertificates.importcertificates.headers.order=Correlation-Id
+link.externalhostproviders.externalhostprovider_id.testconnectivity.testconnectivity.headers.order=Correlation-Id
+link.externalhostproviders.externalhostprovider_id.update.headers.order=Correlation-Id
+link.groups.add.headers.order=Correlation-Id
+link.groups.group_id.delete.headers.order=Correlation-Id
+link.groups.group_id.permissions.add.headers.order=Expect Correlation-Id
+link.groups.group_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.groups.group_id.roles.role_id.permits.add.headers.order=Expect 
Correlation-Id
+link.groups.group_id.roles.role_id.permits.permit_id.delete.headers.order=Correlation-Id
+link.groups.group_id.tags.add.headers.order=Expect Correlation-Id
+link.groups.group_id.tags.tag_id.delete.headers.order=Correlation-Id
+link.hosts.add.headers.order=Expect Correlation-Id
+link.hosts.get.headers.order=All-Content
+link.hosts.host_id.activate.activate.headers.order=Correlation-Id
+link.hosts.host_id.approve.approve.headers.order=Correlation-Id
+link.hosts.host_id.commitnetconfig.commitnetconfig.headers.order=Correlation-Id
+link.hosts.host_id.deactivate.deactivate.headers.order=Correlation-Id
+link.hosts.host_id.delete.headers.order=Correlation-Id
+link.hosts.host_id.fence.fence.headers.order=Correlation-Id
+link.hosts.host_id.fenceagents.add.headers.order=Expect Correlation-Id
+link.hosts.host_id.fenceagents.fenceagent_id.delete.headers.order=Correlation-Id
+link.hosts.host_id.fenceagents.fenceagent_id.update.headers.order=Expect 
Correlation-Id
+link.hosts.host_id.forceselectspm.forceselectspm.headers.order=Correlation-Id
+link.hosts.host_id.install.install.headers.order=Correlation-Id
+link.hosts.host_id.iscsidiscover.iscsidiscover.headers.order=Correlation-Id
+link.hosts.host_id.iscsilogin.iscsilogin.headers.order=Correlation-Id
+link.hosts.host_id.nics.add.headers.order=Expect Correlation-Id
+link.hosts.host_id.nics.nic_id.attach.attach.headers.order=Correlation-Id
+link.hosts.host_id.nics.nic_id.delete.headers.order=Correlation-Id
+link.hosts.host_id.nics.nic_id.detach.detach.headers.order=Correlation-Id
+link.hosts.host_id.nics.nic_id.labels.add.headers.order=Expect Correlation-Id
+link.hosts.host_id.nics.nic_id.labels.label_id.delete.headers.order=Correlation-Id
+link.hosts.host_id.nics.nic_id.update.headers.order=Correlation-Id
+link.hosts.host_id.nics.setupnetworks.setupnetworks.headers.order=Correlation-Id
+link.hosts.host_id.permissions.add.headers.order=Expect Correlation-Id
+link.hosts.host_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.hosts.host_id.refreshcapabilities.refreshcapabilities.headers.order=Correlation-Id
+link.hosts.host_id.tags.add.headers.order=Expect Correlation-Id
+link.hosts.host_id.tags.tag_id.delete.headers.order=Correlation-Id
+link.hosts.host_id.unregisteredstoragedomainsdiscover.unregisteredstoragedomainsdiscover.headers.order=Correlation-Id
+link.hosts.host_id.update.headers.order=Correlation-Id
+link.instancetypes.add.headers.order=Expect Correlation-Id
+link.instancetypes.instancetype_id.delete.headers.order=Correlation-Id
+link.jobs.add.headers.order=Expect Correlation-Id
+link.jobs.job_id.clear.clear.headers.order=Correlation-Id
+link.jobs.job_id.end.end.headers.order=Correlation-Id
+link.jobs.job_id.steps.add.headers.order=Expect Correlation-Id
+link.jobs.job_id.steps.step_id.end.end.headers.order=Correlation-Id
+link.macpools.add.headers.order=Expect Correlation-Id
+link.macpools.macpool_id.delete.headers.order=Correlation-Id
+link.macpools.macpool_id.update.headers.order=Correlation-Id
+link.networks.add.headers.order=Expect Correlation-Id
+link.networks.network_id.delete.headers.order=Correlation-Id
+link.networks.network_id.labels.add.headers.order=Expect Correlation-Id
+link.networks.network_id.labels.label_id.delete.headers.order=Correlation-Id
+link.networks.network_id.permissions.add.headers.order=Expect Correlation-Id
+link.networks.network_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.networks.network_id.update.headers.order=Correlation-Id
+link.networks.network_id.vnicprofiles.add.headers.order=Expect Correlation-Id
+link.networks.network_id.vnicprofiles.vnicprofile_id.delete.headers.order=Correlation-Id
+link.openstackimageproviders.add.headers.order=Expect Correlation-Id
+link.openstackimageproviders.openstackimageprovider_id.delete.headers.order=Correlation-Id
+link.openstackimageproviders.openstackimageprovider_id.importcertificates.importcertificates.headers.order=Correlation-Id
+link.openstackimageproviders.openstackimageprovider_id.testconnectivity.testconnectivity.headers.order=Correlation-Id
+link.openstackimageproviders.openstackimageprovider_id.update.headers.order=Correlation-Id
+link.openstacknetworkproviders.add.headers.order=Expect Correlation-Id
+link.openstacknetworkproviders.openstacknetworkprovider_id.delete.headers.order=Correlation-Id
+link.openstacknetworkproviders.openstacknetworkprovider_id.update.headers.order=Correlation-Id
+link.permissions.add.headers.order=Expect Correlation-Id
+link.permissions.permission_id.delete.headers.order=Correlation-Id
+link.roles.add.headers.order=Expect Correlation-Id
+link.roles.role_id.delete.headers.order=Correlation-Id
+link.roles.role_id.permits.add.headers.order=Expect Correlation-Id
+link.roles.role_id.permits.permit_id.delete.headers.order=Correlation-Id
+link.roles.role_id.update.headers.order=Correlation-Id
+link.schedulingpolicies.add.headers.order=Expect Correlation-Id
+link.schedulingpolicies.schedulingpolicy_id.balances.add.headers.order=Expect 
Correlation-Id
+link.schedulingpolicies.schedulingpolicy_id.balances.balance_id.delete.headers.order=Correlation-Id
+link.schedulingpolicies.schedulingpolicy_id.delete.headers.order=Correlation-Id
+link.schedulingpolicies.schedulingpolicy_id.filters.add.headers.order=Expect 
Correlation-Id
+link.schedulingpolicies.schedulingpolicy_id.filters.filter_id.delete.headers.order=Correlation-Id
+link.schedulingpolicies.schedulingpolicy_id.update.headers.order=Correlation-Id
+link.schedulingpolicies.schedulingpolicy_id.weights.add.headers.order=Expect 
Correlation-Id
+link.schedulingpolicies.schedulingpolicy_id.weights.weight_id.delete.headers.order=Correlation-Id
+link.schedulingpolicyunits.schedulingpolicyunit_id.delete.headers.order=Correlation-Id
+link.storageconnections.add.headers.order=Expect Correlation-Id
+link.storageconnections.storageconnection_id.delete.headers.order=Correlation-Id
+link.storageconnections.storageconnection_id.update.headers.order=Correlation-Id
+link.storagedomains.add.headers.order=Expect Correlation-Id
+link.storagedomains.storagedomain_id.delete.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.diskprofiles.add.headers.order=Expect 
Correlation-Id
+link.storagedomains.storagedomain_id.diskprofiles.diskprofile_id.delete.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.disks.add.headers.order=Expect 
Correlation-Id
+link.storagedomains.storagedomain_id.disks.disk_id.delete.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.disks.disk_id.export.export.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.disksnapshots.disksnapshot_id.delete.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.isattached.isattached.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.permissions.add.headers.order=Expect 
Correlation-Id
+link.storagedomains.storagedomain_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.storageconnections.add.headers.order=Expect
 Correlation-Id
+link.storagedomains.storagedomain_id.templates.template_id.delete.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.templates.template_id.import.import.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.templates.template_id.register.register.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.update.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.vms.vm_id.delete.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.vms.vm_id.import.import.headers.order=Correlation-Id
+link.storagedomains.storagedomain_id.vms.vm_id.register.register.headers.order=Correlation-Id
+link.tags.add.headers.order=Correlation-Id
+link.tags.tag_id.delete.headers.order=Correlation-Id
+link.tags.tag_id.update.headers.order=Correlation-Id
+link.templates.add.headers.order=Expect Correlation-Id
+link.templates.get.headers.order=All-Content
+link.templates.template_id.delete.headers.order=Correlation-Id
+link.templates.template_id.disks.disk_id.copy.copy.headers.order=Correlation-Id
+link.templates.template_id.disks.disk_id.delete.headers.order=Correlation-Id
+link.templates.template_id.disks.disk_id.export.export.headers.order=Correlation-Id
+link.templates.template_id.export.export.headers.order=Correlation-Id
+link.templates.template_id.nics.add.headers.order=Expect Correlation-Id
+link.templates.template_id.nics.nic_id.delete.headers.order=Correlation-Id
+link.templates.template_id.nics.nic_id.update.headers.order=Correlation-Id
+link.templates.template_id.permissions.add.headers.order=Expect Correlation-Id
+link.templates.template_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.templates.template_id.tags.add.headers.order=Expect Correlation-Id
+link.templates.template_id.tags.tag_id.delete.headers.order=Correlation-Id
+link.templates.template_id.update.headers.order=Correlation-Id
+link.templates.template_id.watchdogs.add.headers.order=Expect Correlation-Id
+link.templates.template_id.watchdogs.watchdog_id.delete.headers.order=Correlation-Id
+link.templates.template_id.watchdogs.watchdog_id.update.headers.order=Correlation-Id
+link.users.add.headers.order=Expect Correlation-Id
+link.users.user_id.delete.headers.order=Correlation-Id
+link.users.user_id.permissions.add.headers.order=Expect Correlation-Id
+link.users.user_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.users.user_id.roles.role_id.permits.add.headers.order=Expect 
Correlation-Id
+link.users.user_id.roles.role_id.permits.permit_id.delete.headers.order=Correlation-Id
+link.users.user_id.tags.add.headers.order=Expect Correlation-Id
+link.users.user_id.tags.tag_id.delete.headers.order=Correlation-Id
+link.vmpools.add.headers.order=Expect Correlation-Id
+link.vmpools.vmpool_id.allocatevm.allocatevm.headers.order=Correlation-Id
+link.vmpools.vmpool_id.delete.headers.order=Correlation-Id
+link.vmpools.vmpool_id.permissions.add.headers.order=Expect Correlation-Id
+link.vmpools.vmpool_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.vmpools.vmpool_id.update.headers.order=Correlation-Id
+link.vms.add.headers.order=Correlation-Id Expect
+link.vms.get.headers.order=All-Content
+link.vms.vm_id.cdroms.add.headers.order=Expect Correlation-Id
+link.vms.vm_id.cdroms.cdrom_id.delete.headers.order=Correlation-Id
+link.vms.vm_id.cdroms.cdrom_id.update.headers.order=Correlation-Id
+link.vms.vm_id.clone.clone.headers.order=Correlation-Id
+link.vms.vm_id.commit_snapshot.commit_snapshot.headers.order=Correlation-Id
+link.vms.vm_id.delete.headers.order=Correlation-Id
+link.vms.vm_id.detach.detach.headers.order=Correlation-Id
+link.vms.vm_id.disks.add.headers.order=Expect Correlation-Id
+link.vms.vm_id.disks.disk_id.activate.activate.headers.order=Correlation-Id
+link.vms.vm_id.disks.disk_id.deactivate.deactivate.headers.order=Correlation-Id
+link.vms.vm_id.disks.disk_id.delete.headers.order=Correlation-Id
+link.vms.vm_id.disks.disk_id.export.export.headers.order=Correlation-Id
+link.vms.vm_id.disks.disk_id.move.move.headers.order=Correlation-Id
+link.vms.vm_id.disks.disk_id.update.headers.order=Correlation-Id
+link.vms.vm_id.export.export.headers.order=Correlation-Id
+link.vms.vm_id.logon.logon.headers.order=Correlation-Id
+link.vms.vm_id.maintenance.maintenance.headers.order=Correlation-Id
+link.vms.vm_id.migrate.migrate.headers.order=Correlation-Id
+link.vms.vm_id.move.move.headers.order=Correlation-Id
+link.vms.vm_id.nics.add.headers.order=Expect Correlation-Id
+link.vms.vm_id.nics.get.headers.order=All-Content
+link.vms.vm_id.nics.nic_id.activate.activate.headers.order=Correlation-Id
+link.vms.vm_id.nics.nic_id.deactivate.deactivate.headers.order=Correlation-Id
+link.vms.vm_id.nics.nic_id.delete.headers.order=Correlation-Id
+link.vms.vm_id.nics.nic_id.update.headers.order=Correlation-Id
+link.vms.vm_id.numanodes.add.headers.order=Expect Correlation-Id
+link.vms.vm_id.numanodes.numanode_id.delete.headers.order=Correlation-Id
+link.vms.vm_id.numanodes.numanode_id.update.headers.order=Correlation-Id
+link.vms.vm_id.permissions.add.headers.order=Expect Correlation-Id
+link.vms.vm_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.vms.vm_id.preview_snapshot.preview_snapshot.headers.order=Correlation-Id
+link.vms.vm_id.reboot.reboot.headers.order=Correlation-Id
+link.vms.vm_id.shutdown.shutdown.headers.order=Correlation-Id
+link.vms.vm_id.snapshots.add.headers.order=Expect Correlation-Id
+link.vms.vm_id.snapshots.get.headers.order=All-Content
+link.vms.vm_id.snapshots.snapshot_id.delete.headers.order=Correlation-Id
+link.vms.vm_id.snapshots.snapshot_id.disks.disk_id.delete.headers.order=Correlation-Id
+link.vms.vm_id.snapshots.snapshot_id.restore.restore.headers.order=Correlation-Id
+link.vms.vm_id.start.start.headers.order=Correlation-Id
+link.vms.vm_id.stop.stop.headers.order=Correlation-Id
+link.vms.vm_id.suspend.suspend.headers.order=Correlation-Id
+link.vms.vm_id.tags.add.headers.order=Expect Correlation-Id
+link.vms.vm_id.tags.tag_id.delete.headers.order=Correlation-Id
+link.vms.vm_id.ticket.ticket.headers.order=Correlation-Id
+link.vms.vm_id.undo_snapshot.undo_snapshot.headers.order=Correlation-Id
+link.vms.vm_id.update.headers.order=Correlation-Id
+link.vms.vm_id.watchdogs.add.headers.order=Expect Correlation-Id
+link.vms.vm_id.watchdogs.watchdog_id.delete.headers.order=Correlation-Id
+link.vms.vm_id.watchdogs.watchdog_id.update.headers.order=Correlation-Id
+link.vnicprofiles.add.headers.order=Expect Correlation-Id
+link.vnicprofiles.vnicprofile_id.delete.headers.order=Correlation-Id
+link.vnicprofiles.vnicprofile_id.permissions.add.headers.order=Expect 
Correlation-Id
+link.vnicprofiles.vnicprofile_id.permissions.permission_id.delete.headers.order=Correlation-Id
+link.vnicprofiles.vnicprofile_id.update.headers.order=Correlation-Id
diff --git a/sdk/README.md b/sdk/README.md
index 77c7ddc..71f61a3 100644
--- a/sdk/README.md
+++ b/sdk/README.md
@@ -71,9 +71,14 @@
 changes are introduced.
 
 Once you have inspected the code, and if everything looks correct, commit the
-modified metadata and source files. The commit message for this change should
-include a reference to the commit or tag of the engine that was used to
-download the updated metadata. For example:
+modified metadata and source files.
+
+The process will also potentially modify the `memory.properties` file
+used by the generator. Changes to this file must also be commited.
+
+The commit message for this change should include a reference to the
+commit or tag of the engine that was used to download the updated
+metadata. For example:
 
     sdk: Regenerate against the latest API
 


-- 
To view, visit https://gerrit.ovirt.org/39459
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I4a3916a04e8475f105099836de67ab85d3fb3feb
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine-sdk-java
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