Package org.candlepin.pinsetter.tasks

Source Code of org.candlepin.pinsetter.tasks.MigrateOwnerJob

/**
* Copyright (c) 2009 - 2012 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package org.candlepin.pinsetter.tasks;

import static org.quartz.JobBuilder.*;

import org.candlepin.audit.EventSink;
import org.candlepin.client.CandlepinConnection;
import org.candlepin.client.ConsumerClient;
import org.candlepin.client.OwnerClient;
import org.candlepin.common.config.Configuration;
import org.candlepin.common.exceptions.BadRequestException;
import org.candlepin.common.exceptions.NotFoundException;
import org.candlepin.config.ConfigProperties;
import org.candlepin.model.Consumer;
import org.candlepin.model.ConsumerCurator;
import org.candlepin.model.Entitlement;
import org.candlepin.model.EntitlementCurator;
import org.candlepin.model.Owner;
import org.candlepin.model.OwnerCurator;
import org.candlepin.model.Pool;
import org.candlepin.model.PoolCurator;
import org.candlepin.util.Util;

import com.google.inject.Inject;

import org.apache.commons.lang.StringUtils;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.jboss.resteasy.client.ClientResponse;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
/**
* MigrateOwnerJob is an async job that will extract the owner and its data
* from another Candlepin instance. The job is passed an owner key identifying
* the owner to be migrated, an URI pointing to the Candlepin instance where
* the owner to be migrated currently exists, and finally an optional delete
* flag that indicates whether the original owner should be deleted once
* migration has occurred.
*/
public class MigrateOwnerJob extends KingpinJob {
    private static Logger log = LoggerFactory.getLogger(MigrateOwnerJob.class);

    private OwnerCurator ownerCurator;
    private PoolCurator poolCurator;
    private EntitlementCurator entCurator;
    private ConsumerCurator consumerCurator;
    private CandlepinConnection conn;
    private Configuration config;
    private HashMap<String, String> entMap = new HashMap<String, String>();
    private EventSink sink;


    /**
     * Constructs the job with the connection, configuration, and necessary
     * object curators required to persist the objects.
     * @param connection Represents connection to another Candlepin.
     * @param conf Candlepin configuration.
     * @param oc database layer for Owner
     * @param pc database layer for Pool
     * @param ec database layer for Entitlement
     * @param cc database layer for Consumer
     */
    @Inject
    public MigrateOwnerJob(CandlepinConnection connection, Configuration conf,
        OwnerCurator oc, PoolCurator pc, EntitlementCurator ec,
        ConsumerCurator cc, EventSink es) {
        ownerCurator = oc;
        consumerCurator = cc;
        conn = connection;
        config = conf;
        poolCurator = pc;
        entCurator = ec;
        sink = es;
    }

    private static String buildUri(String uri) {
        if (uri == null || "".equals(uri.trim())) {
            return "";
        }

        String[] parts = uri.split("://");
        if (parts.length > 1) {
            String[] paths = parts[1].split("/");
            StringBuffer buf = new StringBuffer(parts[0]);
            buf.append("://");
            buf.append(paths[0]);
            buf.append("/candlepin");
            uri = buf.toString();
        }
        else {
            StringBuffer buf = new StringBuffer("http://");
            buf.append(parts[0]);
            buf.append("/candlepin");
            uri = buf.toString();
        }

        return uri;
    }

