Package co.cask.cdap.internal.app.runtime.service

Source Code of co.cask.cdap.internal.app.runtime.service.InMemoryRunnableRunner

/*
* Copyright © 2014 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.service;

import co.cask.cdap.api.common.RuntimeArguments;
import co.cask.cdap.api.service.ServiceSpecification;
import co.cask.cdap.app.ApplicationSpecification;
import co.cask.cdap.app.metrics.ServiceRunnableMetrics;
import co.cask.cdap.app.program.Program;
import co.cask.cdap.app.runtime.ProgramController;
import co.cask.cdap.app.runtime.ProgramOptions;
import co.cask.cdap.app.runtime.ProgramRunner;
import co.cask.cdap.common.conf.CConfiguration;
import co.cask.cdap.common.election.InMemoryElectionRegistry;
import co.cask.cdap.common.lang.InstantiatorFactory;
import co.cask.cdap.common.lang.PropertyFieldSetter;
import co.cask.cdap.common.metrics.MetricsCollectionService;
import co.cask.cdap.data2.dataset2.DatasetFramework;
import co.cask.cdap.internal.app.runtime.MetricsFieldSetter;
import co.cask.cdap.internal.app.runtime.ProgramOptionConstants;
import co.cask.cdap.internal.app.services.HttpServiceTwillRunnable;
import co.cask.cdap.internal.app.services.ServiceWorkerTwillRunnable;
import co.cask.cdap.internal.lang.Reflections;
import co.cask.cdap.logging.context.UserServiceLoggingContext;
import co.cask.cdap.proto.ProgramType;
import co.cask.tephra.TransactionSystemClient;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.reflect.TypeToken;
import com.google.inject.Inject;
import org.apache.twill.api.RunId;
import org.apache.twill.api.RuntimeSpecification;
import org.apache.twill.api.TwillRunnable;
import org.apache.twill.common.Cancellable;
import org.apache.twill.discovery.Discoverable;
import org.apache.twill.discovery.DiscoveryService;
import org.apache.twill.discovery.DiscoveryServiceClient;
import org.apache.twill.internal.RunIds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
* Runs runnable-service in single-node
*/
public class InMemoryRunnableRunner implements ProgramRunner {

  private static final Logger LOG = LoggerFactory.getLogger(InMemoryRunnableRunner.class);

  private final MetricsCollectionService metricsCollectionService;
  private final DiscoveryService dsService;
  private final InMemoryElectionRegistry electionRegistry;
  private final ConcurrentLinkedQueue<Discoverable> discoverables;
  private final TransactionSystemClient transactionSystemClient;
  private final DatasetFramework datasetFramework;
  private final CConfiguration cConfiguration;
  private final DiscoveryServiceClient discoveryServiceClient;

  @Inject
  public InMemoryRunnableRunner(CConfiguration cConfiguration,
                                DiscoveryServiceClient discoveryServiceClient,
                                DiscoveryService dsService, InMemoryElectionRegistry electionRegistry,
                                MetricsCollectionService metricsCollectionService,
                                TransactionSystemClient transactionSystemClient, DatasetFramework datasetFramework) {
    this.metricsCollectionService = metricsCollectionService;
    this.discoveryServiceClient = discoveryServiceClient;
    this.dsService = dsService;
    this.electionRegistry = electionRegistry;
    this.discoverables = new ConcurrentLinkedQueue<Discoverable>();
    this.transactionSystemClient = transactionSystemClient;
    this.datasetFramework = datasetFramework;
    this.cConfiguration = cConfiguration;
  }

