org.wso2.carbon.la.core.impl.LogsController.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.la.core.impl.LogsController.java

Source

/*
 * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you 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 org.wso2.carbon.la.core.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
import org.wso2.carbon.analytics.datasource.commons.AnalyticsSchema;
import org.wso2.carbon.analytics.datasource.commons.ColumnDefinition;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.databridge.commons.Event;
import org.wso2.carbon.event.stream.core.EventStreamService;
import org.wso2.carbon.la.commons.constants.LAConstants;
import org.wso2.carbon.la.commons.domain.LogGroup;
import org.wso2.carbon.la.commons.domain.LogStream;
import org.wso2.carbon.la.core.exceptions.LogsControllerException;
import org.wso2.carbon.la.core.utils.LACoreServiceValueHolder;
import org.wso2.carbon.la.database.DatabaseService;
import org.wso2.carbon.la.database.exceptions.DatabaseHandlerException;

import java.util.*;

public class LogsController {

    private static final Log log = LogFactory.getLog(LogsController.class);

    private DatabaseService databaseService;

    public LogsController() {
        databaseService = LACoreServiceValueHolder.getInstance().getDatabaseService();

    }

    public int createLogGroup(LogGroup logGroup) throws LogsControllerException {
        try {
            return databaseService.createLogGroup(logGroup);
        } catch (DatabaseHandlerException e) {
            throw new LogsControllerException(e.getMessage(), e);
        }
    }

    public void deleteLogGroup(String name, int tenantId, String username) throws LogsControllerException {
        try {
            databaseService.deleteLogGroup(name, tenantId, username);
            if (log.isDebugEnabled()) {
                log.debug("Log Group deleted : " + name);
            }
        } catch (DatabaseHandlerException e) {
            throw new LogsControllerException(e.getMessage(), e);
        }
    }

    public List<String> getAllLogGroupNames(int tenantId, String username) throws LogsControllerException {
        try {
            List<String> logGroupList = databaseService.getAllLogGroupNames(tenantId, username);
            return logGroupList;
        } catch (DatabaseHandlerException e) {
            throw new LogsControllerException(e.getMessage(), e);
        }
    }

    public void createLogStream(LogStream logStream) throws LogsControllerException {
        try {
            databaseService.createLogStream(logStream);
            if (log.isDebugEnabled()) {
                log.debug("Log Stream created : " + logStream.getName());
            }
        } catch (DatabaseHandlerException e) {
            throw new LogsControllerException(e.getMessage(), e);
        }
    }

    public void deleteLogStream(String name, int logGroupId) throws LogsControllerException {
        try {
            databaseService.deleteLogStream(name, logGroupId);
            if (log.isDebugEnabled()) {
                log.debug("Log stream deleted : " + name + " log groupId : " + logGroupId);
            }
        } catch (DatabaseHandlerException e) {
            throw new LogsControllerException(e.getMessage(), e);
        }
    }

    public List<String> getAllLogStreamNames(int logGroupId) throws LogsControllerException {
        try {
            List<String> logStreamList = databaseService.getAllLogStreamNamesOfLogGroup(logGroupId);
            return logStreamList;
        } catch (DatabaseHandlerException e) {
            throw new LogsControllerException(e.getMessage(), e);
        }
    }

    public List<String> getStreamMetaData(String logStream, int tenantId, String username)
            throws LogsControllerException {
        try {
            List<String> logStreamList = databaseService.getStreamMetaData(logStream, tenantId, username);
            return logStreamList;
        } catch (DatabaseHandlerException e) {
            throw new LogsControllerException(e.getMessage(), e);
        }
    }

    /**
     * @param rawEvent
     * @param tenantId
     * @param username
     * @throws LogsControllerException
     */
    public void publishLogEvent(Map<String, Object> rawEvent, int tenantId, String username)
            throws LogsControllerException {

        if (!rawEvent.containsKey(LAConstants.LOG_STREAM)) {
            if (log.isDebugEnabled()) {
                log.debug("logstream doesn't exist in the event, hence publishing to default stream");
            }
            rawEvent.put(LAConstants.LOG_STREAM, LAConstants.DEFAULT_STREAM);
        }
        long timestamp = extractTimeStamp(rawEvent);

        String logStreamId = (String) rawEvent.get(LAConstants.LOG_STREAM);
        rawEvent.remove(LAConstants.LOG_STREAM);
        rawEvent.remove(LAConstants.LOG_TIMESTAMP);
        rawEvent.remove(LAConstants.LOG_TIMESTAMP_LONG);

        //TODO: add tags support
        Map<String, String> filteredEvent = getStringStringMap(rawEvent);
        Map<String, ColumnDefinition> newArbitraryColumns = getNewArbitraryFields(filteredEvent, username);
        //Update table schema and Stream metadata if new fields are present in the event
        if (newArbitraryColumns.size() > 0) {
            updateSchema(newArbitraryColumns, username);
            updateLogStreamMetadata(logStreamId, newArbitraryColumns.keySet(), tenantId, username);
        }

        EventStreamService eventStreamService = LACoreServiceValueHolder.getInstance().getEventStreamService();
        if (eventStreamService != null) {
            Event logEvent = new Event();
            logEvent.setTimeStamp(System.currentTimeMillis());
            logEvent.setStreamId(LAConstants.LOG_ANALYZER_STREAM_ID);
            logEvent.setTimeStamp(timestamp);
            logEvent.setPayloadData(new Object[] { logStreamId });
            logEvent.setArbitraryDataMap(filteredEvent);
            eventStreamService.publish(logEvent);
            if (log.isDebugEnabled()) {
                log.debug("Successfully published event " + logEvent.toString());
            }
        }
    }

    private Long extractTimeStamp(Map<String, Object> rawEvent) throws LogsControllerException {
        long logTimeStamp = 0;
        if (rawEvent.containsKey(LAConstants.LOG_TIMESTAMP)) {
            String timeStamp = (String) rawEvent.get(LAConstants.LOG_TIMESTAMP);
            try {
                DateTime dateTime = new DateTime(timeStamp);
                logTimeStamp = dateTime.getMillis();
            } catch (IllegalArgumentException e) {
                throw new LogsControllerException(
                        "Invalid timestamp format : " + timeStamp + "user ISO8601 standard compatible timestamp",
                        e);
            }
        } else if (rawEvent.containsKey(LAConstants.LOG_TIMESTAMP_LONG)) {
            try {
                logTimeStamp = (long) rawEvent.get(LAConstants.LOG_TIMESTAMP_LONG);
            } catch (ClassCastException e) {
                throw new LogsControllerException(
                        "Class cast exception occurred while converting LOG_TIMESTAMP_LONG", e);
            }
        } else {
            logTimeStamp = System.currentTimeMillis();
        }
        return logTimeStamp;
    }

    private void updateLogStreamMetadata(String logStreamId, Set<String> strings, int tenantId, String username)
            throws LogsControllerException {
        try {
            if (databaseService.isStreamExists(logStreamId, tenantId, username)) {
                databaseService.updateLogStreamMetadata(logStreamId, strings, tenantId, username);
            } else {
                databaseService.insertLogStreamMetadata(logStreamId, strings, tenantId, username);
            }
        } catch (DatabaseHandlerException e) {
            throw new LogsControllerException(e.getMessage(), e);
        }
    }

    private Map<String, String> getStringStringMap(Map<String, Object> rawEvent) throws LogsControllerException {
        Map<String, String> filteredEvent = new HashMap<>();
        for (Map.Entry<String, Object> entry : rawEvent.entrySet()) {
            try {
                filteredEvent.put(entry.getKey(), entry.getValue().toString());
            } catch (ClassCastException e) {
                throw new LogsControllerException("Unsupported datatype present in the log event" + e.getMessage(),
                        e);
            }
        }
        return filteredEvent;
    }

    /**
     * Update the stream schema upon new fields
     *
     * @param newArbitraryColumns
     * @param username
     * @throws LogsControllerException
     */
    private void updateSchema(Map<String, ColumnDefinition> newArbitraryColumns, String username)
            throws LogsControllerException {
        AnalyticsDataAPI analyticsDataAPIService = LACoreServiceValueHolder.getInstance().getAnalyticsDataAPI();
        AnalyticsSchema analyticsSchema;
        try {
            analyticsSchema = analyticsDataAPIService.getTableSchema(username,
                    LAConstants.LOG_ANALYZER_STREAM_NAME);
            Map<String, ColumnDefinition> previousColumns = analyticsSchema.getColumns();
            previousColumns.putAll(newArbitraryColumns);

            AnalyticsSchema updatedAnalyticsSchema = new AnalyticsSchema(new ArrayList(previousColumns.values()),
                    null);
            analyticsDataAPIService.setTableSchema(username, LAConstants.LOG_ANALYZER_STREAM_NAME,
                    updatedAnalyticsSchema);
            if (log.isDebugEnabled()) {
                log.debug("Log Analyzer schema updated successfully");
            }
        } catch (AnalyticsException e) {
            throw new LogsControllerException("Error occurred while updating loganalyzer schema " + e.getMessage(),
                    e);
        }
    }

    /**
     * get the new arbitrary fields present in the stream
     *
     * @param rawEvent
     * @param username
     * @return
     * @throws LogsControllerException
     */
    private Map<String, ColumnDefinition> getNewArbitraryFields(Map<String, String> rawEvent, String username)
            throws LogsControllerException {
        Map<String, ColumnDefinition> newColumns = new HashMap<>();
        AnalyticsDataAPI analyticsDataAPIService = LACoreServiceValueHolder.getInstance().getAnalyticsDataAPI();
        try {
            AnalyticsSchema analyticsSchema = analyticsDataAPIService.getTableSchema(username,
                    LAConstants.LOG_ANALYZER_STREAM_NAME);
            Map<String, ColumnDefinition> columns = analyticsSchema.getColumns();
            for (String arbitraryKey : rawEvent.keySet()) {
                String columnName = LAConstants.ARBITRARY_FIELD_PREFIX + arbitraryKey;
                // _timestam is a reserved field in DAS, we need to omit that colum nname
                if (!columns.containsKey(columnName)
                        && !LAConstants.DAS_TIMESTAMP_FIELD.equalsIgnoreCase(columnName)) {
                    newColumns.put(columnName,
                            new ColumnDefinition(columnName, AnalyticsSchema.ColumnType.STRING, true, false));
                }
            }
        } catch (AnalyticsException e) {
            throw new LogsControllerException(
                    "Error occurred while getting new arbitrary fields of the event " + e.getMessage(), e);
        }
        return newColumns;
    }
}