Is it possible to replicate a single specific entity across workspaces (different sites) using this module (this API) instead of replicating all entities ?
Thanks !

Comments

DamienGR created an issue. See original summary.

timmillwood’s picture

Status: Active » Postponed

Yes, and no.

The UI doesn't support it yet, we are looking at adding a filter in at some point in the near future.

However the API supports it, you will see the replication library we are using supports an array of document IDs as part of the task. Therefore you could add the UUID of an entity in here and it should replicate just that one entitiy. This will not take into account any references in that entity such as users, tags, files etc, so you may get lots of weird stub entities unless you manually add the UUIDs for the references too.

Essentially this is how we plan to implement the filter.

DamienGR’s picture

Thank you for your answer. I will try to create my own Replicator (ReplicatorInterface) based on CouchdbReplicator.

timmillwood’s picture

That would be cool to see, if only to test.

You could extend CouchdbReplicator because it's only the \Drupal\relaxed\CouchdbReplicator::replicate method you'd need to change.

Grimreaper’s picture

Hello,

I also have the need to share single content.

My environment is a Drupal 8.1.10 with the dev version of the deploy ecosystem modules. And I am testing against a couchDB 1.6.1 (inside a docker container, official image).

Before extending the CouchdbReplicator, I tried to POC the mechanism by hardcoding an uuid into CouchdbReplicator replicate() method.

if ($task !== NULL) {
        $couchdb_task->setDocIds(array('de79459a-596b-4d7b-ba3a-b1ccad365670'));
        $couchdb_task->setParameters($task->getParameters());
}

Instead of:

if ($task !== NULL) {
        $couchdb_task->setFilter($task->getFilter());
        $couchdb_task->setParameters($task->getParameters());
}

And then if I try to deploy, I have the following errors in dblog.

Type: PHP

Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException: No route found for "POST /relaxed/couchdb/_changes": Method Not Allowed (Allow: PUT, GET) in Symfony\Component\HttpKernel\EventListener\RouterListener->onKernelRequest() (line 180 of /project/www/vendor/symfony/http-kernel/EventListener/RouterListener.php).

And

Type: Relaxed

Doctrine\CouchDB\HTTP\HTTPException: HTTP Error with status 405 occurred while requesting /couchdb/_changes?filter=_doc_ids. Error: in Doctrine\CouchDB\HTTP\HTTPException::fromResponse() (line 68 of /project/www/vendor/doctrine/couchdb/lib/Doctrine/CouchDB/HTTP/HTTPException.php).

I can't figure out how to pass a single entity to replicate.

Thanks for any help.

Grimreaper’s picture

Hum I think I found the problem:

In https://github.com/relaxedws/couchdb-replicator/blob/master/src/Replicat...

$options = array(
              'feed' => 'continuous',
              'style' => $this->task->getStyle(),
              'heartbeat' => $this->task->getHeartbeat(),
              'since' => $this->task->getSinceSeq(),
              'filter' => $this->task->getFilter(),
              'parameters' => $this->task->getParameters(),
                //'doc_ids' => $this->task->getDocIds(), // Not supported.
                //'limit' => 10000 //taking large value for now, needs optimisation
            );

It seems that filtering on a doc ID is not supported in the relaxedws library.

PS: Nope I pass in the else statement and in this statement the doc_ids option is not commented.

Grimreaper’s picture

Hello,

I found why I got the error.

When using doc_ids the request on the _changes endpoint is now a POST and not a GET request and the Drupal\relaxed\Plugin\rest\resource\ChangesResource does not have any post method.

I am trying to implement one. Now I am stuck with this error "Could not denormalize object of type Drupal\\replication\\Changes\\Changes, no supporting normalizer found."

I will try to figure out how to solve that.

Grimreaper’s picture

Having too much problems with the serializer/deserializer objects.

I found that using a parameter uuids allowed to filter the _changes endpoint.

Currently for the POC I have hardcoded my UUID in the CouchdbReplicator:

$couchdb_task->setParameters(array('uuids' => array('a4b33676-2703-478c-9d88-37a3cb7a3316')));

I will see to pass it generically.

Grimreaper’s picture

Going in the process of replication, I think there is no need to extend the CouchdbReplicator.

For my use case, I think I will create a new entity form because in the save method of deploy/src/Entity/Form/ReplicationForm.php, if I add

...
$task = new ReplicationTask();
    $task->setParameter('uuids', array('a4b33676-2703-478c-9d88-37a3cb7a3316'));

    try {
      $response = \Drupal::service('workspace.replicator_manager')->replicate(
        $this->entity->get('source')->entity,
        $this->entity->get('target')->entity,
        $task
      );
...

I can filter on UUID, so in my new form I will make a table to select the content entities to deploy. Maybe with a view, I don't know yet.

Grimreaper’s picture

Status: Postponed » Needs review

Hello,

I have created a functionnal sandbox https://www.drupal.org/sandbox/florenttorregrosa/2839013. I will upload the code soon.

Do you think this feature could be integrated in Deploy or should it stay a separated project?

Without response I will promote the sandbox to full project on the beginning of the next year.

Thanks for the review.

Grimreaper’s picture

Hello,

I have promoted my sandbox into a full project.

For information, I do not depend on relaxed web services and I made deploy an optional module for this feature.

shelane’s picture

We would want to replicate a node or a selection of nodes and their related entities. Particularly we use paragraphs (nested as well) and that is where the bulk of the content is.