Note: This is a beta release of Red Hat Bugzilla 5.0. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Also email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback here.

Bug 1087916

Summary: Restapi throws NPE when POST action for end job step is sent.
Product: Red Hat Enterprise Virtualization Manager Reporter: Ondra Machacek <omachace>
Component: ovirt-engine-restapiAssignee: Juan Hernández <juan.hernandez>
Status: CLOSED CURRENTRELEASE QA Contact: Ondra Machacek <omachace>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 3.4.0CC: aberezin, bazulay, emesika, gklein, iheim, oramraz, pstehlik, rbalakri, Rhev-m-bugs, yeylon
Target Milestone: ---   
Target Release: 3.5.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard: infra
Fixed In Version: ovirt-engine-3.5.0_alpha1 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-02-17 17:10:51 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: Infra RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Bug Depends On:    
Bug Blocks: 1142923, 1156165    

Description Ondra Machacek 2014-04-15 15:01:10 UTC
Description of problem:

If some of the elemements <async>, <grace_period> or <succeeded> is missing
when sending end action for job step rest api throws NPE.


Version-Release number of selected component (if applicable):
av6.1

How reproducible:
always

Steps to Reproduce:
curl -k -X POST -H "Accept: application/xml" -H "Content-Type: application/xml" -H "Filter: $filter" \
    -d "<action></action>" \
     -u $U $URL/jobs/3f84b6d7-592d-4b86-85ea-ae57450c3c89/steps/824593bf-95b2-44e4-80f2-dd47a90aa600/end

Actual results:
throws NPE (see additional info)

Expected results:
Success/Error if attributes are mandatory.

Additional info:


<html><head><title>JBoss Web/7.2.2.Final-redhat-1 - JBWEB000064: Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>JBWEB000065: HTTP Status 500 - java.lang.NullPointerException</h1><HR size="1" noshade="noshade"><p><b>JBWEB000309: type</b> JBWEB000066: Exception report</p><p><b>JBWEB000068: message</b> <u>java.lang.NullPointerException</u></p><p><b>JBWEB000069: description</b> <u>JBWEB000145: The server encountered an internal error that prevented it from fulfilling this request.</u></p><p><b>JBWEB000070: exception</b> <pre>org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException
	org.jboss.resteasy.core.SynchronousDispatcher.handleApplicationException(SynchronousDispatcher.java:365)
	org.jboss.resteasy.core.SynchronousDispatcher.handleException(SynchronousDispatcher.java:233)
	org.jboss.resteasy.core.SynchronousDispatcher.handleInvokerException(SynchronousDispatcher.java:209)
	org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:557)
	org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:524)
	org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:126)
	org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208)
	org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55)
	org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
	org.ovirt.engine.core.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:80)
</pre></p><p><b>JBWEB000071: root cause</b> <pre>java.lang.NullPointerException
	org.ovirt.engine.api.restapi.resource.BackendStepResource.end(BackendStepResource.java:53)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.lang.reflect.Method.invoke(Method.java:601)
	org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
	org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:269)
	org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:227)
	org.jboss.resteasy.core.ResourceLocator.invokeOnTargetObject(ResourceLocator.java:159)
	org.jboss.resteasy.core.ResourceLocator.invoke(ResourceLocator.java:107)
	org.jboss.resteasy.core.ResourceLocator.invokeOnTargetObject(ResourceLocator.java:154)
	org.jboss.resteasy.core.ResourceLocator.invoke(ResourceLocator.java:107)
	org.jboss.resteasy.core.ResourceLocator.invokeOnTargetObject(ResourceLocator.java:154)
	org.jboss.resteasy.core.ResourceLocator.invoke(ResourceLocator.java:92)
	org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:542)
	org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:524)
	org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:126)
	org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208)
	org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55)
	org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
	org.ovirt.engine.core.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:80)
