«1. Обзор

Dropwizard — это среда Java с открытым исходным кодом, используемая для быстрой разработки высокопроизводительных веб-сервисов RESTful. Он собирает некоторые популярные библиотеки для создания облегченного пакета. Основными библиотеками, которые он использует, являются Jetty, Jersey, Jackson, JUnit и Guava. Кроме того, он использует собственную библиотеку под названием Metrics.

В этом руководстве мы узнаем, как настроить и запустить простое приложение Dropwizard. Когда мы закончим, наше приложение предоставит RESTful API, который позволит нам получить список сохраненных брендов.

2. Зависимости Maven

Во-первых, зависимость dropwizard-core — это все, что нам нужно для создания нашего сервиса. Давайте добавим его в наш pom.xml:

<dependency>
    <groupId>io.dropwizard</groupId>
    <artifactId>dropwizard-core</artifactId>
    <version>2.0.0</version>
</dependency>

3. Конфигурация

Теперь мы создадим необходимые классы, необходимые для запуска каждого приложения Dropwizard.

Приложения Dropwizard хранят свойства в файлах YML. Поэтому мы создадим файл Introduction-config.yml в каталоге ресурсов:

defaultSize: 5

Мы можем получить доступ к значениям в этом файле, создав класс, расширяющий io.dropwizard.Configuration:

public class BasicConfiguration extends Configuration {
    @NotNull private final int defaultSize;

    @JsonCreator
    public BasicConfiguration(@JsonProperty("defaultSize") int defaultSize) {
        this.defaultSize = defaultSize;
    }

    public int getDefaultSize() {
        return defaultSize;
    }
}

Dropwizard использует Джексона для десериализации файла конфигурации в наш класс. Следовательно, мы использовали аннотации Джексона.

Далее создадим основной класс приложения, который отвечает за подготовку нашего сервиса к использованию:

public class IntroductionApplication extends Application<BasicConfiguration> {

    public static void main(String[] args) throws Exception {
        new IntroductionApplication().run("server", "introduction-config.yml");
    }

    @Override
    public void run(BasicConfiguration basicConfiguration, Environment environment) {
        //register classes
    }

    @Override
    public void initialize(Bootstrap<BasicConfiguration> bootstrap) {
        bootstrap.setConfigurationSourceProvider(new ResourceConfigurationSourceProvider());
        super.initialize(bootstrap);
    }
}

Во-первых, основной метод отвечает за запуск приложения. Мы можем либо передать аргументы методу run, либо заполнить его самостоятельно.

Первым аргументом может быть либо сервер, либо проверка. Опция проверки проверяет конфигурацию, а опция сервера запускает приложение. Второй аргумент — это расположение файла конфигурации.

Кроме того, метод initialize устанавливает поставщика конфигурации в ResourceConfigurationSourceProvider, что позволяет приложению найти заданный файл конфигурации в каталоге ресурсов. Этот метод не обязательно переопределять.

Наконец, метод run позволяет нам получить доступ как к Environment, так и к BaseConfiguration, которые мы будем использовать позже в этой статье.

4. Ресурс

Во-первых, давайте создадим доменный класс для нашего бренда:

public class Brand {
    private final Long id;
    private final String name;

    // all args constructor and getters
}

Во-вторых, давайте создадим класс BrandRepository, который будет отвечать за возврат брендов:

public class BrandRepository {
    private final List<Brand> brands;

    public BrandRepository(List<Brand> brands) {
        this.brands = ImmutableList.copyOf(brands);
    }

    public List<Brand> findAll(int size) {
        return brands.stream()
          .limit(size)
          .collect(Collectors.toList());
    }

    public Optional<Brand> findById(Long id) {
        return brands.stream()
          .filter(brand -> brand.getId().equals(id))
          .findFirst();
    }
}

Кроме того, мы смогли использовать ImmutableList из Guava, потому что это часть самого Dropwizard.

В-третьих, мы создадим класс BrandResource. Dropwizard по умолчанию использует JAX-RS с Джерси в качестве реализации. Поэтому мы воспользуемся аннотациями из этой спецификации, чтобы показать конечные точки нашего REST API:

