Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

class EnginePersister
{
/** @var Manager */
/** @var IndexService */
private $indexService;
/** @var DocumentMapperFactory */
private $documentMapperFactory;
Expand Down
4 changes: 2 additions & 2 deletions src/CoreShop2VueStorefrontBundle/Bridge/ImporterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ public function __construct(PersisterFactory $persisterFactory)
/**
* @return array<ImporterFactory>
*/
public function create(?string $site = null, ?string $type = null, ?string $language = null, ?string $store = null, ?\DateTimeInterface $since = null): array
public function create(?string $site = null, ?string $type = null, ?string $language = null, ?string $store = null, ?\DateTimeInterface $since = null, ?string $runTimestamp = null): array
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this to be configurable, it will never be changed to anything else.

{
$persisters = $this->persisterFactory->create($site, $type, $language, $store);
$persisters = $this->persisterFactory->create($site, $type, $language, $store, $runTimestamp);
$importers = [];
foreach ($persisters as $config) {
$importers[] = new ElasticsearchImporter($config['repository'], $config['persister'], $config['site'], $config['type'], $config['language'], $config['store'], $since);
Expand Down
16 changes: 7 additions & 9 deletions src/CoreShop2VueStorefrontBundle/Bridge/PersisterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace CoreShop2VueStorefrontBundle\Bridge;

use CoreShop2VueStorefrontBundle\Bridge\SwappingIndexService;
use ONGR\ElasticsearchBundle\Mapping\Converter;
use ONGR\ElasticsearchBundle\Mapping\IndexSettings;
use ONGR\ElasticsearchBundle\Service\IndexService;
Expand Down Expand Up @@ -77,7 +78,7 @@ public function __construct(ContainerInterface $container, Converter $converter,
/**
* @return array<array{persister: PersisterFactory, store: string, language: string, type: string}>
*/
public function create(?string $site = null, ?string $type = null, ?string $language = null, ?string $store = null): array
public function create(?string $site = null, ?string $type = null, ?string $language = null, ?string $store = null, ?string $runTimestamp = null): array
{
$options = $this->resolver->resolve(['site' => $site, 'type' => $type, 'language' => $language, 'store' => $store]);

Expand Down Expand Up @@ -115,16 +116,9 @@ public function create(?string $site = null, ?string $type = null, ?string $lang
];

$indexName = $this->inject($this->elasticsearchConfig['index'], $variables);
$settings = new IndexSettings(
$className,
$indexName,
$indexName,
$this->elasticsearchConfig['templates'][$className] ?? [],
$this->inject($this->elasticsearchConfig['hosts'], $variables, true)
);
$indexSettings = new IndexSettings(
$className,
$indexName,
$runTimestamp ? $indexName.'_'.$runTimestamp : $indexName,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better name, maybe $indexSuffix?

$indexName,
array_replace_recursive(
$indexSettings->getIndexMetadata(),
Expand All @@ -139,6 +133,10 @@ public function create(?string $site = null, ?string $type = null, ?string $lang
$indexSettings
);

if ($runTimestamp) {
$indexService = new SwappingIndexService($indexService, $runTimestamp);
}

$persisters[] = [
'persister' => new EnginePersister($indexService, $this->documentMapperFactory, $language, $concreteStore),
'site' => $name,
Expand Down
77 changes: 77 additions & 0 deletions src/CoreShop2VueStorefrontBundle/Bridge/SwappingIndexService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

declare(strict_types=1);

namespace CoreShop2VueStorefrontBundle\Bridge;

use ONGR\ElasticsearchBundle\Service\IndexService;

class SwappingIndexService extends IndexService
{
private $runTimestamp;
/**
* @var IndexService
*/
private $baseIndexService;

public function __construct(IndexService $baseIndexService, string $runTimestamp)
{
$this->baseIndexService = $baseIndexService;
$this->runTimestamp = $runTimestamp;
}

/**
* Flushes ES and adds extra steps needed for swapping (assign alias to new index, remove from old indices, drop old indices)
*
* @param array $params
* @return array
*/
public function flush(array $params = []): array
{
$return = $this->baseIndexService->flush($params);

$indicesClient = $this->baseIndexService->getClient()->indices();
$settings = $this->baseIndexService->indexSettings;

$oldIndices = null;
// if alias doesn't exist, the previous index will have a clashing name with alias we're creating so we have to drop it
if(!$indicesClient->existsAlias(['name' => $settings->getAlias()])) {
$this->baseIndexService->dropIndex();
}
else {
//get index names associated with alias
$oldIndices = implode(',', array_keys($indicesClient->getAlias(['name' => $settings->getAlias()])));
//delete alias from old indices
$indicesClient->deleteAlias([
"index" => $oldIndices,
"name" => $settings->getAlias()
]);
}
//assign alias to new index
$indicesClient->putAlias([
"index" => $settings->getIndexName(),
"name" => $settings->getAlias()
]);

if($oldIndices) {
//drop old indices
$indicesClient->delete([
"index" => $oldIndices
]);
}

return $return;
}

public function getBaseIndexService(): IndexService
{
return $this->baseIndexService;
}

public function __call($method, $args)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unfortunate, but I guess it's the only way to do it. Wish IndexService had an interface.

{
if (!method_exists($this, $method) && method_exists($this->baseIndexService, $method)) {
return $this->baseIndexService->$method($args);
}
}
}
4 changes: 3 additions & 1 deletion src/CoreShop2VueStorefrontBundle/Command/IndexCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ protected function configure()
->addArgument('language', InputArgument::OPTIONAL, 'Language to index')
->addArgument('store', InputArgument::OPTIONAL, 'Site store to index')
->addOption('updated-since', 's', InputOption::VALUE_OPTIONAL, 'Fetch objects updated in the relative timeframe ("5minute", "2hour", "1day", "yesterday" etc)')
->addOption('swap', null, InputOption::VALUE_OPTIONAL, 'Do a full reingest by swapping indices', false)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Booleans use InputOption::VALUE_NONE, they're false by default.

->setName('vsbridge:index-objects')
->setDescription('Indexing objects of given type in vuestorefront');
}
Expand Down Expand Up @@ -63,6 +64,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$language = $input->getArgument('language');
$store = $input->getArgument('store');

$runTimestamp = date('YmdHis');
$sinceDatetime = null;
if (null !== $since = $input->getOption('updated-since')) {
$sinceDatetime = new \Datetime();
Expand All @@ -78,7 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$style->warning(sprintf('Indexing only updated since: %1$s', $sinceDatetime->format('c')));
}

$importers = $this->importerFactory->create($site, $type, $language, $store, $sinceDatetime);
$importers = $this->importerFactory->create($site, $type, $language, $store, $sinceDatetime, $input->getOption('swap') ? $runTimestamp : null);

/** @var ImporterInterface $importer */
foreach ($importers as $importer) {
Expand Down