org.xipki.pki.ca.client.shell.loadtest.CaLoadTestRevoke.java Source code

Java tutorial

Introduction

Here is the source code for org.xipki.pki.ca.client.shell.loadtest.CaLoadTestRevoke.java

Source

/*
 *
 * Copyright (c) 2013 - 2016 Lijun Liao
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3
 * as published by the Free Software Foundation with the addition of the
 * following permission added to Section 15 as permitted in Section 7(a):
 *
 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
 * THE AUTHOR LIJUN LIAO. LIJUN LIAO DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
 * OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License.
 *
 * You can be released from the requirements of the license by purchasing
 * a commercial license. Buying such a license is mandatory as soon as you
 * develop commercial activities involving the XiPKI software without
 * disclosing the source code of your own applications.
 *
 * For more information, please contact Lijun Liao at this
 * address: lijun.liao@gmail.com
 */

package org.xipki.pki.ca.client.shell.loadtest;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.Certificate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xipki.commons.common.LoadExecutor;
import org.xipki.commons.common.util.CollectionUtil;
import org.xipki.commons.common.util.ParamUtil;
import org.xipki.commons.datasource.springframework.dao.DataAccessException;
import org.xipki.commons.security.CrlReason;
import org.xipki.pki.ca.client.api.CaClient;
import org.xipki.pki.ca.client.api.CaClientException;
import org.xipki.pki.ca.client.api.CertIdOrError;
import org.xipki.pki.ca.client.api.PkiErrorException;
import org.xipki.pki.ca.client.api.dto.RevokeCertRequest;
import org.xipki.pki.ca.client.api.dto.RevokeCertRequestEntry;

/**
 * @author Lijun Liao
 * @since 2.0.0
 */

public class CaLoadTestRevoke extends LoadExecutor {

    private static final Logger LOG = LoggerFactory.getLogger(CaLoadTestRevoke.class);

    private static final CrlReason[] REASONS = { CrlReason.UNSPECIFIED, CrlReason.KEY_COMPROMISE,
            CrlReason.AFFILIATION_CHANGED, CrlReason.SUPERSEDED, CrlReason.CESSATION_OF_OPERATION,
            CrlReason.CERTIFICATE_HOLD, CrlReason.PRIVILEGE_WITHDRAWN };

    private final CaClient caClient;

    private final X500Name caSubject;

    private final int num;

    private final int maxCerts;

    private final Iterator<BigInteger> serialNumberIterator;

    private AtomicInteger processedCerts = new AtomicInteger(0);

    public CaLoadTestRevoke(final CaClient caClient, final Certificate caCert,
            final Iterator<BigInteger> serialNumberIterator, final int maxCerts, final int num,
            final String description) throws Exception {
        super(description);
        ParamUtil.requireNonNull("caCert", caCert);
        this.num = ParamUtil.requireMin("num", num, 1);
        this.caClient = ParamUtil.requireNonNull("caClient", caClient);
        this.serialNumberIterator = ParamUtil.requireNonNull("serialNumberIterator", serialNumberIterator);
        this.caSubject = caCert.getSubject();
        this.maxCerts = maxCerts;
    } // constructor

    class Testor implements Runnable {

        @Override
        public void run() {
            while (!stop() && getErrorAccout() < 1) {
                List<BigInteger> serialNumbers;
                try {
                    serialNumbers = nextSerials();
                } catch (DataAccessException ex) {
                    account(1, 1);
                    break;
                }

                if (CollectionUtil.isEmpty(serialNumbers)) {
                    break;
                }

                boolean successful = testNext(serialNumbers);
                int numFailed = successful ? 0 : 1;
                account(1, numFailed);
            }
        }

        private boolean testNext(final List<BigInteger> serialNumbers) {
            RevokeCertRequest request = new RevokeCertRequest();
            int id = 1;
            for (BigInteger serialNumber : serialNumbers) {
                CrlReason reason = REASONS[Math.abs(serialNumber.intValue()) % REASONS.length];
                RevokeCertRequestEntry entry = new RevokeCertRequestEntry(Integer.toString(id++), caSubject,
                        serialNumber, reason.getCode(), null);
                request.addRequestEntry(entry);
            }

            Map<String, CertIdOrError> result;
            try {
                result = caClient.revokeCerts(request, null);
            } catch (CaClientException | PkiErrorException ex) {
                LOG.warn("{}: {}", ex.getClass().getName(), ex.getMessage());
                return false;
            } catch (Throwable th) {
                LOG.warn("{}: {}", th.getClass().getName(), th.getMessage());
                return false;
            }

            if (result == null) {
                return false;
            }

            int numSuccess = 0;
            for (CertIdOrError entry : result.values()) {
                if (entry.getCertId() != null) {
                    numSuccess++;
                }
            }
            return numSuccess == serialNumbers.size();
        } // method testNext

    } // class Testor

    @Override
    protected Runnable getTestor() throws Exception {
        return new Testor();
    }

    private List<BigInteger> nextSerials() throws DataAccessException {
        List<BigInteger> ret = new ArrayList<>(num);
        for (int i = 0; i < num; i++) {
            if (maxCerts > 0) {
                int num = processedCerts.getAndAdd(1);
                if (num >= maxCerts) {
                    break;
                }
            }

            if (serialNumberIterator.hasNext()) {
                BigInteger serial = serialNumberIterator.next();
                ret.add(serial);
            } else {
                break;
            }
        }
        return ret;
    }

}