edu.usu.sdl.openstorefront.service.SystemServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for edu.usu.sdl.openstorefront.service.SystemServiceImpl.java

Source

/*
 * Copyright 2014 Space Dynamics Laboratory - Utah State University Research Foundation.
 *
 * 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 edu.usu.sdl.openstorefront.service;

import edu.usu.sdl.openstorefront.common.exception.OpenStorefrontRuntimeException;
import edu.usu.sdl.openstorefront.common.manager.FileSystemManager;
import edu.usu.sdl.openstorefront.common.manager.PropertiesManager;
import edu.usu.sdl.openstorefront.common.util.OpenStorefrontConstant;
import edu.usu.sdl.openstorefront.common.util.StringProcessor;
import edu.usu.sdl.openstorefront.common.util.TimeUtil;
import edu.usu.sdl.openstorefront.core.api.SystemService;
import edu.usu.sdl.openstorefront.core.api.model.TaskFuture;
import edu.usu.sdl.openstorefront.core.entity.AlertType;
import edu.usu.sdl.openstorefront.core.entity.ApplicationProperty;
import edu.usu.sdl.openstorefront.core.entity.AsyncTask;
import edu.usu.sdl.openstorefront.core.entity.ComponentIntegration;
import edu.usu.sdl.openstorefront.core.entity.DBLogRecord;
import edu.usu.sdl.openstorefront.core.entity.ErrorTicket;
import edu.usu.sdl.openstorefront.core.entity.GeneralMedia;
import edu.usu.sdl.openstorefront.core.entity.HelpSection;
import edu.usu.sdl.openstorefront.core.entity.Highlight;
import edu.usu.sdl.openstorefront.core.model.AlertContext;
import edu.usu.sdl.openstorefront.core.model.ErrorInfo;
import edu.usu.sdl.openstorefront.core.model.HelpSectionAll;
import edu.usu.sdl.openstorefront.core.view.GlobalIntegrationModel;
import edu.usu.sdl.openstorefront.core.view.SystemErrorModel;
import edu.usu.sdl.openstorefront.security.SecurityUtil;
import edu.usu.sdl.openstorefront.service.manager.DBLogManager;
import edu.usu.sdl.openstorefront.service.manager.JobManager;
import edu.usu.sdl.openstorefront.validation.ValidationModel;
import edu.usu.sdl.openstorefront.validation.ValidationResult;
import edu.usu.sdl.openstorefront.validation.ValidationUtil;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;

/**
 * Handles System related entities
 *
 * @author dshurtleff
 */
@SuppressWarnings("ClassWithMultipleLoggers")
public class SystemServiceImpl extends ServiceProxy implements SystemService {

    private static final Logger log = Logger.getLogger(SystemServiceImpl.class.getName());
    private static final Logger errorLog = Logger.getLogger(OpenStorefrontConstant.ERROR_LOGGER);

    private static final int MAX_DB_CLEAN_AMOUNT = 1000;
    private static final int MIN_DB_CLEAN_AMOUNT = 1000;

    @Override
    public ApplicationProperty getProperty(String key) {
        ApplicationProperty applicationProperty = persistenceService.findById(ApplicationProperty.class, key);
        return applicationProperty;
    }

    @Override
    public String getPropertyValue(String key) {
        ApplicationProperty property = getProperty(key);
        if (property != null) {
            return property.getValue();
        }
        return null;
    }

    @Override
    public void saveProperty(String key, String value) {
        if (StringUtils.isBlank(value)) {
            //remove existing
            ApplicationProperty existingProperty = persistenceService.findById(ApplicationProperty.class, key);
            if (existingProperty != null) {
                persistenceService.delete(existingProperty);
            }
        } else {
            ApplicationProperty existingProperty = persistenceService.findById(ApplicationProperty.class, key);
            if (existingProperty != null) {
                existingProperty.setValue(value);
                existingProperty.setUpdateDts(TimeUtil.currentDate());
                existingProperty.setUpdateUser(OpenStorefrontConstant.SYSTEM_USER);
                persistenceService.persist(existingProperty);
            } else {
                ApplicationProperty property = new ApplicationProperty();
                property.setKey(key);
                property.setValue(value);
                property.setActiveStatus(ApplicationProperty.ACTIVE_STATUS);
                property.setCreateDts(TimeUtil.currentDate());
                property.setUpdateDts(TimeUtil.currentDate());
                property.setCreateUser(OpenStorefrontConstant.SYSTEM_USER);
                property.setUpdateUser(OpenStorefrontConstant.SYSTEM_USER);
                persistenceService.persist(property);
            }
        }
    }