  @SuppressWarnings("unchecked")
  @Override
  public ProgramController run(final Program program, ProgramOptions options) {
    InMemoryTwillContext twillContext = null;
    try {
      // Extract and verify parameters
      String runnableName = options.getName();
      Preconditions.checkNotNull(runnableName, "Missing runnable name.");

      int instanceId = Integer.parseInt(options.getArguments().getOption(ProgramOptionConstants.INSTANCE_ID, "-1"));
      Preconditions.checkArgument(instanceId >= 0, "Missing instance Id");

      int instanceCount = Integer.parseInt(options.getArguments().getOption(ProgramOptionConstants.INSTANCES, "0"));
      Preconditions.checkArgument(instanceCount > 0, "Invalid or missing instance count");

      String runIdOption = options.getArguments().getOption(ProgramOptionConstants.RUN_ID);
      Preconditions.checkNotNull(runIdOption, "Missing runId");
      RunId runId = RunIds.fromString(runIdOption);

      ApplicationSpecification appSpec = program.getSpecification();
      Preconditions.checkNotNull(appSpec, "Missing application specification.");

      ProgramType processorType = program.getType();
      Preconditions.checkNotNull(processorType, "Missing processor type.");
      Preconditions.checkArgument(processorType == ProgramType.SERVICE, "Only Service process type is supported.");

      String processorName = program.getName();
      Preconditions.checkNotNull(processorName, "Missing processor name.");

      ServiceSpecification serviceSpec = appSpec.getServices().get(processorName);
      RuntimeSpecification runnableSpec = serviceSpec.getRunnables().get(runnableName);
      Preconditions.checkNotNull(runnableSpec, "RuntimeSpecification missing for Runnable \"%s\"", runnableName);

      Class<?> clz = null;

      String classStr = runnableSpec.getRunnableSpecification().getClassName();
      // special case for handling http service
      if (classStr.equals(HttpServiceTwillRunnable.class.getName())) {
        clz = HttpServiceTwillRunnable.class;
      } else {
        clz = Class.forName(runnableSpec.getRunnableSpecification().getClassName(),
                            true, program.getClassLoader());
      }

      Preconditions.checkArgument(TwillRunnable.class.isAssignableFrom(clz), "%s is not a TwillRunnable.", clz);

      Class<? extends TwillRunnable> runnableClass = (Class<? extends TwillRunnable>) clz;
      RunId twillRunId = RunIds.generate();
      final String[] argArray = RuntimeArguments.toPosixArray(options.getUserArguments());

      DiscoveryService dService = new DiscoveryService() {
        @Override
        public Cancellable register(final Discoverable discoverable) {
          discoverables.add(discoverable);
          return dsService.register(new Discoverable() {
            @Override
            public String getName() {
              return String.format("service.%s.%s.%s", program.getAccountId(),
                                   program.getApplicationId(), program.getName());
            }

            @Override
            public InetSocketAddress getSocketAddress() {
              return discoverable.getSocketAddress();
            }
          });
        }
      };

      twillContext = new InMemoryTwillContext(twillRunId, runId, InetAddress.getLocalHost(), new String[0], argArray,
                                              runnableSpec.getRunnableSpecification(), instanceId,
                                              runnableSpec.getResourceSpecification().getVirtualCores(),
                                              runnableSpec.getResourceSpecification().getMemorySize(),
                                              discoveryServiceClient, dService, instanceCount, electionRegistry);

      TypeToken<? extends  TwillRunnable> runnableType = TypeToken.of(runnableClass);
      TwillRunnable runnable = null;

      if (runnableClass.isAssignableFrom(HttpServiceTwillRunnable.class)) {
        // Special case for running HTTP services
        runnable = new HttpServiceTwillRunnable(program, runId, cConfiguration, runnableName, metricsCollectionService,
                                                discoveryServiceClient, datasetFramework,
                                                transactionSystemClient);
      } else if (runnableClass.isAssignableFrom(ServiceWorkerTwillRunnable.class)) {
        runnable = new ServiceWorkerTwillRunnable(program, runId, runnableName, program.getClassLoader(),
                                                  cConfiguration, metricsCollectionService, datasetFramework,
                                                  transactionSystemClient, discoveryServiceClient);
      } else {
        runnable = new InstantiatorFactory(false).get(runnableType).create();
      }

      InMemoryRunnableDriver driver = new
        InMemoryRunnableDriver(runnable, twillContext, new UserServiceLoggingContext(program.getAccountId(),
                                                                                     program.getApplicationId(),
                                                                                     processorName,
                                                                                     runnableName));

      //Injecting Metrics
      Reflections.visit(runnable, runnableType,
                        new MetricsFieldSetter(new ServiceRunnableMetrics(metricsCollectionService,
                                                                          program.getApplicationId(),
                                                                          serviceSpec.getName(), runnableName,
                                                                          twillContext.getInstanceId())),
                        new PropertyFieldSetter(runnableSpec.getRunnableSpecification().getConfigs()));

      ProgramController controller = new InMemoryRunnableProgramController(program.getName(), runnableName,
                                                                           twillContext, driver,
                                                                           discoverables);

      LOG.info("Starting Runnable: {}", runnableName);
      driver.start();
      LOG.info("Runnable started: {}", runnableName);

      return controller;
    } catch (Exception e) {
      throw Throwables.propagate(e);
    }
  }
}
TOP

Related Classes of co.cask.cdap.internal.app.runtime.service.InMemoryRunnableRunner

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.