[2.7.0] Added Spark in Workflow: CDAP-465

Jira Issue : CDAP-465

- Adds Spark as a part of workflow
- Refactored Workflow to be generic to Programs
- Added Spark in unit tests for workflow.

Summary
---------------

1. WorkflowProgramRunner gets ProgramRunnerFactory instead of MapReduceProgramRunner and passes it to WorkflowDriver. This allows the WorkflowDriver to create the required type of ProgramRunner for the Program in the Workflow.

2. The workflow context now has a method getProgramRunner rather than getMapReduceRunner which returns Callable<RuntimeContext> which allows it to work with MapReduce and Spark. 

3. MapReduceWorkflowAction is not ProgramWorkflowAction which is common between the programs as the action remains the same irrespective of the Program. All it does is call the Callable which has the appropriate ProgramRunner for the program.

4. The ProgramWorkflowAction now takes ProgramType which it stores in the properties of the WorkflowActionSpecification. This is needed to know the type of the program to create the appropriate program runner for the program. 

5. I have added a enum of supported programs in WorkflowSupportedProgram. This was needed as SparkSpecification is in cdap-api and we cannot use TypeId or ProgramType there.

6. Now we have a ProgramWorkflowRunner interface for which we have two concrete implementation MapReduceProgramWorkflowRunner and SparkProgramWorkflowRunner. The common code between these are in AbstractProgramWorkflowRunner which can be used by any program. These two need to be different as the program have their own Specification.

7. ProgramWorkflowRunnerFactory is based on Factory pattern and it provides a single point to determine the appropriate ProgramWorkflowRunner instance to be created for the program type from the action spec.

8. WorkflowSparkProgram and WorkflowMapReduceProgram are forwarding program to make an appropriate program from workflow programs in spec. The common code is in AbstractWorkflowProgram. 

I have tried to refactor workflow to make it generic to all programs. As now it can create any program runner from the ProgramRunnerFactory and can run any program which implement ProgramRunner and whose context has a RuntimeContext as the Callable is ties to that. For example it  should be simple to add Service/Flow in workflow.

@anew : Please review and provide your feedback and suggestions. Thanks.
what happens when you pass null into the executeProgram() method? Is that well-behaved? If I understand correctly then this is expected to be always a MapReduceProgramController. So perhaps throw an exception with a meaningful message instead of returning null?