    @Override
    public void saveHightlight(List<Highlight> highlights) {
        for (Highlight hightlight : highlights) {
            saveHightlight(hightlight);
        }
    }

    @Override
    public void saveHightlight(Highlight highlight) {
        Highlight existing = null;
        if (StringUtils.isNotBlank(highlight.getHighlightId())) {
            existing = persistenceService.findById(Highlight.class, highlight.getHighlightId());
        }
        if (existing != null) {
            existing.updateFields(highlight);
            persistenceService.persist(existing);
        } else {
            highlight.setHighlightId(persistenceService.generateId());
            highlight.populateBaseCreateFields();
            persistenceService.persist(highlight);
        }
    }

    @Override
    public void removeHighlight(String hightlightId) {
        Highlight highlight = persistenceService.findById(Highlight.class, hightlightId);
        if (highlight != null) {
            highlight.setActiveStatus(Highlight.INACTIVE_STATUS);
            highlight.setUpdateUser(SecurityUtil.getCurrentUserName());
            highlight.setUpdateDts(TimeUtil.currentDate());
            persistenceService.persist(highlight);
        }
    }

    @Override
    public void deleteHighlight(String hightlightId) {
        Highlight highlight = persistenceService.findById(Highlight.class, hightlightId);
        if (highlight != null) {
            persistenceService.delete(highlight);
        }
    }

    @Override
    public void activateHighlight(String hightlightId) {
        Highlight highlight = persistenceService.findById(Highlight.class, hightlightId);
        if (highlight != null) {
            highlight.setActiveStatus(Highlight.ACTIVE_STATUS);
            highlight.setUpdateUser(SecurityUtil.getCurrentUserName());
            highlight.setUpdateDts(TimeUtil.currentDate());
            persistenceService.persist(highlight);
        }
    }

    @Override
    public void syncHighlights(List<Highlight> highlights) {
        int removeCount = persistenceService.deleteByExample(new Highlight());
        log.log(Level.FINE, MessageFormat.format("Old Highlights removed: {0}", removeCount));

        for (Highlight highlight : highlights) {
            try {
                ValidationModel validationModel = new ValidationModel(highlight);
                validationModel.setConsumeFieldsOnly(true);
                ValidationResult validationResult = ValidationUtil.validate(validationModel);
                if (validationResult.valid()) {
                    highlight.setCreateUser(OpenStorefrontConstant.SYSTEM_ADMIN_USER);
                    highlight.setUpdateUser(OpenStorefrontConstant.SYSTEM_ADMIN_USER);
                    getSystemService().saveHightlight(highlight);
                }

            } catch (Exception e) {
                log.log(Level.SEVERE, "Unable to save highlight.  Title: " + highlight.getTitle(), e);
            }
        }
    }

