Explorar o código

AMBARI-6030. structured_out should be a JSON object, not stringified JSON (dlysnichenko)

Lisnichenko Dmitro %!s(int64=11) %!d(string=hai) anos
pai
achega
84df207bd4

+ 14 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TaskResourceProvider.java

@@ -17,6 +17,8 @@
  */
  */
 package org.apache.ambari.server.controller.internal;
 package org.apache.ambari.server.controller.internal;
 
 
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.TaskStatusRequest;
 import org.apache.ambari.server.controller.TaskStatusRequest;
@@ -63,6 +65,7 @@ class TaskResourceProvider extends AbstractControllerResourceProvider {
   protected static final String TASK_COMMAND_DET_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "command_detail");
   protected static final String TASK_COMMAND_DET_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "command_detail");
   protected static final String TASK_CUST_CMD_NAME_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "custom_command_name");
   protected static final String TASK_CUST_CMD_NAME_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "custom_command_name");
 
 
+  private static final Gson gson = new Gson();
 
 
   private static Set<String> pkPropertyIds =
   private static Set<String> pkPropertyIds =
       new HashSet<String>(Arrays.asList(new String[]{
       new HashSet<String>(Arrays.asList(new String[]{
@@ -148,7 +151,7 @@ class TaskResourceProvider extends AbstractControllerResourceProvider {
         setResourceProperty(resource, TASK_EXIT_CODE_PROPERTY_ID, response.getExitCode(), requestedIds);
         setResourceProperty(resource, TASK_EXIT_CODE_PROPERTY_ID, response.getExitCode(), requestedIds);
         setResourceProperty(resource, TASK_STDERR_PROPERTY_ID, response.getStderr(), requestedIds);
         setResourceProperty(resource, TASK_STDERR_PROPERTY_ID, response.getStderr(), requestedIds);
         setResourceProperty(resource, TASK_STOUT_PROPERTY_ID, response.getStdout(), requestedIds);
         setResourceProperty(resource, TASK_STOUT_PROPERTY_ID, response.getStdout(), requestedIds);
-        setResourceProperty(resource, TASK_STRUCT_OUT_PROPERTY_ID, response.getStructuredOut(), requestedIds);
+        setResourceProperty(resource, TASK_STRUCT_OUT_PROPERTY_ID, prepareStructuredOutJson(response.getStructuredOut()), requestedIds);
         setResourceProperty(resource, TASK_START_TIME_PROPERTY_ID, response.getStartTime(), requestedIds);
         setResourceProperty(resource, TASK_START_TIME_PROPERTY_ID, response.getStartTime(), requestedIds);
         setResourceProperty(resource, TASK_END_TIME_PROPERTY_ID, response.getEndTime(), requestedIds);
         setResourceProperty(resource, TASK_END_TIME_PROPERTY_ID, response.getEndTime(), requestedIds);
         setResourceProperty(resource, TASK_ATTEMPT_CNT_PROPERTY_ID, response.getAttemptCount(), requestedIds);
         setResourceProperty(resource, TASK_ATTEMPT_CNT_PROPERTY_ID, response.getAttemptCount(), requestedIds);
@@ -167,6 +170,16 @@ class TaskResourceProvider extends AbstractControllerResourceProvider {
     return resources;
     return resources;
   }
   }
 
 
+  Object prepareStructuredOutJson(String structuredOutStr) {
+    Object result = null;
+    try {
+      result = gson.fromJson(structuredOutStr, Map.class);
+    } catch (JsonSyntaxException exception) {
+      LOG.warn("Can not parse structured output string " + structuredOutStr);
+    }
+    return result;
+  }
+
   @Override
   @Override
   public RequestStatus updateResources(Request request, Predicate predicate)
   public RequestStatus updateResources(Request request, Predicate predicate)
       throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
       throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {

+ 29 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/TaskResourceProviderTest.java

@@ -29,10 +29,12 @@ import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.junit.Assert;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.Test;
+import static org.junit.Assert.*;
 
 
 import java.util.HashSet;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
 
 
@@ -198,4 +200,31 @@ public class TaskResourceProviderTest {
     // verify
     // verify
     verify(managementController);
     verify(managementController);
   }
   }
+
+  @Test
+  public void testPrepareStructuredOutJson() {
+    Resource.Type type = Resource.Type.Task;
+    // Test general case
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    TaskResourceProvider taskResourceProvider = new TaskResourceProvider(
+            PropertyHelper.getPropertyIds(type),
+            PropertyHelper.getKeyPropertyIds(type), managementController);
+    replay(managementController);
+
+    // Check parsing of nested JSON
+    Map result = (Map) taskResourceProvider.prepareStructuredOutJson("{\"a\":\"b\", \"c\": {\"d\":\"e\",\"f\": [\"g\",\"h\"],\"i\": {\"k\":\"l\"}}}");
+    assertEquals(result.size(), 2);
+    Map submap = (Map) result.get("c");
+    assertEquals(submap.size(), 3);
+    List sublist = (List) submap.get("f");
+    assertEquals(sublist.size(), 2);
+    Map subsubmap = (Map) submap.get("i");
+    assertEquals(subsubmap.size(), 1);
+    assertEquals(subsubmap.get("k"), "l");
+    // Check negative case - invalid JSON
+    result = (Map) taskResourceProvider.prepareStructuredOutJson("{\"a\": invalid JSON}");
+    assertNull(result);
+
+    verify(managementController);
+  }
 }
 }