    @Override
    public void toExecute(JobExecutionContext ctx)
        throws JobExecutionException {
        String key = ctx.getMergedJobDataMap().getString("owner_key");
        String uri = buildUri(ctx.getMergedJobDataMap().getString("uri"));
        boolean delete = ctx.getMergedJobDataMap().getBoolean("delete");

        validateInput(key, uri);

        Credentials creds = new UsernamePasswordCredentials(
            config.getString(ConfigProperties.SHARD_USERNAME),
            config.getString(ConfigProperties.SHARD_PASSWORD));
        OwnerClient oclient = conn.connect(OwnerClient.class, creds, uri);

        log.info("Migrating owner [" + key +
            "] from candlepin instance running on [" + uri + "]");
        replicateOwner(key, oclient);


        log.info("Migrating pools for owner [" + key +
            "] from candlepin instance running on [" + uri + "]");
        replicatePools(key, oclient);

        log.info("Migrating entitlements for owner [" + key +
            "] from candlepin instance running on [" + uri + "]");
        replicateEntitlements(key, oclient);

        log.info("Migrating consumers for owner [" + key +
            "] from candlepin instance running on [" + uri + "]");
        replicateConsumers(key, oclient);

        ConsumerClient cclient = conn.connect(ConsumerClient.class, creds, uri);
        log.info("Associating consumers to their entitlements for owner [" +
            key + "]");
        associateConsumersToEntitlements(key, cclient);

        if (delete) {
            log.info("Removing owner [" + key +
                "] from candlepin instance running on [" + uri + "]");
            cleanupOwner(key, oclient);
        }
        else {
            log.info("delete flag was false, owner [" + key +
                "] will not be deleted from candlepin instance running on [" +
                uri + "]");
        }

        log.info("FINISHED - migration of owner [" + key +
            "] from candlepin instance running on [" + uri + "]");
    }

    /**
     * deletes the owner from the <strong>other</strong> Candlepin instance.
     * @param key owner key to be deleted.
     * @param client Candlepin client.
     * @throws WebApplicationException if the other Candlepin instance returns
     * other than OK, ACCEPTED, or NO_CONTENT.
     */
    private void cleanupOwner(String key, OwnerClient client) {
        Response rsp = client.deleteOwner(key, false);
        if (rsp.getStatus() != Status.OK.getStatusCode() &&
            rsp.getStatus() != Status.ACCEPTED.getStatusCode() &&
            rsp.getStatus() != Status.NO_CONTENT.getStatusCode()) {
            throw new WebApplicationException(rsp);
        }
    }

    /**
     * associates the migrated entitlements to the migrated consumers since
     * the api does not return the associations.
     * @param key owner key to be deleted.
     * @param client Candlepin client.
     * @throws WebApplicationException if the other Candlepin instance returns
     * other than OK.
     */
    private void associateConsumersToEntitlements(String key,
        ConsumerClient client) {

        Owner owner = ownerCurator.lookupByKey(key);
        log.debug("owner [" + owner.getDisplayName() + "] has [" +
            owner.getConsumers().size() + "] consumers");

        List<Consumer> consumers = consumerCurator.listByOwner(owner);
        for (Consumer c : consumers) {

            if (log.isDebugEnabled()) {
                log.debug("Processing consumer [" + c.getUuid() + "]");
            }

            ClientResponse<List<Entitlement>> rsp =
                client.replicateEntitlements(c.getUuid(), null);
            if (rsp.getStatus() != Status.OK.getStatusCode()) {
                throw new WebApplicationException(rsp);
            }

            for (Entitlement e : rsp.getEntity()) {
                Entitlement realent = entCurator.find(e.getId());
                realent.setConsumer(c);
                entCurator.merge(realent);
            }
        }

        sink.emitOwnerMigrated(owner);
    }

    /**
     * Replicates the Owner from the Candlepin pointed to by the client.
     * @param key owner key who should be migrated.
     * @param client Candlepin client.
     * @throws NotFoundException if the other Candlepin instance returns
     * NOT_FOUND.
     */
    private void replicateOwner(String key, OwnerClient client) {
        ClientResponse<Owner> rsp = client.replicateOwner(key);

        log.info("call returned - status: [" + rsp.getStatus() + "] reason [" +
            rsp.getResponseStatus() + "]");

        if (rsp.getStatus() == Status.NOT_FOUND.getStatusCode()) {
            throw new NotFoundException("Can't find owner [" + key + "]");
        }

        Owner owner = rsp.getEntity();
        ownerCurator.replicate(owner);

    }

    /**
     * Replicates the owner's pools from the Candlepin pointed to by the client.
     * @param key owner key whose pools should be migrated.
     * @param client Candlepin client.
     * @throws WebApplicationException if the other Candlepin instance returns
     * other than OK.
     */
    private void replicatePools(String key, OwnerClient client) {
        ClientResponse<List<Pool>> rsp = client.replicatePools(key);
        if (rsp.getStatus() != Status.OK.getStatusCode()) {
            throw new WebApplicationException(rsp);
        }

        List<Pool> pools = rsp.getEntity();

        for (Pool pool : pools) {
            Entitlement ent = pool.getSourceEntitlement();
            poolCurator.replicate(pool);
            if (ent != null) {
                log.info("pool.id" + pool.getId() + " sourceEntitlement " + ent.getId());
                entMap.put(ent.getId(), pool.getId());
            }
        }
    }