    @Override
    public SystemErrorModel generateErrorTicket(ErrorInfo errorInfo) {
        Objects.requireNonNull(errorInfo);

        errorLog.log(Level.SEVERE, "System Error Occured", errorInfo.getError());

        SystemErrorModel systemErrorModel = new SystemErrorModel();
        systemErrorModel.setMessage(errorInfo.getError().getMessage());
        if (errorInfo.getError() instanceof OpenStorefrontRuntimeException) {
            OpenStorefrontRuntimeException openStorefrontRuntimeException = (OpenStorefrontRuntimeException) errorInfo
                    .getError();
            systemErrorModel.setPotentialResolution(openStorefrontRuntimeException.getPotentialResolution());
            errorInfo.setErrorTypeCode(openStorefrontRuntimeException.getErrorTypeCode());
        }
        try {

            String ticketNumber = persistenceService.generateId();
            StringBuilder ticket = new StringBuilder();
            ticket.append("TicketNumber: ").append(ticketNumber).append("\n");
            ticket.append("Client IP: ").append(errorInfo.getClientIp()).append("\n");
            ticket.append("User: ").append(SecurityUtil.getCurrentUserName()).append("\n");
            ticket.append("Message: ").append(systemErrorModel.getMessage()).append("\n");
            ticket.append("Potential Resolution: ")
                    .append(StringProcessor.blankIfNull(systemErrorModel.getPotentialResolution())).append("\n");
            ticket.append("Request: ").append(errorInfo.getRequestUrl()).append("\n");
            ticket.append("Request Method: ").append(errorInfo.getRequestMethod()).append("\n");
            ticket.append("Input Data: \n").append(errorInfo.getInputData()).append("\n\n");
            ticket.append("StackTrace: ").append("\n\n");

            StringWriter stringWriter = new StringWriter();
            PrintWriter printWriter = new PrintWriter(stringWriter);
            errorInfo.getError().printStackTrace(printWriter);
            ticket.append(stringWriter.toString());

            systemErrorModel.setErrorTicketNumber(ticketNumber);
            ErrorTicket errorTicket = new ErrorTicket();
            errorTicket.setErrorTicketId(ticketNumber);
            errorTicket.setTicketFile(ticketNumber);
            errorTicket.setClientIp(errorInfo.getClientIp());
            errorTicket.setMessage(systemErrorModel.getMessage());
            errorTicket.setPotentialResolution(systemErrorModel.getPotentialResolution());
            if (StringUtils.isNotBlank(errorInfo.getRequestUrl())) {
                errorTicket.setCalledAction(errorInfo.getRequestUrl() + " Method: " + errorInfo.getRequestMethod());
            }
            errorTicket.setErrorTypeCode(errorInfo.getErrorTypeCode());
            errorTicket.setInput(errorInfo.getInputData());
            errorTicket.setActiveStatus(ErrorTicket.ACTIVE_STATUS);
            errorTicket.setCreateDts(TimeUtil.currentDate());
            errorTicket.setUpdateDts(TimeUtil.currentDate());
            errorTicket.setCreateUser(SecurityUtil.getCurrentUserName());
            errorTicket.setUpdateUser(SecurityUtil.getCurrentUserName());
            persistenceService.persist(errorTicket);

            //save file
            Path path = Paths.get(FileSystemManager.getDir(FileSystemManager.ERROR_TICKET_DIR).getPath() + "/"
                    + errorTicket.getTicketFile());
            Files.write(path, ticket.toString().getBytes(Charset.defaultCharset()));

            AlertContext alertContext = new AlertContext();
            alertContext.setAlertType(AlertType.SYSTEM_ERROR);
            alertContext.setDataTrigger(errorTicket);
            getAlertService().checkAlert(alertContext);

        } catch (Throwable t) {
            //NOTE: this is a critial path.  if an error is thrown and not catch it would result in a info link or potential loop.
            //So that's why there is a catch all here.
            log.log(Level.SEVERE, "Error was thrown while processing the error", t);
        }
        return systemErrorModel;
    }

    @Override
    public String errorTicketInfo(String errorTicketId) {
        String ticketData = null;
        ErrorTicket errorTicket = persistenceService.findById(ErrorTicket.class, errorTicketId);
        if (errorTicket != null) {
            Path path = Paths.get(FileSystemManager.getDir(FileSystemManager.ERROR_TICKET_DIR).getPath() + "/"
                    + errorTicket.getTicketFile());
            try {
                byte data[] = Files.readAllBytes(path);
                ticketData = new String(data);
            } catch (IOException io) {
                //We don't want to throw an error here if there something going on with the system.
                ticketData = "Unable to retrieve ticket information.  (Check log for more details) Message: "
                        + io.getMessage();
                log.log(Level.WARNING, ticketData, io);
            }
        }
        return ticketData;
    }

    @Override
    public void cleanupOldErrors() {
        long count = persistenceService.countClass(ErrorTicket.class);
        long max = Long.parseLong(PropertiesManager.getValue(PropertiesManager.KEY_MAX_ERROR_TICKETS,
                OpenStorefrontConstant.ERRORS_MAX_COUNT_DEFAULT));

        if (count > max) {

            //query ticket
            long limit = count - max;
            String query = "SELECT FROM ErrorTicket ORDER BY updateDts ASC LIMIT " + limit;
            List<ErrorTicket> errorTickets = persistenceService.query(query, null);
            errorTickets.stream().forEach((errorTicket) -> {
                Path path = Paths.get(FileSystemManager.getDir(FileSystemManager.ERROR_TICKET_DIR).getPath() + "/"
                        + errorTicket.getTicketFile());
                if (path.toFile().exists()) {
                    path.toFile().delete();
                }
                persistenceService.delete(errorTicket);
            });
        }
    }

    @Override
    public GlobalIntegrationModel getGlobalIntegrationConfig() {
        GlobalIntegrationModel globalIntegrationModel = new GlobalIntegrationModel();

        String refreshTime = getPropertyValue(ApplicationProperty.GLOBAL_INTEGRATION_REFRESH);
        if (refreshTime == null) {
            refreshTime = GlobalIntegrationModel.DEFAULT_REFRESH_RATE;
        }
        globalIntegrationModel.setJiraRefreshRate(refreshTime);

        return globalIntegrationModel;
    }

