/*
* Copyright © 2015 Cask Data, Inc.
*
* Licensed 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 co.cask.cdap.internal.app.runtime.batch.dataset.output;
import com.google.common.collect.ImmutableMap;
import org.apache.hadoop.mapreduce.JobContext;
import org.apache.hadoop.mapreduce.JobStatus;
import org.apache.hadoop.mapreduce.OutputCommitter;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import java.io.IOException;
import java.util.Map;
/**
* OutputCommitter that delegates to a collection of other OutputFormatCommitters.
*/
public class MultipleOutputsCommitter extends OutputCommitter {
private final Map<String, OutputCommitter> committers;
public MultipleOutputsCommitter(Map<String, OutputCommitter> committers) {
this.committers = ImmutableMap.copyOf(committers);
}
@Override
public void setupJob(JobContext jobContext) throws IOException {
for (Map.Entry<String, OutputCommitter> committer : committers.entrySet()) {
JobContext namedJobContext = MultipleOutputs.getNamedJobContext(jobContext, committer.getKey());
committer.getValue().setupJob(namedJobContext);
}
}
@Override
public void setupTask(TaskAttemptContext taskContext) throws IOException {
for (Map.Entry<String, OutputCommitter> committer : committers.entrySet()) {
TaskAttemptContext namedTaskContext = MultipleOutputs.getNamedTaskContext(taskContext, committer.getKey());
committer.getValue().setupTask(namedTaskContext);
}
}
@Override
public boolean needsTaskCommit(TaskAttemptContext taskContext) throws IOException {
// needs task commit if any delegates need task commit
for (Map.Entry<String, OutputCommitter> committer : committers.entrySet()) {
TaskAttemptContext namedTaskContext = MultipleOutputs.getNamedTaskContext(taskContext, committer.getKey());
if (committer.getValue().needsTaskCommit(namedTaskContext)) {
return true;
}
}
return false;
}
@Override
public void commitTask(TaskAttemptContext taskContext) throws IOException {
for (Map.Entry<String, OutputCommitter> committer : committers.entrySet()) {
TaskAttemptContext namedTaskContext = MultipleOutputs.getNamedTaskContext(taskContext, committer.getKey());
if (committer.getValue().needsTaskCommit(namedTaskContext)) {
committer.getValue().commitTask(namedTaskContext);
}
}
}
@Override
public void abortTask(TaskAttemptContext taskContext) throws IOException {
for (Map.Entry<String, OutputCommitter> committer : committers.entrySet()) {
TaskAttemptContext namedTaskContext = MultipleOutputs.getNamedTaskContext(taskContext, committer.getKey());
committer.getValue().abortTask(namedTaskContext);
}
}
@Override
public void commitJob(JobContext jobContext) throws IOException {
for (Map.Entry<String, OutputCommitter> committer : committers.entrySet()) {
JobContext namedJobContext = MultipleOutputs.getNamedJobContext(jobContext, committer.getKey());
committer.getValue().commitJob(namedJobContext);
}
}
@Override
public void abortJob(JobContext jobContext, JobStatus.State state) throws IOException {
for (Map.Entry<String, OutputCommitter> committer : committers.entrySet()) {
JobContext namedJobContext = MultipleOutputs.getNamedJobContext(jobContext, committer.getKey());
committer.getValue().abortJob(namedJobContext, state);
}
}
@Override
public boolean isRecoverySupported() {
// recovery is supported if it is supported on all delegates
for (OutputCommitter committer : committers.values()) {
if (!committer.isRecoverySupported()) {
return false;
}
}
return true;
}
@Override
public void recoverTask(TaskAttemptContext taskContext) throws IOException {
for (Map.Entry<String, OutputCommitter> committer : committers.entrySet()) {
TaskAttemptContext namedTaskContext = MultipleOutputs.getNamedTaskContext(taskContext, committer.getKey());
committer.getValue().recoverTask(namedTaskContext);
}
}
}