    /**
     * Replicates the owner's consumers from the Candlepin pointed to by the
     * client.
     * @param key owner key whose consumers should be migrated.
     * @param client Candlepin client.
     * @throws WebApplicationException if the other Candlepin instance returns
     * other than OK.
     */
    private void replicateConsumers(String key, OwnerClient client) {
        // track down consumers for the owner
        ClientResponse<List<Consumer>> rsp = client.replicateConsumers(key);

        if (rsp.getStatus() != Status.OK.getStatusCode()) {
            throw new WebApplicationException(rsp);
        }

        for (Consumer consumer : rsp.getEntity()) {
            log.info("importing consumer: " + consumer.toString());

            log.info("consumer.id: " + consumer.getId());
            log.info("consumer.entitlements:  " +
                ((consumer.getEntitlements() != null) ?
                    consumer.getEntitlements().toString() : "null"));
            log.info("consumer.facts: " +
                ((consumer.getFacts() != null) ?
                    consumer.getFacts().toString() : "null"));
            log.info("consumer.keyPair: " + consumer.getKeyPair());
            log.info("consumer.idcert: " + consumer.getIdCert());

            consumerCurator.replicate(consumer);
        }
    }

    /**
     * Replicates the owner's entitlements from the Candlepin pointed to by the
     * client.
     * @param key owner key whose entitlements should be migrated.
     * @param client Candlepin client.
     * @throws WebApplicationException if the other Candlepin instance returns
     * other than OK.
     */
    private void replicateEntitlements(String key, OwnerClient client) {
        ClientResponse<List<Entitlement>> rsp = client.replicateEntitlements(key);

        if (rsp.getStatus() != Status.OK.getStatusCode()) {
            throw new WebApplicationException(rsp);
        }

        Owner owner = ownerCurator.lookupByKey(key);
        List<Entitlement> ents = rsp.getEntity();

        for (Entitlement ent : ents) {
            ent.setOwner(owner);

            entCurator.replicate(ent);
            if (entMap.containsKey(ent.getId())) {
                log.info("entitlement with source pool " +
                    poolCurator.find(entMap.get(ent.getId())));

                Pool entPool = poolCurator.find(entMap.get(ent.getId()));
                entPool.setSourceEntitlement(entCurator.find(ent.getId()));
                poolCurator.merge(entPool);
            }
        }
    }

    /**
     * Creates the JobDetail for this MigrateOwnerJob class. The JobDetail will
     * get passed in through the execute method via the JobExecutionContext.
     * @param key owner key who should be migrated.
     * @param uri URI of the Candlepin instance where owner will be pulled.
     * @param delete true if owner should be deleted from the Candlepin
     * instance pointed by the URI.
     * @return JobDetail containing the information needed by the asynchronous
     * job to handle the migration of the given owner (key).
     */
    public static JobDetail migrateOwner(String key, String uri, boolean delete) {
        uri = buildUri(uri);
        validateInput(key, uri);

        JobDataMap map = new JobDataMap();
        map.put("owner_key", key);
        map.put("uri", uri);
        map.put("delete", delete);

        JobDetail detail = newJob(MigrateOwnerJob.class)
            .withIdentity("migrate_owner_" + Util.generateUUID())
            .requestRecovery(true) // recover the job upon restarts
            .usingJobData(map)
            .build();

        return detail;
    }

    private static void validateInput(String key, String uri) {
        if (StringUtils.isEmpty(key)) {
            throw new BadRequestException("Invalid owner key");
        }

        if (StringUtils.isEmpty(uri)) {
            throw new BadRequestException("Invalid URL [" + uri + "]");
        }

        try {
            new URL(uri);
        }
        catch (MalformedURLException e) {
            throw new BadRequestException("Invalid URL [" + uri + "]", e);
        }

    }
}
TOP

Related Classes of org.candlepin.pinsetter.tasks.MigrateOwnerJob

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.