Repository: cloudslang/cloud-slang
Issue: LanguageEventData.getException throw ClassCastException

2015-06-11 11:24:57,465 [1_WorkerExecutionThread-13_124100530](ExecutionServiceImpl.java:100) ERROR - Error during execution: 
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Exception
    at io.cloudslang.lang.runtime.events.LanguageEventData.getException(LanguageEventData.java:106)


Changed files:
cloudslang-content-verifier/src/main/java/io/cloudslang/lang/tools/build/tester/TriggerTestCaseEventListener.java
cloudslang-tests/src/main/java/io/cloudslang/lang/systemtests/TriggerFlows.java
cloudslang-content-verifier/src/test/java/io/cloudslang/lang/tools/build/tester/SlangTestRunnerTest.java
cloudslang-runtime/src/main/java/io/cloudslang/lang/runtime/events/LanguageEventData.java
cloudslang-runtime/src/test/java/io/cloudslang/lang/runtime/events/LanguageEventDataTest.java

diff --git a/cloudslang-content-verifier/src/main/java/io/cloudslang/lang/tools/build/tester/TriggerTestCaseEventListener.java b/cloudslang-content-verifier/src/main/java/io/cloudslang/lang/tools/build/tester/TriggerTestCaseEventListener.java
index 88a2f0573..3a3cf1ab2 100644
--- a/cloudslang-content-verifier/src/main/java/io/cloudslang/lang/tools/build/tester/TriggerTestCaseEventListener.java
+++ b/cloudslang-content-verifier/src/main/java/io/cloudslang/lang/tools/build/tester/TriggerTestCaseEventListener.java
@@ -21,8 +21,6 @@ package io.cloudslang.lang.tools.build.tester;
 import io.cloudslang.lang.entities.ScoreLangConstants;
 import io.cloudslang.lang.runtime.events.LanguageEventData;
 import org.apache.commons.collections4.MapUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
 import io.cloudslang.score.events.EventConstants;
 import io.cloudslang.score.events.ScoreEvent;
 import io.cloudslang.score.events.ScoreEventListener;