    @Override
    public void saveGlobalIntegrationConfig(GlobalIntegrationModel globalIntegrationModel) {
        saveProperty(ApplicationProperty.GLOBAL_INTEGRATION_REFRESH, globalIntegrationModel.getJiraRefreshRate());

        List<ComponentIntegration> integrations = getComponentService()
                .getComponentIntegrationModels(ComponentIntegration.ACTIVE_STATUS);
        for (ComponentIntegration integration : integrations) {
            if (StringUtils.isBlank(integration.getRefreshRate())) {
                JobManager.updateComponentIntegrationJob(integration);
            }
        }
    }

    @Override
    public void saveGeneralMedia(GeneralMedia generalMedia, InputStream fileInput) {
        Objects.requireNonNull(generalMedia);
        Objects.requireNonNull(fileInput);
        Objects.requireNonNull(generalMedia.getName(), "Name must be set.");

        generalMedia.setFileName(generalMedia.getName());
        try (InputStream in = fileInput) {
            Files.copy(in, generalMedia.pathToMedia(), StandardCopyOption.REPLACE_EXISTING);
            generalMedia.populateBaseCreateFields();
            persistenceService.persist(generalMedia);
        } catch (IOException ex) {
            throw new OpenStorefrontRuntimeException("Unable to store media file.",
                    "Contact System Admin.  Check file permissions and disk space ", ex);
        }
    }

    @Override
    public void removeGeneralMedia(String mediaName) {
        GeneralMedia generalMedia = persistenceService.findById(GeneralMedia.class, mediaName);
        if (generalMedia != null) {
            Path path = generalMedia.pathToMedia();
            if (path != null) {
                if (path.toFile().exists()) {
                    path.toFile().delete();
                }
            }
            persistenceService.delete(generalMedia);
        }
    }

    @Override
    public void saveAsyncTask(TaskFuture taskFuture) {
        AsyncTask existingTask = persistenceService.findById(AsyncTask.class, taskFuture.getTaskId());
        if (existingTask != null) {
            persistenceService.delete(existingTask);
        }

        AsyncTask asyncTask = new AsyncTask();
        asyncTask.setTaskId(taskFuture.getTaskId());
        asyncTask.setAllowMultiple(taskFuture.isAllowMultiple());
        asyncTask.setCompletedDts(taskFuture.getCompletedDts());
        asyncTask.setError(taskFuture.getError());
        asyncTask.setStatus(taskFuture.getStatus());
        asyncTask.setSubmitedDts(taskFuture.getSubmitedDts());
        asyncTask.setTaskName(taskFuture.getTaskName());
        asyncTask.setDetails(taskFuture.getDetails());

        asyncTask.setCreateUser(taskFuture.getCreateUser());
        asyncTask.setUpdateUser(taskFuture.getCreateUser());
        asyncTask.populateBaseCreateFields();

        persistenceService.persist(asyncTask);

    }

    @Override
    public void removeAsyncTask(String taskId) {
        AsyncTask task = persistenceService.findById(AsyncTask.class, taskId);
        if (task != null) {
            persistenceService.delete(task);
        }
    }

    @Override
    public void addLogRecord(DBLogRecord logRecord) {
        logRecord.setLogId(persistenceService.generateId());
        persistenceService.saveNonBaseEntity(logRecord);
    }

    @Override
    public void cleanUpOldLogRecords() {
        long count = persistenceService.countClass(DBLogRecord.class);
        long max = DBLogManager.getMaxLogEntries();

        if (count > max) {
            log.log(Level.INFO, MessageFormat.format("Cleaning old log records:  {0}", (count - max)));

            long limit = count - max - MIN_DB_CLEAN_AMOUNT;
            if (limit > MAX_DB_CLEAN_AMOUNT) {
                limit = MAX_DB_CLEAN_AMOUNT;
            }
            if (limit < 0) {
                limit = 1;
            }
            String query = "SELECT FROM DBLogRecord ORDER BY eventDts ASC LIMIT " + limit;
            List<DBLogRecord> logRecords = persistenceService.query(query, null);
            logRecords.stream().forEach((record) -> {
                persistenceService.delete(record);
            });
        }
    }