</pre></p><p><b>JBWEB000072: note</b> <u>JBWEB000073: The full stack trace of the root cause is available in the JBoss Web/7.2.2.Final-redhat-1 logs.</u></p><HR size="1" noshade="noshade"><h3>JBoss Web/7.2.2.Final-redhat-1</h3></body></html>

Comment 1 Ondra Machacek 2014-04-15 15:14:28 UTC
not true for grace_period and async. It could be missing.
Only when <succeeded> is missing NPE appears.

Comment 2 Juan Hernández 2014-04-15 15:25:30 UTC
This happens because the "suceeded" parameter isn't declared as mandatory, and ins't validated, but then we get its value as follows:

  new EndExternalStepParameters(guid, action.isSucceeded())

When the parameter hasn't been provided the "isSuceeded" method will return null, and then the constructor of "EndExternalStepParameters" will try to unbox it and thus will produce the NPE.

If the parameter is mandatory then it should be documented as such in the RSDL metadata (in the rsdl_metadata.yaml file) and it should be validated:

  validateParameters(action, "suceeded")

If it isn't mandatory then, when it isn't provided by the user, the RESTAPI should send to the backend a parameters object without a value, and the backend should assign whatever default is appropriate.

Eli, is this parameter required?

Comment 3 Juan Hernández 2014-04-29 09:12:09 UTC
*** Bug 1092361 has been marked as a duplicate of this bug. ***

Comment 4 Juan Hernández 2014-04-29 09:14:45 UTC
I just closed bug 1092361 as duplicate of this one. It isn't exactly the same issue, but fixing the documentation for "succeeded" will fix both issues. We need to do something like this:

diff --git a/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml b/backend/manager/modules/resta
index 7e5fc87..6ae37d2 100644
--- a/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml
+++ b/backend/manager/modules/restapi/interface/definition/src/main/resources/rsdl_metadata.yaml
@@ -4615,7 +4615,8 @@ actions:
       parameterType: Action
       signatures:
       - mandatoryArguments: {}
-        optionalArguments: {action.force: 'xs:boolean', action.status.state: 'xs:string', action.async: 'xs:boolean', action.grace_per
+        optionalArguments: {action.force: 'xs:boolean', action.status.state: 'xs:string', action.async: 'xs:boolean', action.grace_per
+          succeeded: 'xs:boolean'}
         description: invoke the command to end the specified step of an external job with an optional agrument to force the operation
     urlparams: {}
     headers:

But as I said in comment 2 I don't know if the parameter is mandatory or optional.

Eli, I need your help.

Comment 5 Eli Mesika 2014-05-08 12:47:16 UTC
(In reply to Juan Hernández from comment #4)
> But as I said in comment 2 I don't know if the parameter is mandatory or
> optional.
> 
> Eli, I need your help.

The parameter should be mandatory

Comment 6 Juan Hernández 2014-05-08 13:18:12 UTC
The proposed patch adds a validation to check that the "succeeded" parameter is present, so that the RESTAPI will return the following message if it isn't:

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <fault>
    <reason>Incomplete parameters</reason>
    <detail>Action [succeeded] required for end</detail>
  </fault>

It also updates the RSDL so that the parameter will be documented as mandatory.

Comment 7 Ondra Machacek 2014-06-16 13:33:23 UTC
Ok in ovirt-engine-restapi-3.5.0-0.0.master.20140605145557.git3ddd2de.el6.noarch

curl -k -X POST -H "Accept: application/xml" -H "Content-Type: application/xml" -H "Filter: $filter" -d "<action><async>false</async></action>" -u $U $URL/jobs/dce4297b-98ff-4ee7-a434-08a0b4ca33f8/steps/a25cbfe8d89c-40f6-a9bd-929e130bfa47/end

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<fault>
    <reason>Incomplete parameters</reason>
    <detail>Action [succeeded] required for end</detail>
</fault>

Comment 8 Eyal Edri 2015-02-17 17:10:51 UTC
rhev 3.5.0 was released. closing.