@@ -60,7 +58,8 @@ public class TriggerTestCaseEventListener implements ScoreEventListener {
 
     @Override
     public synchronized void onEvent(ScoreEvent scoreEvent) throws InterruptedException {
-        @SuppressWarnings("unchecked") Map<String,Serializable> data = (Map<String,Serializable>)scoreEvent.getData();
+        @SuppressWarnings("unchecked") Map<String,Serializable> data = (Map<String,Serializable>) scoreEvent.getData();
+        LanguageEventData eventData;
         switch (scoreEvent.getEventType()){
             case EventConstants.SCORE_FINISHED_EVENT :
                 break;
@@ -70,15 +69,18 @@ public class TriggerTestCaseEventListener implements ScoreEventListener {
                 flowFinished.set(true);
                 break;
             case ScoreLangConstants.SLANG_EXECUTION_EXCEPTION:
-                errorMessage.set((String)data.get(LanguageEventData.EXCEPTION));
+                eventData = (LanguageEventData) data;
+                errorMessage.set(eventData.getException());
                 flowFinished.set(true);
                 break;
             case ScoreLangConstants.EVENT_EXECUTION_FINISHED :
-                result = (String)data.get(LanguageEventData.RESULT);
+                eventData = (LanguageEventData) data;
+                result = eventData.getResult();
                 flowFinished.set(true);
                 break;
             case ScoreLangConstants.EVENT_OUTPUT_END:
-                Map<String, Serializable> extractOutputs = extractOutputs(data);
+                eventData = (LanguageEventData) data;
+                Map<String, Serializable> extractOutputs = extractOutputs(eventData);
                 if(MapUtils.isNotEmpty(extractOutputs)) {
                     outputs = extractOutputs;
                 }
@@ -90,18 +92,17 @@ public class TriggerTestCaseEventListener implements ScoreEventListener {
         return new ReturnValues(outputs, result);
     }
 
-    private static Map<String, Serializable> extractOutputs(Map<String, Serializable> data) {
+    private static Map<String, Serializable> extractOutputs(LanguageEventData data) {
 
         Map<String, Serializable> outputsMap = new HashMap<>();
 
         boolean thereAreOutputsForRootPath =
                 data.containsKey(LanguageEventData.OUTPUTS)
                 && data.containsKey(LanguageEventData.PATH)
-                && data.get(LanguageEventData.PATH).equals(EXEC_START_PATH);
+                && data.getPath().equals(EXEC_START_PATH);
 
         if (thereAreOutputsForRootPath) {
-            @SuppressWarnings("unchecked") Map<String, Serializable> outputs =
-                    (Map<String, Serializable>) data.get(LanguageEventData.OUTPUTS);
+            Map<String, Serializable> outputs = data.getOutputs();
             if (MapUtils.isNotEmpty(outputs)) outputsMap.putAll(outputs);
         }
 
diff --git a/cloudslang-content-verifier/src/test/java/io/cloudslang/lang/tools/build/tester/SlangTestRunnerTest.java b/cloudslang-content-verifier/src/test/java/io/cloudslang/lang/tools/build/tester/SlangTestRunnerTest.java
index 89e2bef34..1a70d3a2a 100644
--- a/cloudslang-content-verifier/src/test/java/io/cloudslang/lang/tools/build/tester/SlangTestRunnerTest.java
+++ b/cloudslang-content-verifier/src/test/java/io/cloudslang/lang/tools/build/tester/SlangTestRunnerTest.java
@@ -1,7 +1,5 @@
 package io.cloudslang.lang.tools.build.tester;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Sets;
 import io.cloudslang.lang.api.Slang;
 import io.cloudslang.lang.compiler.SlangSource;
 import io.cloudslang.lang.entities.CompilationArtifact;
@@ -449,7 +447,9 @@ public class SlangTestRunnerTest {
             @Override
             public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                 ScoreEventListener listener = (ScoreEventListener) invocationOnMock.getArguments()[0];
-                listener.onEvent(new ScoreEvent(ScoreLangConstants.EVENT_EXECUTION_FINISHED, ImmutableMap.of(LanguageEventData.RESULT, "SUCCESS")));
+                LanguageEventData data = new LanguageEventData();
+                data.setResult("SUCCESS");
+                listener.onEvent(new ScoreEvent(ScoreLangConstants.EVENT_EXECUTION_FINISHED, data));
                 return listener;
             }
         }).when(slang).subscribeOnEvents(any(ScoreEventListener.class), anySetOf(String.class));
@@ -460,9 +460,13 @@ public class SlangTestRunnerTest {
             @Override
             public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                 ScoreEventListener listener = (ScoreEventListener) invocationOnMock.getArguments()[0];
-                ImmutableMap data = ImmutableMap.of(LanguageEventData.OUTPUTS, outputs, LanguageEventData.PATH, "0");
+                LanguageEventData data = new LanguageEventData();
+                data.setOutputs(outputs);
+                data.setPath("0");
                 listener.onEvent(new ScoreEvent(ScoreLangConstants.EVENT_OUTPUT_END, data));
-                listener.onEvent(new ScoreEvent(ScoreLangConstants.EVENT_EXECUTION_FINISHED, ImmutableMap.of(LanguageEventData.RESULT, "SUCCESS")));
+                data = new LanguageEventData();
+                data.setResult("SUCCESS");
+                listener.onEvent(new ScoreEvent(ScoreLangConstants.EVENT_EXECUTION_FINISHED, data));
                 return listener;
             }
         }).when(slang).subscribeOnEvents(any(ScoreEventListener.class), anySetOf(String.class));
@@ -473,7 +477,9 @@ public class SlangTestRunnerTest {
             @Override
             public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                 ScoreEventListener listener = (ScoreEventListener) invocationOnMock.getArguments()[0];
-                listener.onEvent(new ScoreEvent(ScoreLangConstants.SLANG_EXECUTION_EXCEPTION, ImmutableMap.of(LanguageEventData.EXCEPTION, "Error")));
+                LanguageEventData data = new LanguageEventData();
+                data.setException("Error");
+                listener.onEvent(new ScoreEvent(ScoreLangConstants.SLANG_EXECUTION_EXCEPTION, data));
                 return listener;
             }
         }).when(slang).subscribeOnEvents(any(ScoreEventListener.class), anySetOf(String.class));
