Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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.



Apache Druid is a high performance analytics data store for event-driven data. More information about Druid
can be found on https://druid.apache.org.

Documentation
-------------
You can find the documentation for {THIS_OR_THE_LATEST} Druid release on the project website https://druid.apache.org/docs/{DRUIDVERSION}/.

You can get started with Druid with our quickstart at https://druid.apache.org/docs/{DRUIDVERSION}/tutorials/quickstart.html.


Build from Source
-----------------
You can build Apache Druid directly from source.

Prerequisites:
  JDK 8, 8u92+
  Maven version 3.x


The basic command to build Druid from source is:

    mvn clean install


This will run static analysis, unit tests, compile classes, and package the projects into JARs. It will not generate the
source or binary distribution tarball.

In addition to the basic stages, you may also want to add the following profiles and properties:

  -Pdist           - Distribution profile: Generates the binary distribution tarball by pulling in core extensions and
                     dependencies and packaging the files as 'distribution/target/apache-druid-x.x.x-bin.tar.gz'
  -Papache-release - Apache release profile: Generates GPG signature and checksums, and builds the source distribution
                     tarball as `distribution/target/apache-druid-x.x.x-src.tar.gz`
  -Prat            - Apache Rat profile: Runs the Apache Rat license audit tool
  -DskipTests      - Skips unit tests (which reduces build time)

Putting these together, if you wish to build the source and binary distributions with signatures and checksums, audit
licenses, and skip the unit tests, you would run:

    mvn clean install -Papache-release,dist,rat -DskipTests


Community
---------
Community support is available on the druid-user mailing list druid-user@googlegroups.com also available at
https://groups.google.com/forum/#!forum/druid-user.

Development discussions occur on dev@druid.apache.org (archive available at
https://lists.apache.org/list.html?dev@druid.apache.org), which you can subscribe to by emailing
dev-subscribe@druid.apache.org.


Contributing
------------
If you find any bugs, please file a GitHub issue at https://github.com/apache/druid/issues.

If you wish to contribute, please follow the guidelines listed at https://druid.apache.org/community/.
