diff --git a/.ahoy.yml b/.ahoy.yml new file mode 100644 index 0000000..5829cd8 --- /dev/null +++ b/.ahoy.yml @@ -0,0 +1,201 @@ +--- +ahoyapi: v2 + +commands: + build: + usage: Build or rebuild project. + cmd: | + ahoy clean \ + && if [ "$COMPOSER" != "composer.json" ]; then ahoy composer-merge; fi \ + && if [ "$COMPOSER" != "composer.json" ]; then ahoy link-package; fi \ + && (docker network prune -f > /dev/null && docker network inspect amazeeio-network > /dev/null || docker network create amazeeio-network) \ + && ahoy up -- --build --force-recreate \ + && ahoy install-dev \ + && if [ "$COMPOSER" != "composer.json" ] && [ "$DRUPAL_PROFILE" ]; then ahoy init-profile; fi \ + && ahoy install-site \ + && if [ "$COMPOSER" != "composer.json" ]; then ahoy init-module; fi \ + && if [ "$COMPOSER" != "composer.json" ]; then ahoy drush pm-enable tide_test -y; fi \ + && ahoy line "Build complete" \ + && ahoy info 1 + + info: + usage: Print information about this project. + cmd: | + ahoy line "Site URL : " ${LOCALDEV_URL}:${LOCAL_PORT:-80}/ + ahoy line "Path to project : " ${APP} + ahoy line "Path to docroot : " ${APP}/${WEBROOT} + ahoy line "DB port on host : " $(docker port $(docker-compose ps -q mariadb) 3306 | cut -d : -f 2) + ahoy line "Mailhog URL : " http://mailhog.docker.internal:${LOCAL_PORT:-80}/ + if [ "$1" ]; then + ahoy line "One-time login : " $(ahoy login -- --no-browser) + fi + + up: + usage: Build and start Docker containers. + cmd: | + docker-compose up -d "$@" \ + && ahoy cli "dockerize -wait tcp://mariadb:3306 -timeout 1m" \ + && if docker-compose logs | grep -q "\[Error\]"; then docker-compose logs; exit 1; fi \ + && docker ps -a --filter name=^/${COMPOSE_PROJECT_NAME}_ && + # Add Bay SSH key before fetching DB. + # During local development, pygmy injects SSH key from the host, so specifying + # key as $BAY_KEY environment variable is not required (the host key of every + # developer must be added to Bay during project onboarding). + if [ "$BAY_KEY" ]; then + ahoy cli "mkdir -p /home/.ssh && echo -e \"$BAY_KEY\" > /home/.ssh/key && chmod 600 /home/.ssh/key;" + fi + + down: + usage: Stop Docker containers and remove container, images, volumes and networks. + cmd: docker-compose down --volumes + + start: + usage: Start existing Docker containers. + cmd: docker-compose start "$@" + + stop: + usage: Stop running Docker containers. + cmd: docker-compose stop "$@" + + restart: + usage: Restart all stopped and running Docker containers. + cmd: docker-compose restart + + logs: + usage: Show Docker logs. + cmd: docker-compose logs "$@" + + pull: + usage: Pull latest docker images. + cmd: | + docker image ls --format \"{{.Repository}}:{{.Tag}}\" | grep singledigital/ | grep -v none | xargs -n1 docker pull | cat \ + && docker image ls --format \"{{.Repository}}:{{.Tag}}\" | grep amazeeio/ | grep -v none | xargs -n1 docker pull | cat + + cli: + usage: Start a shell inside CLI container or run a command. + cmd: if \[ "$@" \]; then docker exec -i $(docker-compose ps -q cli) bash -c "$@"; else docker exec -it $(docker-compose ps -q cli) bash; fi + + drush: + usage: Run drush commands in the CLI service container. + cmd: docker exec -i $(docker-compose ps -q cli) drush -r ${APP}/${WEBROOT} -l ${LOCALDEV_URL} "$@" + + login: + usage: Login to a website. + cmd: ahoy drush user:unblock -q "$(ahoy drush user:information --uid=1 --fields=name --format=string)" 2>/dev/null && ahoy drush user:login --no-browser + + doctor: + usage: Find problems with current project setup. + cmd: scripts/doctor.sh + + # @note: Call this on the host before starting containers. + composer-merge: + usage: Merge composer files. + cmd: scripts/composer-merge.sh + + install-dev: + usage: Install dependencies. + cmd: ahoy cli "composer install -n --ansi --prefer-dist --no-suggest" + + install-site: + usage: Install site. + cmd: | + ahoy flush-redis + if [ "$INSTALL_NEW_SITE" == "1" ]; then + ahoy cli -- ./scripts/drupal/install-new-site.sh + else + ahoy cli -- ./scripts/rebuild-env.sh + fi + + db-import: + usage: Import the production database. + cmd: ahoy cli -- ./scripts/rebuild-env.sh + + fix-bay-token: + usage: Fix the bay token by re-importing. + cmd: | + pygmy stop \ + && sleep 1 \ + && pygmy start \ + && docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs docker rm \ + && docker-compose up -d --force \ + && pygmy stop \ + && sleep 1 \ + && pygmy start + + link-package: + usage: Link package from current repository root. + cmd: scripts/link-package.sh + hide: true + + init-module: + usage: Install a module from current repository root. + cmd: ahoy cli "INSTALL_SUGGEST=$INSTALL_SUGGEST scripts/drupal-init-module.sh" + hide: true + + init-profile: + usage: Install a profile from current repository root. + cmd: ahoy cli "INSTALL_SUGGEST=$INSTALL_SUGGEST scripts/drupal-init-profile.sh" + hide: true + + clean: + usage: Remove all build files. + cmd: | + ahoy down \ + && ([ -d .git ] && git ls-files --directory --other -i --exclude-from=.gitignore ${WEBROOT} | grep -v "settings.local.php" | grep -v "services.local.yml" | xargs chmod -Rf 777 || true) \ + && ([ -d .git ] && git ls-files --directory --other -i --exclude-from=.gitignore ${WEBROOT} | grep -v "settings.local.php" | grep -v "services.local.yml" | xargs rm -Rf || true) \ + && rm -Rf vendor \ + && rm -Rf screenshots \ + && rm -Rf composer.build.* + + clean-full: + usage: Remove all development files. + cmd: | + ahoy clean \ + && ([ -d .git ] && git ls-files --directory --other . | grep -v ".idea" | xargs chmod -Rf 777 || true) \ + && ([ -d .git ] && git ls-files --directory --other . | grep -v ".idea" | xargs rm -Rf || true) + + deploy: + usage: Deploy or re-deploy a branch in Bay. + cmd: ./scripts/bay-deploy.sh "$@" + + lint: + usage: Lint code. + cmd: ahoy cli "vendor/bin/phpcs ${PHPCS_TARGETS}" + + test-behat: + usage: Run Behat tests. + cmd: ahoy cli "./vendor/bin/behat --strict --colors ${BEHAT_PROFILE} $@" + + flush-redis: + usage: Flush Redis cache. + cmd: docker exec -i $(docker-compose ps -q redis) redis-cli flushall > /dev/null + + set-dev-tools-commit: + usage: Specify a commit of Dev-Tools to downloaded and commit the result. + cmd: sed -i '' 's/.*GH_COMMIT.*/'"export GH_COMMIT=$1"'/' dev-tools.sh + + # Utilities. + line: + cmd: printf "$(tput -Txterm setaf 2)${1}$(tput -Txterm sgr0)${2}\n" + hide: true + +entrypoint: +- bash +- "-c" +- | + [ -f .env ] && export $(grep -v '^#' .env | xargs) && [ -f .env.local ] && export $(grep -v '^#' .env.local | xargs) + export PROJECT_NAME=${PROJECT_NAME:-$(basename $(pwd))} + export APP=${APP:-/app} + export WEBROOT=${WEBROOT:-docroot} + export MYSQL_HOST=${MYSQL_HOST:-mariadb} + export MYSQL_PORT=${MYSQL_PORT:-3306} + export COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-$PROJECT_NAME} + export LOCALDEV_URL=${LOCALDEV_URL:-http://content-sdp.docker.internal} + export COMPOSER=${COMPOSER:-composer.json} + export DRUPAL_PROFILE=${DRUPAL_PROFILE:-} + export DRUPAL_MODULE_PREFIX=${DRUPAL_MODULE_PREFIX:-mysite} + PHPCS_TARGETS=${PHPCS_TARGETS:-.} && export PHPCS_TARGETS=${PHPCS_TARGETS//,/ } + if [ "$CI" ]; then export ES_TPL=elasticsearch.ci.yml; fi + bash -c "$0" "$@" +- '{{cmd}}' +- '{{name}}' diff --git a/.docker/Caddyfile b/.docker/Caddyfile new file mode 100644 index 0000000..5031113 --- /dev/null +++ b/.docker/Caddyfile @@ -0,0 +1,9 @@ +content-sdp.docker.internal:80 { + reverse_proxy nginx:8080 +} +elasticsearch.docker.internal:80 { + reverse_proxy elasticsearch:9200 +} +mailhog.docker.internal:80 { + reverse_proxy mailhog:8025 +} diff --git a/.docker/Dockerfile.elasticsearch b/.docker/Dockerfile.elasticsearch index 836beb6..da997bb 100644 --- a/.docker/Dockerfile.elasticsearch +++ b/.docker/Dockerfile.elasticsearch @@ -1,11 +1,8 @@ -FROM amazeeio/elasticsearch:7-latest +FROM singledigital/bay-elasticsearch:5.x ARG ES_TPL ENV ES_TPL=${ES_TPL:-elasticsearch.yml} -RUN bin/elasticsearch-plugin install analysis-kuromoji \ - && bin/elasticsearch-plugin install analysis-icu - COPY .docker/elasticsearch.yml .docker/elasticsearch.* /tmp/elasticsearch/ RUN mkdir -p config \ diff --git a/.docker/elasticsearch.ci.yml b/.docker/elasticsearch.ci.yml new file mode 100644 index 0000000..b5bcfad --- /dev/null +++ b/.docker/elasticsearch.ci.yml @@ -0,0 +1,14 @@ +cluster.name: "docker-cluster" +network.host: 0.0.0.0 +transport.host: localhost + +discovery.type: single-node +xpack.license.self_generated.type: basic +xpack.security.enabled: false + +path.repo: ["/usr/share/elasticsearch/data/snapshots"] + +http.cors.enabled: true +http.cors.allow-origin: "*" +http.cors.allow-methods : OPTIONS, HEAD, GET +http.cors.allow-headers : X-Requested-With, X-Auth-Token, Content-Type, Content-Length diff --git a/.docker/elasticsearch.yml b/.docker/elasticsearch.yml new file mode 100644 index 0000000..bcdc1d1 --- /dev/null +++ b/.docker/elasticsearch.yml @@ -0,0 +1,13 @@ +cluster.name: "docker-cluster" +network.host: 0.0.0.0 + +discovery.type: single-node +xpack.license.self_generated.type: basic +xpack.security.enabled: false + +path.repo: ["/usr/share/elasticsearch/data/snapshots"] + +http.cors.enabled: true +http.cors.allow-origin: "*" +http.cors.allow-methods : OPTIONS, HEAD, GET +http.cors.allow-headers : X-Requested-With, X-Auth-Token, Content-Type, Content-Length diff --git a/.gitattributes b/.gitattributes index cf11764..a37894e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,61 @@ -# Ignore files for distribution archives. -.gitattributes export-ignore -.gitignore export-ignore -.github export-ignore -.circleci export-ignore -.circleci/config.yml export-ignore -.env export-ignore -dev-init.sh export-ignore +# Drupal git normalization +# @see https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html +# @see https://www.drupal.org/node/1542048 + +# Normally these settings would be done with macro attributes for improved +# readability and easier maintenance. However macros can only be defined at the +# repository root directory. Drupal avoids making any assumptions about where it +# is installed. + +# Define text file attributes. +# - Treat them as text. +# - Ensure no CRLF line-endings, neither on checkout nor on checkin. +# - Detect whitespace errors. +# - Exposed by default in `git diff --color` on the CLI. +# - Validate with `git diff --check`. +# - Deny applying with `git apply --whitespace=error-all`. +# - Fix automatically with `git apply --whitespace=fix`. + +*.config text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.css text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.dist text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.engine text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.html text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=html +*.inc text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.install text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.js text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.json text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.lock text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.map text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.md text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.module text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.php text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.po text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.profile text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.script text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.sh text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.sql text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.svg text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.theme text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.twig text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.txt text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.xml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.yml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 + +# Define binary file attributes. +# - Do not treat them as text. +# - Include binary diff in patches instead of "binary files differ." +*.eot -text diff +*.exe -text diff +*.gif -text diff +*.gz -text diff +*.ico -text diff +*.jpeg -text diff +*.jpg -text diff +*.otf -text diff +*.phar -text diff +*.png -text diff +*.svgz -text diff +*.ttf -text diff +*.woff -text diff +*.woff2 -text diff diff --git a/README.md b/README.md index b4a8249..d256c46 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ your `composer.json`: ```json { - "repositories": { + "repositories": { "dpc-sdp/tide_search": { "type": "vcs", "no-api": true, @@ -30,38 +30,41 @@ your `composer.json`: Require this package as any other Composer package: ```bash -composer require dpc/tide_search -``` +composer require dpc/tide_search +``` ## Support -[Digital Engagement, Department of Premier and Cabinet, Victoria, Australia](https://github.com/dpc-sdp) +[Digital Engagement, Department of Premier and Cabinet, Victoria, Australia](https://github.com/dpc-sdp) is a maintainer of this package. ## Contribute [Open an issue](https://github.com/dpc-sdp) on GitHub or submit a pull request with suggested changes. ## Development and maintenance -Development is powered by [Dev-Tools](https://github.com/dpc-sdp/dev-tools). Please refer to Dev-Tools' +Development is powered by [Dev-Tools](https://github.com/dpc-sdp/dev-tools). Please refer to Dev-Tools' page for [system requirements](https://github.com/dpc-sdp/dev-tools/#prerequisites) and other details. To start local development stack: -1. Checkout this project -2. Run `./dev-tools.sh` -3. Run `ahoy build` - +1. Checkout this project +2. Ensure other projects using our dev stack are stopped +3. Run `./dev-tools.sh` +4. Run `ahoy build` +5. Use `ahoy login` to gain access to the CMS (or use the one time login link given at end of build) +6. Use `ahoy lint && ahoy test-behat` to run CI tests + ## Related projects -- [tide](https://github.com/dpc-sdp/tide) -- [tide_api](https://github.com/dpc-sdp/tide_api) +- [tide](https://github.com/dpc-sdp/tide) +- [tide_api](https://github.com/dpc-sdp/tide_api) - [tide_core](https://github.com/dpc-sdp/tide_core) - [tide_event](https://github.com/dpc-sdp/tide_event) - [tide_landing_page](https://github.com/dpc-sdp/tide_landing_page) -- [tide_media](https://github.com/dpc-sdp/tide_media) -- [tide_monsido](https://github.com/dpc-sdp/tide_monsido) -- [tide_news](https://github.com/dpc-sdp/tide_news) -- [tide_page](https://github.com/dpc-sdp/tide_page) -- [tide_site](https://github.com/dpc-sdp/tide_site) -- [tide_test](https://github.com/dpc-sdp/tide_test) -- [tide_webform](https://github.com/dpc-sdp/tide_webform) +- [tide_media](https://github.com/dpc-sdp/tide_media) +- [tide_monsido](https://github.com/dpc-sdp/tide_monsido) +- [tide_news](https://github.com/dpc-sdp/tide_news) +- [tide_page](https://github.com/dpc-sdp/tide_page) +- [tide_site](https://github.com/dpc-sdp/tide_site) +- [tide_test](https://github.com/dpc-sdp/tide_test) +- [tide_webform](https://github.com/dpc-sdp/tide_webform) ## License This project is licensed under [GPL2](https://github.com/dpc-sdp/tide_search/blob/master/LICENSE.txt) diff --git a/composer.json b/composer.json index 34b500d..ebd8987 100644 --- a/composer.json +++ b/composer.json @@ -1,24 +1,24 @@ { - "name": "dpc-sdp/tide_search", - "description": "Search configuration for Tide Drupal 8 distribution", - "type": "drupal-module", - "license": "GPL-2.0-or-later", - "require": { - "drupal/search_api": "^1.11", - "drupal/elasticsearch_connector": "^7.0", - "dpc-sdp/tide_core": "^3.0.0" - }, - "repositories": { - "drupal": { - "type": "composer", - "url": "https://packages.drupal.org/8" - } - }, - "extra": { - "drush": { - "services": { - "drush.services.yml": "^10" - } - } + "description": "Search configuration for Tide Drupal 8 distribution", + "extra": { + "drush": { + "services": { + "drush.services.yml": "^10" + } } + }, + "license": "GPL-2.0-or-later", + "name": "dpc-sdp/tide_search", + "repositories": { + "drupal": { + "type": "composer", + "url": "https://packages.drupal.org/8" + } + }, + "require": { + "dpc-sdp/tide_core": "^3.0.0", + "drupal/elasticsearch_connector": "^7.0", + "drupal/search_api": "^1.11" + }, + "type": "drupal-module" } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..1a77a61 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,153 @@ +# Docker Compose configuration file. +# +# - Using a single file to work in local, CI and production environments. +# - Local overrides are possible using docker-composer.override.yml file. +# - Use inline comments starting with ### to have the line removed in CI. +version: '2.3' + +x-bay-image-version: + &bay-image-version ${BAY_IMAGE_VERSION:-5.x} + +x-project: + &project ${PROJECT_NAME:-mysite} + +x-volumes: + &default-volumes + # Understanding host mounting in Docker-based projects. + # + # To share application code between services (containers), Docker uses volumes. + # When used in non-development environments, containers have access to + # the same shared files using volumes and these volumes do not need to be + # mounted from the host. But for development environment, when the code + # constantly changes on the host, we need to have these changes synchronized + # into all containers. Since we are using single `docker-compose.yml` file for + # all environments, we have to accommodate both cases, so we are specifying an + # override for the same directory as a mounted volume as a commented-out lines, + # which will be automatically uncommented in CI. + # + # See Docker Compose reference about volumes https://docs.docker.com/compose/compose-file/compose-file-v2/#volume-configuration-reference + volumes: + - .:/app:${VOLUME_FLAGS:-delegated} ### Local overrides to mount host filesystem. Automatically removed in CI and PROD. + - ./docroot/sites/default/files:/app/docroot/sites/default/files:${VOLUME_FLAGS:-delegated} ### Local overrides to mount host filesystem. Automatically removed in CI and PROD. + ##- app:/app + ##- files:/app/docroot/sites/default/files + +x-environment: + &default-environment + LAGOON_PROJECT: *project + # Local dev URL populated from the environment. Do not override here. Instead, + # specify the value in .env file. + LAGOON_LOCALDEV_URL: ${LOCALDEV_URL:-http://mysite.docker.amazee.io} + GITHUB_TOKEN: ${GITHUB_TOKEN:-} + BAY_KEY: ${BAY_KEY:-} + BAY_IMAGE_VERSION: ${BAY_IMAGE_VERSION:-5.x} + LAGOON_ENVIRONMENT_TYPE: ${LAGOON_ENVIRONMENT_TYPE:-local} + DRUPAL_REFRESH_SEARCHAPI: ${DRUPAL_REFRESH_SEARCHAPI:-} + # Uncomment to enable Xdebug and then restart via `ahoy up`. + #XDEBUG_ENABLE: "true" + DOCKERHOST: host.docker.internal + +services: + + cli: + build: + context: . + dockerfile: .docker/Dockerfile.cli + args: + COMPOSER: ${COMPOSER:-composer.json} + BAY_IMAGE_VERSION: *bay-image-version + image: *project + environment: + << : *default-environment + COMPOSER_MEMORY_LIMIT: -1 + << : *default-volumes + labels: + lagoon.type: cli-persistent + lagoon.persistent: /app/docroot/sites/default/files/ + lagoon.persistent.name: nginx-php + + nginx: + build: + context: . + dockerfile: .docker/Dockerfile.nginx-drupal + args: + CLI_IMAGE: *project + BAY_IMAGE_VERSION: *bay-image-version + << : *default-volumes + environment: + << : *default-environment + depends_on: + - cli + labels: + lagoon.type: nginx-php-persistent + lagoon.persistent: /app/docroot/sites/default/files/ + lagoon.persistent.class: slow + lagoon.name: nginx-php + expose: + - "8080" + php: + build: + context: . + dockerfile: .docker/Dockerfile.php + args: + CLI_IMAGE: *project + BAY_IMAGE_VERSION: *bay-image-version + environment: + << : *default-environment + << : *default-volumes + depends_on: + - cli + labels: + lagoon.type: nginx-php-persistent + lagoon.persistent: /app/docroot/sites/default/files/ + lagoon.persistent.class: slow + lagoon.name: nginx-php + + mariadb: + image: singledigital/bay-mariadb:${BAY_IMAGE_VERSION:-5.x} + ports: + - "3306" # Find port on host with `ahoy info` or `docker-compose port mariadb 3306` + labels: + lagoon.type: mariadb-shared + + redis: + image: uselagoon/redis-5:latest + labels: + lagoon.type: redis + + elasticsearch: + ports: + - "9200:9200" + build: + context: . + dockerfile: .docker/Dockerfile.elasticsearch + args: + - ES_TPL=${ES_TPL:-elasticsearch.yml} + labels: + lagoon.type: none + + chrome: + image: seleniarm/standalone-chromium:101.0 + shm_size: '1gb' + environment: + <<: *default-environment + <<: *default-volumes + depends_on: + - cli + labels: + lagoon.type: none + + proxy: + image: caddy:latest + restart: unless-stopped + ports: + - "${LOCAL_PORT:-80}:80" + volumes: + - $PWD/.docker:/etc/caddy + - $PWD/.docker/Caddyfile:/etc/caddy/Caddyfile + labels: + lagoon.type: none + +volumes: + app: {} + files: {} diff --git a/src/ElasticSearch/Parameters/Factory/TideSearchIndexFactory.php b/src/ElasticSearch/Parameters/Factory/TideSearchIndexFactory.php index a594079..1c53ece 100644 --- a/src/ElasticSearch/Parameters/Factory/TideSearchIndexFactory.php +++ b/src/ElasticSearch/Parameters/Factory/TideSearchIndexFactory.php @@ -4,6 +4,7 @@ use Drupal\elasticsearch_connector\ElasticSearch\Parameters\Factory\IndexFactory; use Drupal\elasticsearch_connector\Entity\Cluster; +use Drupal\elasticsearch_connector\Event\PrepareIndexEvent; use Drupal\search_api\Entity\Server; use Drupal\search_api\IndexInterface; @@ -14,6 +15,106 @@ class TideSearchIndexFactory extends IndexFactory { const HASH_LENGTH = 32; + /** + * Override the build parameters required to create an index. + * + * @param \Drupal\search_api\IndexInterface $index + * The index being processed. + * + * @return array + * Return the config for creation of index. + */ + public static function create(IndexInterface $index) { + $indexName = IndexFactory::getIndexName($index); + $filteredIndexName = str_replace('--', '-', $indexName); + $aliasPrefix = 'search-' . (\Drupal::request()->server->get('SEARCH_HASH') ?: '') . '-'; + $aliasName = $aliasPrefix . str_replace('_', '-', $filteredIndexName) . '-alias'; + $indexConfig = [ + 'index' => $indexName, + 'body' => [ + 'aliases' => [ + $aliasName => [ + 'is_hidden' => FALSE, + ], + ], + 'settings' => [ + 'number_of_shards' => $index->getOption('number_of_shards', 5), + 'number_of_replicas' => $index->getOption('number_of_replicas', 1), + 'analysis' => [ + "filter" => [ + "front_ngram" => [ + "type" => "edge_ngram", + "min_gram" => "1", + "max_gram" => "12", + ], + ], + "analyzer" => [ + "i_prefix" => [ + "filter" => [ + "cjk_width", + "lowercase", + "asciifolding", + "front_ngram", + ], + "tokenizer" => "standard", + ], + "q_prefix" => [ + "filter" => [ + "cjk_width", + "lowercase", + "asciifolding", + ], + "tokenizer" => "standard", + ], + ], + ], + ], + 'mappings' => [ + "properties" => [ + "title" => [ + "type" => "text", + "fields" => [ + "keyword" => [ + "type" => "keyword", + "ignore_above" => 256, + ], + "prefix" => [ + "type" => "text", + "index_options" => "docs", + "analyzer" => "i_prefix", + "search_analyzer" => "q_prefix", + ], + ], + ], + "summary_processed" => [ + "type" => "text", + "fields" => [ + "keyword" => [ + "type" => "keyword", + "ignore_above" => 256, + ], + "prefix" => [ + "type" => "text", + "index_options" => "docs", + "analyzer" => "i_prefix", + "search_analyzer" => "q_prefix", + ], + ], + ], + ], + ], + ], + ]; + + // Allow other modules to alter index config before we create it. + $dispatcher = \Drupal::service('event_dispatcher'); + $prepareIndexEvent = new PrepareIndexEvent($indexConfig, $indexName); + $event = $dispatcher->dispatch($prepareIndexEvent, PrepareIndexEvent::PREPARE_INDEX); + $indexConfig = $event->getIndexConfig(); + + return $indexConfig; + } + /** * Overrides the elasticsearch_connector bulk delete params. * diff --git a/tests/behat/features/search.feature b/tests/behat/features/search.feature index 7c6d52a..e0e65da 100644 --- a/tests/behat/features/search.feature +++ b/tests/behat/features/search.feature @@ -14,6 +14,24 @@ Feature: Ensure Search API on Bay Elasticsearch work. Then the response status code should be 200 And the response should contain "elasticsearch_index_drupal_node" + When I visit "http://elasticsearch:9200/_cat/aliases?v" + Then the response status code should be 200 + And the response should contain "search--elasticsearch-index-drupal-node-alias" + + When I send a GET request to "http://elasticsearch:9200/elasticsearch_index_drupal_node/_mapping" + Then the response status code should be 200 + And the response should be in JSON + And the JSON node "elasticsearch_index_drupal_node" should exist + And the JSON node "elasticsearch_index_drupal_node.mappings" should exist + And the JSON node "elasticsearch_index_drupal_node.mappings.properties" should exist + And the JSON node "elasticsearch_index_drupal_node.mappings.properties.summary_processed" should exist + And the JSON node "elasticsearch_index_drupal_node.mappings.properties.summary_processed.fields.prefix.search_analyzer" should be equal to "q_prefix" + And the JSON node "elasticsearch_index_drupal_node" should exist + And the JSON node "elasticsearch_index_drupal_node.mappings" should exist + And the JSON node "elasticsearch_index_drupal_node.mappings.properties" should exist + And the JSON node "elasticsearch_index_drupal_node.mappings.properties.title" should exist + And the JSON node "elasticsearch_index_drupal_node.mappings.properties.title.fields.prefix.analyzer" should be equal to "i_prefix" + @api Scenario: Assert that Elasticsearch can index content. Given topic terms: