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

io.gravitee.rest.api.service.impl.TicketServiceImpl Maven / Gradle / Ivy

There is a newer version: 3.10.0
Show newest version
/**
 * Copyright (C) 2015 The Gravitee team (http://gravitee.io)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.gravitee.rest.api.service.impl;

import static io.gravitee.rest.api.service.builder.EmailNotificationBuilder.EmailTemplate.TEMPLATES_FOR_ACTION_SUPPORT_TICKET;
import static org.apache.commons.lang3.StringUtils.isBlank;

import io.gravitee.common.data.domain.Page;
import io.gravitee.repository.exceptions.TechnicalException;
import io.gravitee.repository.management.api.TicketRepository;
import io.gravitee.repository.management.api.search.Order;
import io.gravitee.repository.management.api.search.TicketCriteria;
import io.gravitee.repository.management.api.search.builder.PageableBuilder;
import io.gravitee.repository.management.api.search.builder.SortableBuilder;
import io.gravitee.repository.management.model.Ticket;
import io.gravitee.rest.api.model.*;
import io.gravitee.rest.api.model.api.ApiEntity;
import io.gravitee.rest.api.model.api.TicketQuery;
import io.gravitee.rest.api.model.common.Pageable;
import io.gravitee.rest.api.model.common.Sortable;
import io.gravitee.rest.api.model.parameters.Key;
import io.gravitee.rest.api.model.parameters.ParameterReferenceType;
import io.gravitee.rest.api.service.*;
import io.gravitee.rest.api.service.builder.EmailNotificationBuilder;
import io.gravitee.rest.api.service.common.RandomString;
import io.gravitee.rest.api.service.exceptions.EmailRequiredException;
import io.gravitee.rest.api.service.exceptions.SupportUnavailableException;
import io.gravitee.rest.api.service.exceptions.TechnicalManagementException;
import io.gravitee.rest.api.service.exceptions.TicketNotFoundException;
import io.gravitee.rest.api.service.impl.upgrade.DefaultMetadataUpgrader;
import io.gravitee.rest.api.service.notification.ApiHook;
import io.gravitee.rest.api.service.notification.ApplicationHook;
import io.gravitee.rest.api.service.notification.NotificationParamsBuilder;
import io.gravitee.rest.api.service.notification.PortalHook;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.inject.Inject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @author Azize ELAMRANI (azize at graviteesource.com)
 * @author GraviteeSource Team
 */
@Component
public class TicketServiceImpl extends TransactionalService implements TicketService {

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

    @Inject
    private UserService userService;

    @Inject
    private MetadataService metadataService;

    @Inject
    private ApiService apiService;

    @Inject
    private ApplicationService applicationService;

    @Inject
    private EmailService emailService;

    @Inject
    private ParameterService parameterService;

    @Inject
    private NotifierService notifierService;

    @Inject
    private TicketRepository ticketRepository;

    private boolean isEnabled(String referenceId, ParameterReferenceType referenceType) {
        if (referenceType == ParameterReferenceType.ENVIRONMENT) {
            return parameterService.findAsBoolean(Key.PORTAL_SUPPORT_ENABLED, referenceId, referenceType);
        }
        return parameterService.findAsBoolean(Key.CONSOLE_SUPPORT_ENABLED, referenceId, referenceType);
    }

