This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch 4.11
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.11 by this push:
     new f02e402  kvm: send unsupported answer only when applicable (#2714)
f02e402 is described below

commit f02e402ebb86d9ab5b6f34c04e57460ed53b7827
Author: dahn <[email protected]>
AuthorDate: Thu Jun 21 07:33:43 2018 +0200

    kvm: send unsupported answer only when applicable (#2714)
    
    Throw specific NPE child when command is known not to be known. Add unit 
tests.
---
 core/src/com/cloud/resource/RequestWrapper.java    | 23 +++++++++++-------
 .../kvm/resource/LibvirtComputingResource.java     | 11 ++++++++-
 .../resource/wrapper/LibvirtRequestWrapper.java    |  3 +++
 .../kvm/resource/LibvirtComputingResourceTest.java | 27 ++++++++++++++++++++++
 4 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/core/src/com/cloud/resource/RequestWrapper.java 
b/core/src/com/cloud/resource/RequestWrapper.java
index 4e754d6..d1a3c1f 100644
--- a/core/src/com/cloud/resource/RequestWrapper.java
+++ b/core/src/com/cloud/resource/RequestWrapper.java
@@ -29,6 +29,15 @@ import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
 
 public abstract class RequestWrapper {
+    static public class CommandNotSupported extends NullPointerException {
+        public CommandNotSupported(String msg) {
+            super(msg);
+        }
+        public CommandNotSupported(String msg, Throwable cause) {
+            super(msg);
+            initCause(cause);
+        }
+    }
 
     private static final Logger s_logger = 
Logger.getLogger(RequestWrapper.class);
 
@@ -52,7 +61,7 @@ public abstract class RequestWrapper {
 
                 keepResourceClass = keepResourceClass2;
             } catch (final ClassCastException e) {
-                throw new NullPointerException("No key found for '" + 
command.getClass() + "' in the Map!");
+                throw new CommandNotSupported("No key found for '" + 
command.getClass() + "' in the Map!");
             }
         }
         return resource;
@@ -69,14 +78,14 @@ public abstract class RequestWrapper {
                 final Class<? extends Command> commandClass2 = (Class<? 
extends Command>) keepCommandClass.getSuperclass();
 
                 if (commandClass2 == null) {
-                    throw new NullPointerException("All the COMMAND hierarchy 
tree has been visited but no compliant key has been found for '" + commandClass 
+ "'.");
+                    throw new CommandNotSupported("All the COMMAND hierarchy 
tree has been visited but no compliant key has been found for '" + commandClass 
+ "'.");
                 }
 
                 commandWrapper = resourceCommands.get(commandClass2);
 
                 keepCommandClass = commandClass2;
             } catch (final ClassCastException e) {
-                throw new NullPointerException("No key found for '" + 
keepCommandClass.getClass() + "' in the Map!");
+                throw new CommandNotSupported("No key found for '" + 
keepCommandClass.getClass() + "' in the Map!");
             } catch (final NullPointerException e) {
                 // Will now traverse all the resource hierarchy. Returning null
                 // is not a problem.
@@ -102,7 +111,7 @@ public abstract class RequestWrapper {
                 final Class<? extends ServerResource> resourceClass2 = 
(Class<? extends ServerResource>) keepResourceClass.getSuperclass();
 
                 if (resourceClass2 == null) {
-                    throw new NullPointerException("All the SERVER-RESOURCE 
hierarchy tree has been visited but no compliant key has been found for '" + 
command.getClass() + "'.");
+                    throw new CommandNotSupported("All the SERVER-RESOURCE 
hierarchy tree has been visited but no compliant key has been found for '" + 
command.getClass() + "'.");
                 }
 
                 final Hashtable<Class<? extends Command>, CommandWrapper> 
resourceCommands2 = retrieveResource(command,
@@ -110,10 +119,8 @@ public abstract class RequestWrapper {
                 keepResourceClass = resourceClass2;
 
                 commandWrapper = retrieveCommands(command.getClass(), 
resourceCommands2);
-            } catch (final ClassCastException e) {
-                throw new NullPointerException("No key found for '" + 
command.getClass() + "' in the Map!");
-            } catch (final NullPointerException e) {
-                throw e;
+            } catch (final ClassCastException | NullPointerException e) {
+                throw new CommandNotSupported("No key found for '" + 
command.getClass() + "' in the Map!", e);
             }
         }
         return commandWrapper;
diff --git 
a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
 
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 424280c..8a94b05 100644
--- 
a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ 
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -47,6 +47,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
+import com.cloud.resource.RequestWrapper;
 import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
 import org.apache.cloudstack.utils.hypervisor.HypervisorUtils;
@@ -1432,13 +1433,21 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
         return true;
     }
 
+    /**
+     * This finds a command wrapper to handle the command and executes it.
+     * If no wrapper is found an {@see UnsupportedAnswer} is sent back.
+     * Any other exceptions are to be caught and wrapped in an generic {@see 
Answer}, marked as failed.
+     *
+     * @param cmd the instance of a {@see Command} to execute.
+     * @return the for the {@see Command} appropriate {@see Answer} or {@see 
UnsupportedAnswer}
+     */
     @Override
     public Answer executeRequest(final Command cmd) {
 
         final LibvirtRequestWrapper wrapper = 
LibvirtRequestWrapper.getInstance();
         try {
             return wrapper.execute(cmd, this);
-        } catch (final Exception e) {
+        } catch (final RequestWrapper.CommandNotSupported cmde) {
             return Answer.createUnsupportedCommandAnswer(cmd);
         }
     }
diff --git 
a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java
 
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java
index 0b413bc..436a130 100644
--- 
a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java
+++ 
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java
@@ -72,6 +72,9 @@ public class LibvirtRequestWrapper extends RequestWrapper {
             commandWrapper = retryWhenAllFails(command, resourceClass, 
resourceCommands);
         }
 
+        if (commandWrapper == null) {
+            throw new CommandNotSupported("No way to handle " + 
command.getClass());
+        }
         return commandWrapper.execute(command, serverResource);
     }
 }
\ No newline at end of file
diff --git 
a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
 
b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
index 795b961..be191f5 100644
--- 
a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
+++ 
b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
@@ -38,6 +38,8 @@ import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpressionException;
 import javax.xml.xpath.XPathFactory;
 
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.UnsupportedAnswer;
 import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuTuneDef;
 import org.apache.commons.lang.SystemUtils;
 import org.joda.time.Duration;
@@ -5191,4 +5193,29 @@ public class LibvirtComputingResourceTest {
         Assert.assertEquals(CpuTuneDef.MIN_QUOTA, cpuTuneDef.getQuota());
         Assert.assertEquals((int) (CpuTuneDef.MIN_QUOTA / pct), 
cpuTuneDef.getPeriod());
     }
+
+    @Test
+    public void testUnknownCommand() {
+        libvirtComputingResource = new LibvirtComputingResource();
+        Command cmd = new Command() {
+            @Override public boolean executeInSequence() {
+                return false;
+            }
+        };
+        Answer ans = libvirtComputingResource.executeRequest(cmd);
+        assertTrue(ans instanceof UnsupportedAnswer);
+    }
+
+    @Test
+    public void testKnownCommand() {
+        libvirtComputingResource = new LibvirtComputingResource();
+        Command cmd = new PingTestCommand() {
+            @Override public boolean executeInSequence() {
+                throw new NullPointerException("test succeeded");
+            }
+        };
+        Answer ans = libvirtComputingResource.executeRequest(cmd);
+        assertFalse(ans instanceof UnsupportedAnswer);
+        assertTrue(ans instanceof Answer);
+    }
 }

Reply via email to