@Path("/brands")
@Produces(MediaType.APPLICATION_JSON)
public class BrandResource {
    private final int defaultSize;
    private final BrandRepository brandRepository;

    public BrandResource(int defaultSize, BrandRepository brandRepository) {
        this.defaultSize = defaultSize;
        this.brandRepository = brandRepository;
    }

    @GET
    public List<Brand> getBrands(@QueryParam("size") Optional<Integer> size) {
        return brandRepository.findAll(size.orElse(defaultSize));
    }

    @GET
    @Path("/{id}")
    public Brand getById(@PathParam("id") Long id) {
        return brandRepository
          .findById(id)
          .orElseThrow(RuntimeException::new);
    }
}

Кроме того, мы определили размер как необязательный, чтобы использовать defaultSize из нашей конфигурации, если аргумент не указан.

Наконец, мы зарегистрируем BrandResource в классе IntroductionApplicaton. Для этого реализуем метод run:

@Override
public void run(BasicConfiguration basicConfiguration, Environment environment) {
    int defaultSize = basicConfiguration.getDefaultSize();
    BrandRepository brandRepository = new BrandRepository(initBrands());
    BrandResource brandResource = new BrandResource(defaultSize, brandRepository);

    environment
      .jersey()
      .register(brandResource);
}

Все созданные ресурсы должны быть зарегистрированы в этом методе.

5. Запуск приложения

В этом разделе мы узнаем, как запустить приложение из командной строки.

Сначала мы настроим наш проект для создания JAR-файла с помощью плагина maven-shade:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <configuration>
        <createDependencyReducedPom>true</createDependencyReducedPom>
        <filters>
            <filter>
                <artifact>*:*</artifact>
                <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                </excludes>
            </filter>
        </filters>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer
                      implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>com.baeldung.dropwizard.introduction.IntroductionApplication</mainClass>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

Это рекомендуемая конфигурация плагина. Кроме того, мы включили путь к нашему основному классу в элемент \u003cmainClass\u003e.

Наконец, мы создадим приложение с помощью Maven. Получив JAR-файл, мы можем запустить приложение:

java -jar target/dropwizard-0.0.1-SNAPSHOT.jar

Нет необходимости передавать параметры, поскольку мы уже включили их в класс IntroductionApplication.

После этого журнал консоли должен заканчиваться:

INFO  [2020-01-08 18:55:06,527] org.eclipse.jetty.server.Server: Started @1672ms

Теперь приложение прослушивает порт 8080, и мы можем получить доступ к конечной точке нашего бренда по адресу http://localhost:8080/brands.

6. Проверка работоспособности

При запуске приложения нам сообщили, что приложение не имеет проверки работоспособности. К счастью, Dropwizard предоставляет простое решение для добавления проверок работоспособности в наше приложение.

Начнем с добавления простого класса, расширяющего com.codahale.metrics.health.HealthCheck:

public class ApplicationHealthCheck extends HealthCheck {
    @Override
    protected Result check() throws Exception {
        return Result.healthy();
    }
}

«

«Этот простой метод вернет информацию о работоспособности нашего компонента. Мы могли бы создать несколько проверок работоспособности, и некоторые из них могли бы дать сбой в определенных ситуациях. Например, мы бы вернули Result.unhealthy(), если соединение с базой данных не удалось.

environment
  .healthChecks()
  .register("application", new ApplicationHealthCheck());

Наконец, нам нужно зарегистрировать нашу проверку работоспособности в методе run нашего класса IntroductionApplication:

{
  "application": {
    "healthy": true,
    "duration": 0
  },
  "deadlocks": {
    "healthy": true,
    "duration": 0
  }
}

После запуска приложения мы можем проверить ответ проверки работоспособности по адресу http://localhost:8081/healthcheck:

Как мы видим, наша проверка работоспособности была зарегистрирована под тегом приложения.

7. Заключение

В этой статье мы узнали, как настроить приложение Dropwizard с помощью Maven.

Мы обнаружили, что базовая установка приложения очень проста и быстра. Кроме того, Dropwizard включает в себя все библиотеки, необходимые для запуска высокопроизводительного веб-сервиса RESTful.