diff --git a/cloudslang-runtime/src/main/java/io/cloudslang/lang/runtime/events/LanguageEventData.java b/cloudslang-runtime/src/main/java/io/cloudslang/lang/runtime/events/LanguageEventData.java
index 2e3259526..ab1a63258 100644
--- a/cloudslang-runtime/src/main/java/io/cloudslang/lang/runtime/events/LanguageEventData.java
+++ b/cloudslang-runtime/src/main/java/io/cloudslang/lang/runtime/events/LanguageEventData.java
@@ -102,12 +102,20 @@ public class LanguageEventData extends HashMap<String, Serializable> {
         put(PATH, path);
     }
 
-    public Exception getException() {
-        return (Exception) get(EXCEPTION);
+    public String getResult() {
+        return (String) get(RESULT);
     }
 
-    public void setException(Exception ex) {
-        put(EXCEPTION, ex);
+    public void setResult(String result) {
+        put(RESULT, result);
+    }
+
+    public String getException() {
+        return (String) get(EXCEPTION);
+    }
+
+    public void setException(String exceptionMessage) {
+        put(EXCEPTION, exceptionMessage);
     }
 
     public Map<String, Serializable> getInputs() {
diff --git a/cloudslang-runtime/src/test/java/io/cloudslang/lang/runtime/events/LanguageEventDataTest.java b/cloudslang-runtime/src/test/java/io/cloudslang/lang/runtime/events/LanguageEventDataTest.java
index 864b3451a..5815b50f3 100644
--- a/cloudslang-runtime/src/test/java/io/cloudslang/lang/runtime/events/LanguageEventDataTest.java
+++ b/cloudslang-runtime/src/test/java/io/cloudslang/lang/runtime/events/LanguageEventDataTest.java
@@ -101,15 +101,27 @@ public class LanguageEventDataTest {
 		assertEquals(exePath, eventData.get(LanguageEventData.PATH));
 	}
 
+	/**
+	 * Test method for {@link LanguageEventData#getResult()}.
+	 */
+	@Test
+	public void testResult() {
+        String message = "Good";
+		eventData.setResult(message);
+		assertEquals(message, eventData.getResult());
+		assertEquals(message, eventData.get(LanguageEventData.RESULT));
+	}
+
 	/**
 	 * Test method for {@link LanguageEventData#getException()}.
 	 */
 	@Test
 	public void testException() {
-		Exception ex = new Exception("My exception");
-		eventData.setException(ex);
-		assertEquals(ex, eventData.getException());
-		assertEquals(ex, eventData.get(LanguageEventData.EXCEPTION));
+        String message = "My exception";
+        Exception ex = new Exception(message);
+		eventData.setException(ex.getMessage());
+		assertEquals(message, eventData.getException());
+		assertEquals(message, eventData.get(LanguageEventData.EXCEPTION));
 	}
 
 	/**
diff --git a/cloudslang-tests/src/main/java/io/cloudslang/lang/systemtests/TriggerFlows.java b/cloudslang-tests/src/main/java/io/cloudslang/lang/systemtests/TriggerFlows.java
index bc4ca6d7d..2d8e67cf6 100644
--- a/cloudslang-tests/src/main/java/io/cloudslang/lang/systemtests/TriggerFlows.java
+++ b/cloudslang-tests/src/main/java/io/cloudslang/lang/systemtests/TriggerFlows.java
@@ -59,7 +59,7 @@ public class TriggerFlows {
             ScoreEvent event = finishEvent.take();
             if (event.getEventType().equals(ScoreLangConstants.SLANG_EXECUTION_EXCEPTION)){
                 LanguageEventData languageEvent = (LanguageEventData) event.getData();
-                throw new RuntimeException((String) languageEvent.get(LanguageEventData.EXCEPTION));
+                throw new RuntimeException(languageEvent.getException());
             }
             slang.unSubscribeOnEvents(finishListener);
             return event;