    @Override
    public TicketEntity create(
        final String userId,
        final NewTicketEntity ticketEntity,
        final String referenceId,
        final ParameterReferenceType referenceType
    ) {
        try {
            if (!isEnabled(referenceId, referenceType)) {
                throw new SupportUnavailableException();
            }
            LOGGER.info("Creating a support ticket: {}", ticketEntity);

            final Map parameters = new HashMap<>();

            final UserEntity user = userService.findById(userId);
            if (user.getEmail() == null) {
                throw new EmailRequiredException(userId);
            }
            parameters.put("user", user);

            final String emailTo;
            final ApiModelEntity api;
            final ApplicationEntity applicationEntity;
            if (ticketEntity.getApi() == null || ticketEntity.getApi().isEmpty()) {
                api = null;
                final MetadataEntity emailMetadata = metadataService.findDefaultByKey(DefaultMetadataUpgrader.METADATA_EMAIL_SUPPORT_KEY);
                if (emailMetadata == null) {
                    throw new IllegalStateException("The support email metadata has not been found");
                }
                emailTo = emailMetadata.getValue();
            } else {
                api = apiService.findByIdForTemplates(ticketEntity.getApi(), true);
                final String apiMetadataEmailSupport = api.getMetadata().get(DefaultMetadataUpgrader.METADATA_EMAIL_SUPPORT_KEY);
                if (apiMetadataEmailSupport == null) {
                    throw new IllegalStateException("The support email API metadata has not been found");
                }
                emailTo = apiMetadataEmailSupport;
                parameters.put("api", api);
            }

            if (DefaultMetadataUpgrader.DEFAULT_METADATA_EMAIL_SUPPORT.equals(emailTo)) {
                throw new IllegalStateException("The support email API metadata has not been changed");
            }

            if (ticketEntity.getApplication() != null && !ticketEntity.getApplication().isEmpty()) {
                applicationEntity = applicationService.findById(ticketEntity.getApplication());
                parameters.put("application", applicationEntity);
            } else {
                applicationEntity = null;
            }

            parameters.put("content", ticketEntity.getContent().replaceAll("(\r\n|\n)", "
")); parameters.put("ticketSubject", ticketEntity.getSubject()); final String fromName = user.getFirstname() == null ? user.getEmail() : user.getFirstname() + ' ' + user.getLastname(); emailService.sendEmailNotification( new EmailNotificationBuilder() .replyTo(user.getEmail()) .fromName(fromName) .to(emailTo) .copyToSender(ticketEntity.isCopyToSender()) .template(TEMPLATES_FOR_ACTION_SUPPORT_TICKET) .params(parameters) .build() ); sendUserNotification(user, api, applicationEntity); Ticket ticket = convert(ticketEntity); ticket.setId(RandomString.generate()); ticket.setCreatedAt(new Date()); ticket.setFromUser(userId); Ticket createdTicket = ticketRepository.create(ticket); return convert(createdTicket); } catch (TechnicalException ex) { LOGGER.error("An error occurs while trying to create a ticket {}", ticketEntity, ex); throw new TechnicalManagementException("An error occurs while trying to create a ticket " + ticketEntity, ex); } } @Override public Page search(TicketQuery query, Sortable sortable, Pageable pageable) { try { LOGGER.debug("search tickets"); TicketCriteria criteria = queryToCriteriaBuilder(query).build(); Page tickets = ticketRepository.search( criteria, buildSortable(sortable), new PageableBuilder().pageNumber(pageable.getPageNumber() - 1).pageSize(pageable.getPageSize()).build() ); List entities = tickets .getContent() .stream() .map(this::getApiNameAndApplicationName) .map(this::convert) .collect(Collectors.toList()); LOGGER.debug("search tickets - Done with {} elements", entities.size()); return new Page<>(entities, tickets.getPageNumber() + 1, (int) tickets.getPageElements(), tickets.getTotalElements()); } catch (TechnicalException ex) { LOGGER.error("An error occurs while trying to search tickets", ex); throw new TechnicalManagementException("An error occurs while trying to search tickets", ex); } } @Override public TicketEntity findById(String ticketId) { try { return ticketRepository .findById(ticketId) .map(this::getApiNameAndApplicationName) .map(this::convert) .orElseThrow(() -> new TicketNotFoundException(ticketId)); } catch (TechnicalException ex) { LOGGER.error("An error occurs while trying to search ticket {}", ticketId, ex); throw new TechnicalManagementException("An error occurs while trying to search ticket " + ticketId, ex); } } private void sendUserNotification(final UserEntity user, final ApiModelEntity api, final ApplicationEntity application) { notifierService.trigger( PortalHook.NEW_SUPPORT_TICKET, new NotificationParamsBuilder().user(user).api(api).application(application).build() ); if (api != null) { notifierService.trigger( ApiHook.NEW_SUPPORT_TICKET, api.getId(), new NotificationParamsBuilder().user(user).api(api).application(application).build() ); } if (application != null) { notifierService.trigger( ApplicationHook.NEW_SUPPORT_TICKET, application.getId(), new NotificationParamsBuilder().user(user).api(api).application(application).build() ); } } private TicketEntity convert(Ticket ticket) { if (ticket == null) { return null; } TicketEntity ticketEntity = new TicketEntity(); ticketEntity.setId(ticket.getId()); ticketEntity.setApi(ticket.getApi()); ticketEntity.setApplication(ticket.getApplication()); ticketEntity.setSubject(ticket.getSubject()); ticketEntity.setContent(ticket.getContent()); ticketEntity.setCreatedAt(ticket.getCreatedAt()); ticketEntity.setFromUser(ticket.getFromUser()); return ticketEntity; } private Ticket convert(NewTicketEntity ticketEntity) { if (ticketEntity == null) { return null; } Ticket ticket = new Ticket(); ticket.setApi(ticketEntity.getApi()); ticket.setApplication(ticketEntity.getApplication()); ticket.setSubject(ticketEntity.getSubject()); ticket.setContent(ticketEntity.getContent()); return ticket; } private Ticket getApiNameAndApplicationName(Ticket ticket) { //Retrieve application name if (StringUtils.isNotEmpty(ticket.getApplication())) { ApplicationEntity application = applicationService.findById(ticket.getApplication()); ticket.setApplication(application.getName()); } //Retrieve api name if (StringUtils.isNotEmpty(ticket.getApi())) { ApiEntity api = apiService.findById(ticket.getApi()); ticket.setApi(api.getName()); } return ticket; } private TicketCriteria.Builder queryToCriteriaBuilder(TicketQuery query) { final TicketCriteria.Builder builder = new TicketCriteria.Builder().fromUser(query.getFromUser()); if (query == null) { return builder; } if (!isBlank(query.getApi())) { builder.api(query.getApi()); } if (!isBlank(query.getApplication())) { builder.application(query.getApplication()); } return builder; } private io.gravitee.repository.management.api.search.Sortable buildSortable(Sortable sortable) { if (sortable == null) { return null; } return new SortableBuilder().field(sortable.getField()).order(sortable.isAscOrder() ? Order.ASC : Order.DESC).build(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy