Uploaded image for project: 'OpenShift Java Client'
  1. OpenShift Java Client
  2. OSJC-169

Provide constant implementations for KubernetesResource#equals and #hashCode

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Critical Critical
    • 1.0.0
    • 1.0.0
    • core

      The current implementation of #equals and #hashCode in KubernetesResource are non-constant. Thus storing and retrieving resources in/from a map may fail at times.

      The current impl look as follows:

      	@Override
      	public int hashCode() {
      		final int prime = 31;
      		int result = 1;
      		result = prime * result + ((node == null) ? 0 : node.hashCode());
      		return result;
      	}
      	
      	@Override
      	public boolean equals(Object obj) {
      		if (this == obj)
      			return true;
      		if (obj == null)
      			return false;
      		if (getClass() != obj.getClass())
      			return false;
      		KubernetesResource other = (KubernetesResource) obj;
      		if (node == null) {
      			if (other.node != null)
      				return false;
      		} else if (!node.equals(other.node))
      			return false;
      		return true;
      	}
      

      They delegate to jboss dmr/node. In case of ObjectModelValue an internal LinkedHashMap is used to store/cache values that are extracted from the json and is responsible for #equals and #hashCode

      ObjectModelValue
          /**
           * Determine whether this object is equal to another.
           * 
           * @param other the other object
           * @return {@code true} if they are equal, {@code false} otherwise
           */
          public boolean equals(final ObjectModelValue other) {
              return this == other || other != null && other.map.equals(map);
          }
      
          @Override
          public int hashCode() {
              return map.hashCode();
          }
      

      This can lead to non-constant answer since the structure of this map can change with the progress of the parsing and value extraction.
      This then leads to non-constant behaviour in our resources which then cause map storing/retrieval of our resource to fail.
      The most prominent failure case is where one wants to display those in an Eclipse viewer and refresh them. Btw. the 1st time of display and the refresh the structure in dmr/node may change and thus the refresh in the Eclipse viewer will fail.

      Example (notice how displayName was added to the dmr node after the initial display, before the refresh is executed):
      1) a project resource at display time:

      {"metadata" : {"name" : "default", "selfLink" : "/osapi/v1beta3/projects/default", "uid" : "e9d09a41-008a-11e5-b2ee-3c970ecf95dc", "resourceVersion" : "4", "creationTimestamp" : "2015-05-22T14:00:33Z", "annotations" : null, "namespace" : null}, "spec" : {"finalizers" : ["kubernetes"]}, "status" : {"phase" : "Active"}, "apiVersion" : "v1beta3", "kind" : "Project"}
      

      2) the same project resource when the refresh is tried:

      {"metadata" : {"name" : "default", "selfLink" : "/osapi/v1beta3/projects/default", "uid" : "e9d09a41-008a-11e5-b2ee-3c970ecf95dc", "resourceVersion" : "4", "creationTimestamp" : "2015-05-22T14:00:33Z", "annotations" : null, "namespace" : null}, "spec" : {"finalizers" : ["kubernetes"]}, "status" : {"phase" : "Active"}, "apiVersion" : "v1beta3", "kind" : "Project", "displayName" : null}
      

              adietish@redhat.com André Dietisheim
              adietish@redhat.com André Dietisheim
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved: