/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ambari.view.hive2.client; import akka.actor.ActorRef; import akka.actor.ActorSystem; import akka.actor.Inbox; import com.google.common.base.Optional; import org.apache.ambari.view.ViewContext; import org.apache.ambari.view.hive2.actor.message.Connect; import org.apache.ambari.view.hive2.actor.message.CursorReset; import org.apache.ambari.view.hive2.actor.message.ExecuteJob; import org.apache.ambari.view.hive2.actor.message.FetchError; import org.apache.ambari.view.hive2.actor.message.FetchResult; import org.apache.ambari.view.hive2.actor.message.ResetCursor; import org.apache.ambari.view.hive2.actor.message.ResultNotReady; import org.apache.ambari.view.hive2.actor.message.SQLStatementJob; import org.apache.ambari.view.hive2.actor.message.job.CancelJob; import org.apache.ambari.view.hive2.actor.message.job.Failure; import org.apache.ambari.view.hive2.actor.message.job.FetchFailed; import org.apache.ambari.view.hive2.internal.ConnectionException; import org.apache.ambari.view.hive2.resources.jobs.viewJobs.Job; import org.apache.ambari.view.hive2.utils.ResultFetchFormattedException; import org.apache.ambari.view.hive2.utils.ResultNotReadyFormattedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import scala.concurrent.duration.Duration; import java.sql.SQLException; import java.util.concurrent.TimeUnit; public class AsyncJobRunnerImpl implements AsyncJobRunner { private final Logger LOG = LoggerFactory.getLogger(getClass()); private final ActorRef controller; private final ActorSystem system; private final ViewContext context; public AsyncJobRunnerImpl(ViewContext context, ActorRef controller, ActorSystem system) { this.context = context; this.controller = controller; this.system = system; } @Override public void submitJob(ConnectionConfig config, SQLStatementJob job, Job jobp) { Connect connect = config.createConnectMessage(jobp.getId()); ExecuteJob executeJob = new ExecuteJob(connect, job); controller.tell(executeJob, ActorRef.noSender()); } @Override public void cancelJob(String jobId, String username) { controller.tell(new CancelJob(jobId, username), ActorRef.noSender()); } @Override public Optional<NonPersistentCursor> getCursor(String jobId, String username) { Inbox inbox = Inbox.create(system); inbox.send(controller, new FetchResult(jobId, username)); Object receive = inbox.receive(Duration.create(1, TimeUnit.MINUTES)); if(receive instanceof ResultNotReady) { String errorString = "Result not ready for job: " + jobId + ", username: " + username + ". Try after sometime."; LOG.info(errorString); throw new ResultNotReadyFormattedException(errorString, new Exception(errorString)); } else if(receive instanceof Failure) { Failure failure = (Failure) receive; throw new ResultFetchFormattedException(failure.getMessage(), failure.getError()); } else { Optional<ActorRef> iterator = (Optional<ActorRef>) receive; if(iterator.isPresent()) { return Optional.of(new NonPersistentCursor(context, system, iterator.get())); } else { return Optional.absent(); } } } @Override public Optional<NonPersistentCursor> resetAndGetCursor(String jobId, String username) { Inbox inbox = Inbox.create(system); inbox.send(controller, new FetchResult(jobId, username)); Object receive = inbox.receive(Duration.create(1, TimeUnit.MINUTES)); if(receive instanceof ResultNotReady) { String errorString = "Result not ready for job: " + jobId + ", username: " + username + ". Try after sometime."; LOG.info(errorString); throw new ResultNotReadyFormattedException(errorString, new Exception(errorString)); } else if(receive instanceof Failure) { Failure failure = (Failure) receive; throw new ResultFetchFormattedException(failure.getMessage(), failure.getError()); } else { Optional<ActorRef> iterator = (Optional<ActorRef>) receive; if(iterator.isPresent()) { inbox.send(iterator.get(), new ResetCursor()); Object resetResult = inbox.receive(Duration.create(1, TimeUnit.MINUTES)); if (resetResult instanceof CursorReset) { return Optional.of(new NonPersistentCursor(context, system, iterator.get())); } else { return Optional.absent(); } } else { return Optional.absent(); } } } @Override public Optional<Failure> getError(String jobId, String username) { Inbox inbox = Inbox.create(system); inbox.send(controller, new FetchError(jobId, username)); Object receive = inbox.receive(Duration.create(1, TimeUnit.MINUTES)); if(receive instanceof FetchFailed){ FetchFailed fetchFailed = (FetchFailed) receive; return Optional.of(new Failure(fetchFailed.getMessage(), getExceptionForRetry())); } Optional<Failure> result = (Optional<Failure>) receive; return result; } private ConnectionException getExceptionForRetry() { return new ConnectionException(new SQLException("Cannot connect"),"Connection attempt failed, Please retry"); } }