All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.redhat.lightblue.migrator.DefaultMigrator Maven / Gradle / Ivy

The newest version!
package com.redhat.lightblue.migrator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ContainerNode;
import com.redhat.lightblue.client.LightblueClient;
import com.redhat.lightblue.client.LightblueException;
import com.redhat.lightblue.client.Projection;
import com.redhat.lightblue.client.Query;
import com.redhat.lightblue.client.request.data.DataFindRequest;
import com.redhat.lightblue.client.request.data.DataSaveRequest;
import com.redhat.lightblue.client.response.LightblueResponse;
import com.redhat.lightblue.client.response.LightblueResponseException;
import com.redhat.lightblue.client.util.JSON;

public class DefaultMigrator extends Migrator {

    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultMigrator.class);

    protected static final int BATCH_SIZE = 64;

    private LightblueClient sourceCli;
    private LightblueClient destCli;

    public DefaultMigrator(ThreadGroup grp) {
        super(grp);
    }

    private LightblueClient getSourceCli() {
        try {
            if (sourceCli == null) {
                sourceCli = getLightblueClient(getMigrationConfiguration().getSourceConfigPath());
            }
            return sourceCli;
        } catch (Exception e) {
            LOGGER.error("Cannot get source cli:{}", e);
            throw new RuntimeException("Cannot get source client:" + e);
        }
    }

    private LightblueClient getDestCli() {
        try {
            if (destCli == null) {
                destCli = getLightblueClient(getMigrationConfiguration().getDestinationConfigPath());
            }
            return destCli;
        } catch (Exception e) {
            LOGGER.error("Cannot get dest cli:{}", e);
            throw new RuntimeException("Cannot get dest client:" + e);
        }
    }

    @Override
    public List getSourceDocuments() {
        LOGGER.debug("Retrieving source docs");
        try {
            DataFindRequest sourceRequest = new DataFindRequest(getMigrationConfiguration().getSourceEntityName(),
                    getMigrationConfiguration().getSourceEntityVersion());
            sourceRequest.where(Query.query((ContainerNode) JSON.toJsonNode(getMigrationJob().getQuery())));
            sourceRequest.select(Projection.includeFieldRecursively("*"), Projection.excludeField("objectType"));
            LOGGER.debug("Source docs retrieval req: {}", sourceRequest.getBody());
            JsonNode[] results = getSourceCli().data(sourceRequest, JsonNode[].class);
            LOGGER.debug("There are {} source docs", results.length);
            return Arrays.asList(results);
        } catch (Exception e) {
            LOGGER.error("Error while retrieving source documents:{}", e);
            throw new RuntimeException("Cannot retrieve source documents:" + e);
        }
    }

    @Override
    public List getDestinationDocuments(Collection ids) {
        try {
            List destinationDocuments = new ArrayList<>();
            if (ids == null || ids.isEmpty()) {
                LOGGER.debug("Unable to fetch any destination documents as there are no source documents");
                return destinationDocuments;
            }

            List batch = new ArrayList<>();
            for (Identity id : ids) {
                batch.add(id);
                if (batch.size() >= BATCH_SIZE) {
                    doDestinationDocumentFetch(batch, destinationDocuments);
                    batch.clear();
                }
            }

            if (!batch.isEmpty()) {
                doDestinationDocumentFetch(batch, destinationDocuments);
            }
            return destinationDocuments;
        } catch (Exception e) {
            LOGGER.error("Error while retrieving destination documents:{}", e);
            throw new RuntimeException("Cannot retrieve destination documents:" + e);
        }
    }

    private void doDestinationDocumentFetch(List ids, List dest)
            throws Exception {
        if (ids != null && !ids.isEmpty()) {
            DataFindRequest destinationRequest = new DataFindRequest(getMigrationConfiguration().getDestinationEntityName(),
                    getMigrationConfiguration().getDestinationEntityVersion());
            List requestConditions = new ArrayList<>();
            for (Identity id : ids) {
                List docConditions = new ArrayList<>();
                int i = 0;
                for (String keyField : getMigrationConfiguration().getDestinationIdentityFields()) {
                    Object v = id.get(i);
                    Query docQuery = Query.withValue(keyField, Query.eq, v == null ? null : v.toString());
                    docConditions.add(docQuery);
                    i++;
                }
                requestConditions.add(Query.and(docConditions));
            }
            destinationRequest.where(Query.or(requestConditions));
            destinationRequest.select(Projection.includeFieldRecursively("*"), Projection.excludeField("objectType"));
            LOGGER.debug("Fetching destination docs {}", destinationRequest.getBody());
            JsonNode[] nodes = getDestCli().data(destinationRequest, JsonNode[].class);

            if (nodes != null) {
                LOGGER.debug("There are {} destination docs", nodes.length);
                for (JsonNode node : nodes) {
                    dest.add(node);
                }
            }
        }
    }

    @Override
    public List save(List docs) throws LightblueException {
        List responses = new ArrayList<>();
        StringBuilder errorMessage = new StringBuilder();

        List batch = new ArrayList<>();
        for (JsonNode doc : docs) {
            batch.add(doc);
            if (batch.size() >= BATCH_SIZE) {
                try {
                    responses.add(saveBatch(batch));
                } catch (LightblueResponseException ex) {
                    errorMessage.append(ex.getLightblueResponse().getText());
                }
                batch.clear();
            }
        }
        if (!batch.isEmpty()) {
            try {
                responses.add(saveBatch(batch));
                ping("Saving a batch");
            } catch (LightblueResponseException ex) {
                errorMessage.append(ex.getLightblueResponse().getText());
            }
        }

        if (errorMessage.length() > 0) {
            throw new LightblueException("Failed saving docs: " + errorMessage);
        }

        return responses;
    }

    @Override
    public String createRangeQuery(Date startDate, Date endDate) {
        StringTokenizer tkz = new StringTokenizer(getMigrationConfiguration().getTimestampFieldName(), ", ");
        List ql = new ArrayList<>();
        while (tkz.hasMoreTokens()) {
            String tok = tkz.nextToken();
            ql.add(Query.and(Query.withValue(tok, Query.gte, startDate),
                    Query.withValue(tok, Query.lt, endDate)));
        }
        if (ql.size() == 1) {
            return ql.get(0).toString();
        } else {
            return Query.or(ql).toString();
        }
    }

    private LightblueResponse saveBatch(List documentsToOverwrite) throws LightblueResponseException {
        // LightblueClient - save & overwrite documents
        DataSaveRequest saveRequest = new DataSaveRequest(getMigrationConfiguration().getDestinationEntityName(),
                getMigrationConfiguration().getDestinationEntityVersion());
        saveRequest.setUpsert(true);
        saveRequest.create(documentsToOverwrite.toArray());
        saveRequest.returns(Projection.includeField("*"));
        LightblueResponse response;
        try {
            response = getDestCli().data(saveRequest);
        } catch (LightblueException ex) {
            // bad things happened, bail!
            throw new RuntimeException(ex);
        }
        return response;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy