/* * Copyright © 2016 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.app.runtime.spark; import co.cask.cdap.api.app.ApplicationSpecification; import co.cask.cdap.common.app.RunIds; import co.cask.cdap.common.conf.Constants; import co.cask.cdap.internal.app.ApplicationSpecificationAdapter; import co.cask.cdap.internal.app.runtime.workflow.WorkflowProgramInfo; import co.cask.cdap.proto.id.ProgramId; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import org.apache.hadoop.conf.Configuration; import org.apache.twill.api.RunId; import java.io.File; import java.lang.reflect.Type; import java.util.Map; import java.util.Set; import javax.annotation.Nullable; /** * Helper class for getting and setting configurations that are needed for recreating the runtime context * in each Spark executor. */ public class SparkRuntimeContextConfig { private static final Gson GSON = ApplicationSpecificationAdapter.addTypeAdapters(new GsonBuilder()).create(); private static final Type ARGS_TYPE = new TypeToken<Map<String, String>>() { }.getType(); /** * Configuration key for boolean value to tell whether Spark program is executed on a cluster or not. */ public static final String HCONF_ATTR_CLUSTER_MODE = "cdap.spark.cluster.mode"; private static final String HCONF_ATTR_APP_SPEC = "cdap.spark.app.spec"; private static final String HCONF_ATTR_PROGRAM_ID = "cdap.spark.program.id"; private static final String HCONF_ATTR_RUN_ID = "cdap.spark.run.id"; private static final String HCONF_ATTR_ARGS = "cdap.spark.program.args"; private static final String HCONF_ATTR_WORKFLOW_INFO = "cdap.spark.program.workflow.info"; private static final String HCONF_ATTR_LOCAL_RESOURCES = "cdap.spark.local.resources"; private final Configuration hConf; /** * Returns {@code true} if running in local mode. */ static boolean isLocal(Configuration hConf) { return !hConf.getBoolean(HCONF_ATTR_CLUSTER_MODE, false); } /** * Creates a new instance from the given configuration. */ SparkRuntimeContextConfig(Configuration hConf) { this.hConf = hConf; } /** * Returns the configuration. */ public Configuration getConfiguration() { return hConf; } /** * Returns true if in local mode. */ public boolean isLocal() { return isLocal(hConf); } /** * Sets configurations based on the given context. */ public SparkRuntimeContextConfig set(SparkRuntimeContext context, Set<String> localizeResourceNames, @Nullable File pluginArchive) { setApplicationSpecification(context.getApplicationSpecification()); setProgramId(context.getProgram().getId().toEntityId()); setRunId(context.getRunId().getId()); setArguments(context.getRuntimeArguments()); setWorkflowProgramInfo(context.getWorkflowInfo()); setLocalizedResourceNames(localizeResourceNames); setPluginArchive(pluginArchive); return this; } /** * @return the {@link ApplicationSpecification} stored in the configuration. */ public ApplicationSpecification getApplicationSpecification() { return GSON.fromJson(hConf.get(HCONF_ATTR_APP_SPEC), ApplicationSpecification.class); } /** * @return the {@link ProgramId} stored in the configuration. */ public ProgramId getProgramId() { return GSON.fromJson(hConf.get(HCONF_ATTR_PROGRAM_ID), ProgramId.class); } /** * @return the {@link RunId} stored in the configuration. */ public RunId getRunId() { return RunIds.fromString(hConf.get(HCONF_ATTR_RUN_ID)); } /** * @return the runtime arguments stored in the configuration. */ public Map<String, String> getArguments() { return GSON.fromJson(hConf.get(HCONF_ATTR_ARGS), ARGS_TYPE); } /** * @return the {@link WorkflowProgramInfo} if it is running inside Workflow or {@code null} if not. */ @Nullable public WorkflowProgramInfo getWorkflowProgramInfo() { String info = hConf.get(HCONF_ATTR_WORKFLOW_INFO); if (info == null) { return null; } WorkflowProgramInfo workflowProgramInfo = GSON.fromJson(info, WorkflowProgramInfo.class); return workflowProgramInfo; } /** * @return the set of localized resource names stored in the configuration. */ public Set<String> getLocalizedResourceNames() { return GSON.fromJson(hConf.get(HCONF_ATTR_LOCAL_RESOURCES), new TypeToken<Set<String>>() { }.getType()); } /** * @return the name of the plugin archive file stored in the configuration. */ @Nullable public String getPluginArchive() { return hConf.get(Constants.Plugin.ARCHIVE); } /** * Serialize the {@link ApplicationSpecification} to the configuration. */ private void setApplicationSpecification(ApplicationSpecification spec) { hConf.set(HCONF_ATTR_APP_SPEC, GSON.toJson(spec, ApplicationSpecification.class)); } /** * Serialize the {@link ProgramId} to the configuration. */ private void setProgramId(ProgramId programId) { hConf.set(HCONF_ATTR_PROGRAM_ID, GSON.toJson(programId)); } /** * Serialize the {@link RunId} to the configuration. */ private void setRunId(String runId) { hConf.set(HCONF_ATTR_RUN_ID, runId); } /** * Serialize the runtime arguments to the configuration. */ private void setArguments(Map<String, String> runtimeArgs) { hConf.set(HCONF_ATTR_ARGS, GSON.toJson(runtimeArgs, ARGS_TYPE)); } /** * Serialize the {@link WorkflowProgramInfo} to the configuration if available. */ private void setWorkflowProgramInfo(@Nullable WorkflowProgramInfo info) { if (info != null) { hConf.set(HCONF_ATTR_WORKFLOW_INFO, GSON.toJson(info)); } } /** * Serialize the set of localize resource names to the configuration. */ private void setLocalizedResourceNames(Set<String> names) { hConf.set(HCONF_ATTR_LOCAL_RESOURCES, GSON.toJson(names)); } /** * Saves the plugin archive file name to the configuration. */ private void setPluginArchive(@Nullable File pluginArchive) { if (pluginArchive != null) { hConf.set(Constants.Plugin.ARCHIVE, pluginArchive.getName()); } } }