<commit_before>/**
 * (c) Copyright 2013 WibiData, Inc.
 *
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * 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 org.kiji.rest;

import java.io.IOException;
import java.util.List;
import java.util.Set;

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.common.collect.Sets;
import com.yammer.dropwizard.Service;
import com.yammer.dropwizard.config.Bootstrap;
import com.yammer.dropwizard.config.Environment;
import com.yammer.dropwizard.json.ObjectMapperFactory;

import org.kiji.rest.health.InstanceHealthCheck;
import org.kiji.rest.representations.KijiRestEntityId;
import org.kiji.rest.representations.SchemaOption;
import org.kiji.rest.resources.InstanceResource;
import org.kiji.rest.resources.InstancesResource;
import org.kiji.rest.resources.KijiRESTResource;
import org.kiji.rest.resources.RowsResource;
import org.kiji.rest.resources.TableResource;
import org.kiji.rest.resources.TablesResource;
import org.kiji.rest.serializers.AvroToJsonStringSerializer;
import org.kiji.rest.serializers.JsonToKijiRestEntityId;
import org.kiji.rest.serializers.JsonToSchemaOption;
import org.kiji.rest.serializers.KijiRestEntityIdToJson;
import org.kiji.rest.serializers.SchemaOptionToJson;
import org.kiji.rest.serializers.TableLayoutToJsonSerializer;
import org.kiji.rest.serializers.Utf8ToJsonSerializer;
import org.kiji.schema.Kiji;
import org.kiji.schema.KijiURI;

/**
 * Service to provide REST access to a list of Kiji instances.
 * The configuration is parametrized by a file that contains the cluster
 * address and the list of instances.
 */
public class KijiRESTService extends Service<KijiRESTConfiguration> {
  /**
   * Main method entry point into the KijiREST service.
   *
   * @param args The server token and the path to the YAML configuration file.
   * @throws Exception Prevents the REST service from starting.
   */
  public static void main(final String[] args) throws Exception {
    new KijiRESTService().run(args);
  }

  /** {@inheritDoc} */
  @Override
  public final void initialize(final Bootstrap<KijiRESTConfiguration> bootstrap) {
    bootstrap.setName("kiji-rest");
    registerSerializers(bootstrap.getObjectMapperFactory());
  }

  /**
   * Registers custom serializers with the Jackson ObjectMapper via DropWizard's
   * ObjectMapperFactory. This is used by both the service initialization and the test
   * setup method to ensure consistency between test and production.
   *
   * @param mapperFactory is the ObjectMapperFactory.
   */
  public static final void registerSerializers(ObjectMapperFactory mapperFactory) {
    // TODO: Add a module to convert btw Avro's specific types and JSON. The default
    // mapping seems to throw an exception.
    SimpleModule module = new SimpleModule("KijiRestModule", new Version(1, 0, 0, null,
        "org.kiji.rest", "avroToJson"));
    module.addSerializer(new AvroToJsonStringSerializer());
    module.addSerializer(new Utf8ToJsonSerializer());
    module.addSerializer(new TableLayoutToJsonSerializer());
    module.addSerializer(new SchemaOptionToJson());
    module.addDeserializer(SchemaOption.class, new JsonToSchemaOption());
    module.addSerializer(new KijiRestEntityIdToJson());
    module.addDeserializer(KijiRestEntityId.class, new JsonToKijiRestEntityId());
    mapperFactory.registerModule(module);
  }

  /**
   * {@inheritDoc}
   *
   * @throws IOException when instance in configuration can not be opened and closed.
   */
  @Override
  public final void run(final KijiRESTConfiguration configuration, final Environment environment)
      throws IOException {
    final List<String> instanceStrings = configuration.getInstances();

    final Set<KijiURI> instances = Sets.newHashSet();

    // Load health checks for the visible instances.
    final KijiURI clusterURI = KijiURI.newBuilder(configuration.getClusterURI()).build();
    for (String instance : instanceStrings) {
      final KijiURI instanceURI = KijiURI.newBuilder(clusterURI).withInstanceName(instance).build();
      // Check existence of instance by opening and closing.
      final Kiji kiji = Kiji.Factory.open(instanceURI);
      kiji.release();
      instances.add(instanceURI);
      environment.addHealthCheck(new InstanceHealthCheck(instanceURI));
    }

    ManagedKijiClient kijiClient = new ManagedKijiClient(instances);
    environment.manage(kijiClient);

    // Add exception mappers to print better exception messages to the client than what
    // Dropwizard does by default.
    environment.addProvider(new GeneralExceptionMapper());

    // Remove the in built Dropwizard LoggingExceptionHandler and use a custom one that logs
    // JSON and also ensures that it's logged to the log file.
    Set<Object> jerseySingletons = environment.getJerseyResourceConfig().getSingletons();
    Object oldLoggingHandler = null;

    for (Object o : jerseySingletons) {
      if (o.getClass().getName().contains("DropwizardResourceConfig")) {
        oldLoggingHandler = o;
      }
    }

    jerseySingletons.remove(oldLoggingHandler);

    // Load resources.
    environment.addResource(new KijiRESTResource());
    environment.addResource(new InstancesResource(kijiClient));
    environment.addResource(new InstanceResource(kijiClient));
    environment.addResource(new TableResource(kijiClient));
    environment.addResource(new TablesResource(kijiClient));
    environment.addResource(new RowsResource(kijiClient,
        environment.getObjectMapperFactory().build(),
        configuration.getFresheningConfiguration()));
  }
}
<commit_msg>REST-71. Override all Dropwizard exception mapping.<commit_after>/**
 * (c) Copyright 2013 WibiData, Inc.
 *
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * 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 org.kiji.rest;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.ws.rs.ext.ExceptionMapper;

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.common.collect.Sets;
import com.yammer.dropwizard.Service;
import com.yammer.dropwizard.config.Bootstrap;
import com.yammer.dropwizard.config.Environment;
import com.yammer.dropwizard.json.ObjectMapperFactory;

import org.kiji.rest.health.InstanceHealthCheck;
import org.kiji.rest.representations.KijiRestEntityId;
import org.kiji.rest.representations.SchemaOption;
import org.kiji.rest.resources.InstanceResource;
import org.kiji.rest.resources.InstancesResource;
import org.kiji.rest.resources.KijiRESTResource;
import org.kiji.rest.resources.RowsResource;
import org.kiji.rest.resources.TableResource;
import org.kiji.rest.resources.TablesResource;
import org.kiji.rest.serializers.AvroToJsonStringSerializer;
import org.kiji.rest.serializers.JsonToKijiRestEntityId;
import org.kiji.rest.serializers.JsonToSchemaOption;
import org.kiji.rest.serializers.KijiRestEntityIdToJson;
import org.kiji.rest.serializers.SchemaOptionToJson;
import org.kiji.rest.serializers.TableLayoutToJsonSerializer;
import org.kiji.rest.serializers.Utf8ToJsonSerializer;
import org.kiji.schema.Kiji;
import org.kiji.schema.KijiURI;

/**
 * Service to provide REST access to a list of Kiji instances.
 * The configuration is parametrized by a file that contains the cluster
 * address and the list of instances.
 */