    @Override
    public void clearAllLogRecord() {
        int recordsRemoved = persistenceService.deleteByQuery(DBLogRecord.class, "", new HashMap<>());
        log.log(Level.WARNING,
                MessageFormat.format("DB log records were cleared.  Records cleared: {0}", recordsRemoved));
    }

    @Override
    public void loadNewHelpSections(List<HelpSection> helpSections) {
        Objects.requireNonNull(helpSections, "Help sections required");

        int recordsRemoved = persistenceService.deleteByQuery(HelpSection.class, "", new HashMap<>());
        log.log(Level.FINE,
                MessageFormat.format("Help records were cleared.  Records cleared: {0}", recordsRemoved));

        log.log(Level.FINE, MessageFormat.format("Saving new Help records: {0}", helpSections.size()));
        for (HelpSection helpSection : helpSections) {
            helpSection.setId(persistenceService.generateId());
            persistenceService.persist(helpSection);
        }
    }

    @Override
    public HelpSectionAll getAllHelp(Boolean includeAdmin) {
        HelpSectionAll helpSectionAll = new HelpSectionAll();

        HelpSection helpSectionExample = new HelpSection();
        helpSectionExample.setAdminSection(includeAdmin);

        List<HelpSection> helpSections = persistenceService.queryByExample(HelpSection.class, helpSectionExample);

        if (helpSections.isEmpty() == false) {

            //Root Section
            HelpSection helpSectionRoot = new HelpSection();
            helpSectionRoot.setTitle(PropertiesManager.getValue(PropertiesManager.KEY_APPLICATION_TITLE));
            helpSectionRoot.setContent("<center><h2>User Guide</h2>Version: "
                    + PropertiesManager.getApplicationVersion() + "</center>");
            helpSectionAll.setHelpSection(helpSectionRoot);

            for (HelpSection helpSection : helpSections) {
                String codeTokens[] = helpSection.getSectionNumber().split(Pattern.quote("."));
                HelpSectionAll rootHelp = helpSectionAll;
                StringBuilder codeKey = new StringBuilder();
                for (String codeToken : codeTokens) {
                    codeKey.append(codeToken);
                    //put in stubs as needed
                    boolean found = false;
                    String compare = codeKey.toString();
                    if (codeKey.toString().length() == 1) {
                        compare += ".";
                    }
                    for (HelpSectionAll child : rootHelp.getChildSections()) {
                        if (child.getHelpSection().getSectionNumber().equals(compare)) {
                            found = true;
                            rootHelp = child;
                            break;
                        }
                    }
                    if (!found) {
                        HelpSectionAll newChild = new HelpSectionAll();
                        HelpSection childHelp = new HelpSection();
                        childHelp.setSectionNumber(compare);
                        newChild.setHelpSection(childHelp);
                        rootHelp.getChildSections().add(newChild);
                        rootHelp = newChild;
                    }
                    codeKey.append(".");
                }
                rootHelp.setHelpSection(helpSection);
            }
        }
        //reorder help number so missing sections do cause holes
        reorderHelpSectionTitles(helpSectionAll, "");
        return helpSectionAll;
    }

    private void reorderHelpSectionTitles(HelpSectionAll helpSectionAll, String parentSection) {
        if (helpSectionAll.getChildSections().isEmpty()) {
            return;
        }

        int sectionNumber = 1;
        for (HelpSectionAll helpSection : helpSectionAll.getChildSections()) {
            String titleSplit[] = helpSection.getHelpSection().getTitle().split(" ");
            String titleNumber;
            if (StringUtils.isBlank(parentSection)) {
                titleNumber = sectionNumber + ". ";

            } else {
                titleNumber = parentSection + sectionNumber + " ";
            }

            StringBuilder restOfTitle = new StringBuilder();
            for (int i = 1; i < titleSplit.length; i++) {
                if (restOfTitle.length() != 0) {
                    restOfTitle.append(" ");
                }
                restOfTitle.append(titleSplit[i]);
            }
            helpSection.getHelpSection().setTitle(titleNumber + restOfTitle.toString());

            if (titleNumber.endsWith(". ") == false) {
                StringBuilder temp = new StringBuilder();
                temp.append(titleNumber);
                temp = temp.deleteCharAt(temp.length() - 1);
                temp.append(".");
                titleNumber = temp.toString();
            } else {
                StringBuilder temp = new StringBuilder();
                temp.append(titleNumber);
                temp = temp.deleteCharAt(temp.length() - 1);
                titleNumber = temp.toString();
            }
            reorderHelpSectionTitles(helpSection, titleNumber);

            sectionNumber++;
        }
    }

}