class CertificateAuthoritiesApiController implements CertificateAuthoritiesApi {

    @SuppressWarnings("squid:S3655") // see reason below
    @Override
    @PreAuthorize("(hasAuthority('GENERATE_AUTH_CERT_REQ') and "
            + " (#keyUsageType == T(org.niis.xroad.restapi.openapi.model.KeyUsageType).AUTHENTICATION))"
            + " or (hasAuthority('GENERATE_SIGN_CERT_REQ') and "
            + "(#keyUsageType == T(org.niis.xroad.restapi.openapi.model.KeyUsageType).SIGNING))")
    public ResponseEntity<List<CsrSubjectFieldDescription>> getSubjectFieldDescriptions(
            String caName,
            KeyUsageType keyUsageType,
            String keyId,
            String encodedMemberId,
            Boolean isNewMember) {

        // squid:S3655 throwing NoSuchElementException if there is no value present is
        // fine since keyUsageInfo is mandatory parameter
        KeyUsageInfo keyUsageInfo = KeyUsageTypeMapping.map(keyUsageType).get();

        // memberId is mandatory for sign csrs
        if (keyUsageInfo == KeyUsageInfo.SIGNING) {
            if (StringUtils.isBlank(encodedMemberId)) {
                throw new BadRequestException("memberId is mandatory for sign csrs");
            }
        }

        try {
            if (!StringUtils.isBlank(keyId)) {
                // validate that key.usage matches keyUsageType
                KeyInfo keyInfo = keyService.getKey(keyId);
                if (keyInfo.getUsage() != null) {
                    if (keyInfo.getUsage() != keyUsageInfo) {
                        throw new BadRequestException("key is for different usage",
                                new ErrorDeviation("wrong_key_usage"));
                    }
                }
            }

            ClientId memberId = null;
            if (!StringUtils.isBlank(encodedMemberId)) {
                memberId = clientConverter.convertId(encodedMemberId);
            }

            CertificateProfileInfo profileInfo;
            profileInfo = certificateAuthorityService.getCertificateProfile(
                    caName, keyUsageInfo, memberId, isNewMember);
            List<CsrSubjectFieldDescription> converted = subjectConverter.convert(
                    profileInfo.getSubjectFields());
            return new ResponseEntity<>(converted, HttpStatus.OK);

        } catch (WrongKeyUsageException | KeyNotFoundException | ClientNotFoundException e) {
            throw new BadRequestException(e);
        } catch (CertificateAuthorityNotFoundException e) {
            throw new ResourceNotFoundException(e);
        } catch (CertificateProfileInstantiationException e) {
            throw new InternalServerErrorException(e);
        }
    }

    public  CertificateAuthoritiesApiController(CertificateAuthorityService certificateAuthorityService,
            CertificateAuthorityConverter certificateAuthorityConverter,
            KeyService keyService,
            ClientConverter clientConverter,
            CsrSubjectFieldDescriptionConverter subjectConverter);

}