@DB
  @Override
  @ActionEvent(
      eventType = EventTypes.EVENT_LB_CERT_DELETE,
      eventDescription = "Deleting a certificate to cloudstack",
      async = false)
  public void deleteSslCert(DeleteSslCertCmd deleteSslCertCmd) {

    CallContext ctx = CallContext.current();
    Account caller = ctx.getCallingAccount();

    Long certId = deleteSslCertCmd.getId();
    SslCertVO certVO = _sslCertDao.findById(certId);

    if (certVO == null) {
      throw new InvalidParameterValueException("Invalid certificate id: " + certId);
    }
    _accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, certVO);

    List<LoadBalancerCertMapVO> lbCertRule = _lbCertDao.listByCertId(certId);

    if ((lbCertRule != null) && (!lbCertRule.isEmpty())) {
      String lbUuids = "";

      for (LoadBalancerCertMapVO rule : lbCertRule) {
        LoadBalancerVO lb = _entityMgr.findById(LoadBalancerVO.class, rule.getLbId());
        lbUuids += " " + lb.getUuid();
      }

      throw new CloudRuntimeException("Certificate in use by a loadbalancer(s)" + lbUuids);
    }

    _sslCertDao.remove(certId);
  }
  @DB
  @Override
  @ActionEvent(
      eventType = EventTypes.EVENT_LB_CERT_UPLOAD,
      eventDescription = "Uploading a certificate to cloudstack",
      async = false)
  public SslCertResponse uploadSslCert(UploadSslCertCmd certCmd) {
    try {

      String cert = URLDecoder.decode(certCmd.getCert(), "UTF-8");
      String key = URLDecoder.decode(certCmd.getKey(), "UTF-8");
      String password = certCmd.getPassword();
      String chain =
          certCmd.getChain() == null ? null : URLDecoder.decode(certCmd.getChain(), "UTF-8");

      validate(cert, key, password, chain);
      s_logger.debug("Certificate Validation succeeded");

      String fingerPrint = generateFingerPrint(parseCertificate(cert));

      Long accountId = CallContext.current().getCallingAccount().getId();
      Long domainId = CallContext.current().getCallingAccount().getDomainId();

      SslCertVO certVO =
          new SslCertVO(cert, key, password, chain, accountId, domainId, fingerPrint);
      _sslCertDao.persist(certVO);

      return createCertResponse(certVO, null);

    } catch (UnsupportedEncodingException e) {
      throw new CloudRuntimeException("Error decoding certificate data");
    }
  }
  @Override
  public List<SslCertResponse> listSslCerts(ListSslCertsCmd listSslCertCmd) {
    CallContext ctx = CallContext.current();
    Account caller = ctx.getCallingAccount();

    Long certId = listSslCertCmd.getCertId();
    Long accountId = listSslCertCmd.getAccountId();
    Long lbRuleId = listSslCertCmd.getLbId();

    List<SslCertResponse> certResponseList = new ArrayList<SslCertResponse>();

    if (certId == null && accountId == null && lbRuleId == null) {
      throw new InvalidParameterValueException(
          "Invalid parameters either certificate ID or Account ID or Loadbalancer ID required");
    }

    List<LoadBalancerCertMapVO> certLbMap = null;
    SslCertVO certVO = null;

    if (certId != null) {

      certVO = _sslCertDao.findById(certId);

      if (certVO == null) {
        throw new InvalidParameterValueException("Invalid certificate id: " + certId);
      }

      _accountMgr.checkAccess(caller, SecurityChecker.AccessType.UseEntry, true, certVO);

      certLbMap = _lbCertDao.listByCertId(certId);

      certResponseList.add(createCertResponse(certVO, certLbMap));
      return certResponseList;
    }

    if (lbRuleId != null) {
      LoadBalancer lb = _entityMgr.findById(LoadBalancerVO.class, lbRuleId);

      if (lb == null) {
        throw new InvalidParameterValueException("found no loadbalancer  wth id: " + lbRuleId);
      }

      _accountMgr.checkAccess(caller, SecurityChecker.AccessType.UseEntry, true, lb);

      // get the cert id
      LoadBalancerCertMapVO lbCertMapRule;
      lbCertMapRule = _lbCertDao.findByLbRuleId(lbRuleId);

      if (lbCertMapRule == null) {
        s_logger.debug("No certificate bound to loadbalancer id: " + lbRuleId);
        return certResponseList;
      }

      certVO = _sslCertDao.findById(lbCertMapRule.getCertId());
      certLbMap = _lbCertDao.listByCertId(lbCertMapRule.getCertId());

      certResponseList.add(createCertResponse(certVO, certLbMap));
      return certResponseList;
    }

    // reached here look by accountId
    List<SslCertVO> certVOList = _sslCertDao.listByAccountId(accountId);
    if (certVOList == null || certVOList.isEmpty()) return certResponseList;
    _accountMgr.checkAccess(caller, SecurityChecker.AccessType.UseEntry, true, certVOList.get(0));

    for (SslCertVO cert : certVOList) {
      certLbMap = _lbCertDao.listByCertId(cert.getId());
      certResponseList.add(createCertResponse(cert, certLbMap));
    }

    return certResponseList;
  }