public class KijiRESTService extends Service<KijiRESTConfiguration> {
  /**
   * Main method entry point into the KijiREST service.
   *
   * @param args The server token and the path to the YAML configuration file.
   * @throws Exception Prevents the REST service from starting.
   */
  public static void main(final String[] args) throws Exception {
    new KijiRESTService().run(args);
  }

  /** {@inheritDoc} */
  @Override
  public final void initialize(final Bootstrap<KijiRESTConfiguration> bootstrap) {
    bootstrap.setName("kiji-rest");
    registerSerializers(bootstrap.getObjectMapperFactory());
  }

  /**
   * Registers custom serializers with the Jackson ObjectMapper via DropWizard's
   * ObjectMapperFactory. This is used by both the service initialization and the test
   * setup method to ensure consistency between test and production.
   *
   * @param mapperFactory is the ObjectMapperFactory.
   */
  public static final void registerSerializers(ObjectMapperFactory mapperFactory) {
    // TODO: Add a module to convert btw Avro's specific types and JSON. The default
    // mapping seems to throw an exception.
    SimpleModule module = new SimpleModule("KijiRestModule", new Version(1, 0, 0, null,
        "org.kiji.rest", "avroToJson"));
    module.addSerializer(new AvroToJsonStringSerializer());
    module.addSerializer(new Utf8ToJsonSerializer());
    module.addSerializer(new TableLayoutToJsonSerializer());
    module.addSerializer(new SchemaOptionToJson());
    module.addDeserializer(SchemaOption.class, new JsonToSchemaOption());
    module.addSerializer(new KijiRestEntityIdToJson());
    module.addDeserializer(KijiRestEntityId.class, new JsonToKijiRestEntityId());
    mapperFactory.registerModule(module);
  }

  /**
   * {@inheritDoc}
   *
   * @throws IOException when instance in configuration can not be opened and closed.
   */
  @Override
  public final void run(final KijiRESTConfiguration configuration, final Environment environment)
      throws IOException {
    final List<String> instanceStrings = configuration.getInstances();

    final Set<KijiURI> instances = Sets.newHashSet();

    // Load health checks for the visible instances.
    final KijiURI clusterURI = KijiURI.newBuilder(configuration.getClusterURI()).build();
    for (String instance : instanceStrings) {
      final KijiURI instanceURI = KijiURI.newBuilder(clusterURI).withInstanceName(instance).build();
      // Check existence of instance by opening and closing.
      final Kiji kiji = Kiji.Factory.open(instanceURI);
      kiji.release();
      instances.add(instanceURI);
      environment.addHealthCheck(new InstanceHealthCheck(instanceURI));
    }

    ManagedKijiClient kijiClient = new ManagedKijiClient(instances);
    environment.manage(kijiClient);

    // Add exception mappers to print better exception messages to the client than what
    // Dropwizard does by default.
    environment.addProvider(new GeneralExceptionMapper());

    // Remove the in built Dropwizard LoggingExceptionHandler and use a custom one that logs
    // JSON and also ensures that it's logged to the log file.
    // Inspired by <NAME>'s suggestion on thoughtspark.org.
    Set<Object> jerseyResources = environment.getJerseyResourceConfig().getSingletons();
    Iterator<Object> jerseyResourcesIterator = jerseyResources.iterator();
    while (jerseyResourcesIterator.hasNext()) {
      Object jerseyResource = jerseyResourcesIterator.next();
      if (jerseyResource instanceof ExceptionMapper
          && jerseyResource.getClass().getName().startsWith("com.yammer.dropwizard.jersey")) {
        jerseyResourcesIterator.remove();
      }
    }

    // Load resources.
    environment.addResource(new KijiRESTResource());
    environment.addResource(new InstancesResource(kijiClient));
    environment.addResource(new InstanceResource(kijiClient));
    environment.addResource(new TableResource(kijiClient));
    environment.addResource(new TablesResource(kijiClient));
    environment.addResource(new RowsResource(kijiClient,
        environment.getObjectMapperFactory().build(),
        configuration.getFresheningConfiguration()));
  }
}

{'fraction_non_alphanumeric': 0.08931657501963865, 'fraction_numerical': 0.002199528672427337, 'mean_word_length': 4.5472766884531595, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3519704', 'n_tokens_mistral': 3513, 'n_tokens_neox': 3402, 'n_words': 965}