/////////////////////////////////////////////////////////////////////////
//
// © University of Southampton IT Innovation Centre, 2008
//
// Copyright in this library belongs to the University of Southampton
// University Road, Highfield, Southampton, UK, SO17 1BJ
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//	Created By :			Mark McArdle
//	Created Date :			2008-02-28
//	Created for Project :		CRISP
//
/////////////////////////////////////////////////////////////////////////
//
//  Dependencies : none
//
/////////////////////////////////////////////////////////////////////////
//
//	Last commit info :  $Author: mm $
//                          $Date: 2008-05-19 17:19:44 +0100 (Mon, 19 May 2008) $
//                          $Revision: 9561 $
//
/////////////////////////////////////////////////////////////////////////

package uk.ac.soton.itinnovation.grid.client.tutorial;

import uk.ac.soton.itinnovation.grid.client.proxy.ProxyFactory;
import java.io.File;
import java.net.URL;
import javax.activation.DataHandler;
import uk.ac.soton.ecs.iam.grid.comms.client.DataConversation;
import uk.ac.soton.ecs.iam.grid.comms.client.JobConversation;
import uk.ac.soton.ecs.iam.grid.comms.client.RemoteJobService;
import uk.ac.soton.itinnovation.grid.service.types.JobStatus;
import uk.ac.soton.itinnovation.grid.service.types.jsdl.JobDescription;
import uk.ac.soton.itinnovation.grid.types.ConversationID;
import uk.ac.soton.itinnovation.grid.types.MatchPattern;
import uk.ac.soton.itinnovation.grid.types.PolicyRule;

public class JobOrchestration {
	/** Change this Variable to point to your job service!!! */
	private static String JOB_SERVICE_ENDPOINT1 = "https://....:8443/gria-basic-app-services/services/JobService";
	private static String JOB_SERVICE_ENDPOINT2 = "https://....:8443/gria-basic-app-services/services/JobService";

	/** The application to execute, identified by its URI */
	private static final String APPLICATION1 = "http://it-innovation.soton.ac.uk/grid/imagemagick/swirl";
	private static final String APPLICATION2 = "http://it-innovation.soton.ac.uk/grid/imagemagick/paint";

	/** The input file to upload to the job */
	private static final String INPUT_FILE = "input.png";

	/** The ouptut file to download the results to */
	private static final String OUTPUT_FILE = "output.png";

	public JobOrchestration(String jobservice1,String jobservice2){
		JOB_SERVICE_ENDPOINT1 = jobservice1;
		JOB_SERVICE_ENDPOINT2 = jobservice2;
	}

	/** Creates a new instance of JobOrchestration */
	public static void main(String[] args) throws Exception{
		
		/* Create a TutorialHelpers object and get a ProxyFactory
		 * object from it
		 */
		ProxyFactory proxyFactory = new TutorialHelpers().getFactory();
		
		/* Create a Proxy to the Job Service
		 */
		RemoteJobService jobService1 = proxyFactory.createProxy(ConversationID.getEPR(JOB_SERVICE_ENDPOINT1), RemoteJobService.class);

		/* Use the JobHelpers class to create a JSDL job description
		 * using the defaults for this type of job
		 */
		JobDescription jsdl = JobHelpers.getJobDescription("Job 1",jobService1.getApplicationMetadataDetailed(APPLICATION1));

		/* Make a remote call to the Job Service to create a job resource
		 * using the JSDL we have created
		 */
		JobConversation jobConv1 = jobService1.createJobJSDL(jsdl.toXML());
		
		/* Get Proxy to the inputs and outputs of the 
		 * job as DataConversation objectss.
		 */
		DataConversation[] inputs1 = jobConv1.getInputs();
		DataConversation[] outputs1 = jobConv1.getOutputs();

		/* Upload an input image to the input data stager
		 */
		URL url = JobOrchestration.class.getClassLoader().getResource(INPUT_FILE);
		inputs1[0].save(new DataHandler(url));

		/* Tell the Job Service to start the job
		 */
		jobConv1.submitJobJSDL();
		while(jobConv1.stillActive()) {
			Thread.sleep(5000);
		}

		/* Check to see if the job completed sucessfully
		 */
		JobStatus jobStatus = jobConv1.checkJob();
		if(jobStatus.getExitStatus() != 0) {
			// handle the failure
			throw new RuntimeException("Swirl job failed. Here is the log:\n" + jobStatus.getLogText());
		}

		/* Create another proxy to a different jobservice
		 */
		RemoteJobService jobService2 = proxyFactory.createProxy(ConversationID.getEPR(JOB_SERVICE_ENDPOINT2), RemoteJobService.class);

		/* Use the JobHelpers class to create a JSDL job description
		 * using the defaults for this type of job and follow the
		 * same process as before for job 1
		 */
		JobDescription jsdl2 = JobHelpers.getJobDescription("Job 2",jobService2.getApplicationMetadataDetailed(APPLICATION2));
		JobConversation jobConv2 = jobService2.createJobJSDL(jsdl2.toXML());
		DataConversation[] inputs2 = jobConv2.getInputs();
		DataConversation[] outputs2 = jobConv2.getOutputs();
		
		/* Add a rule on the output of job 1 allowing the 2nd job service 
		 * to read from the stager
		 */
		outputs1[0].addPolicyRule(new PolicyRule(new MatchPattern(jobService2.getServiceProviderID(),jobService2.getServiceProviderIssuer()),"reader"));
		
		/* Instruct the 2nd Job Service to copy the output of job 1 
		 * into the input of job 2
		 */
		inputs2[0].copyFrom(outputs1[0]);

		/* Tell the Job Service to start the job and monitor it
		 */
		jobConv2.submitJobJSDL();
		while(jobConv2.stillActive()) {
			Thread.sleep(5000);
		}
		JobStatus jobStatus2 = jobConv2.checkJob();
		if(jobStatus2.getExitStatus() != 0) {
			// handle the failure
			throw new RuntimeException("Job failed. Here is the log:\n" +jobStatus2.getLogText());
		}
		outputs2[0].read(new File(OUTPUT_FILE));

		/* Clean up the jobs at each service.
		 */
		jobConv1.destroy();
		jobConv2.destroy();
	}



}
