/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.monitoring.internal.messaging;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.BaseMessageListener;
import com.liferay.portal.kernel.messaging.Destination;
import com.liferay.portal.kernel.messaging.DestinationNames;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageListener;
import com.liferay.portal.kernel.monitoring.DataSample;
import com.liferay.portal.kernel.monitoring.DataSampleProcessor;
import com.liferay.portal.kernel.monitoring.Level;
import com.liferay.portal.kernel.monitoring.MonitoringControl;
import com.liferay.portal.kernel.monitoring.MonitoringException;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
/**
* @author Michael C. Han
* @author Brian Wing Shun Chan
*/
@Component(
enabled = false, immediate = true,
property = {"destination.name=" + DestinationNames.MONITORING},
service = {MessageListener.class, MonitoringControl.class}
)
public class MonitoringMessageListener
extends BaseMessageListener implements MonitoringControl {
@Override
public Level getLevel(String namespace) {
Level level = _levels.get(namespace);
if (level == null) {
return Level.OFF;
}
return level;
}
@Override
public Set<String> getNamespaces() {
return _levels.keySet();
}
public void processDataSample(DataSample dataSample)
throws MonitoringException {
String namespace = dataSample.getNamespace();
Level level = _levels.get(namespace);
if ((level != null) && level.equals(Level.OFF)) {
return;
}
List<DataSampleProcessor<DataSample>> dataSampleProcessors =
_dataSampleProcessors.get(namespace);
if ((dataSampleProcessors == null) || dataSampleProcessors.isEmpty()) {
return;
}
for (DataSampleProcessor<DataSample> dataSampleProcessor :
dataSampleProcessors) {
dataSampleProcessor.processDataSample(dataSample);
}
}
@Override
public void setLevel(String namespace, Level level) {
_levels.put(namespace, level);
}
public void setLevels(Map<String, String> levels) {
for (Map.Entry<String, String> entry : levels.entrySet()) {
String namespace = entry.getKey();
String levelName = entry.getValue();
Level level = Level.valueOf(levelName);
_levels.put(namespace, level);
}
}
@Override
@SuppressWarnings("unchecked")
protected void doReceive(Message message) throws Exception {
List<DataSample> dataSamples = (List<DataSample>)message.getPayload();
if (ListUtil.isNotEmpty(dataSamples)) {
for (DataSample dataSample : dataSamples) {
processDataSample(dataSample);
}
}
}
@Reference(
cardinality = ReferenceCardinality.MULTIPLE,
policy = ReferencePolicy.DYNAMIC,
policyOption = ReferencePolicyOption.GREEDY,
unbind = "unregisterDataSampleProcessor"
)
protected synchronized void registerDataSampleProcessor(
DataSampleProcessor<DataSample> dataSampleProcessor,
Map<String, Object> properties) {
String namespace = (String)properties.get("namespace");
if (Validator.isNull(namespace)) {
if (_log.isWarnEnabled()) {
_log.warn(
"No namespace defined for service " +
dataSampleProcessor.getClass());
}
return;
}
List<DataSampleProcessor<DataSample>> dataSampleProcessors =
_dataSampleProcessors.get(namespace);
if (dataSampleProcessors == null) {
dataSampleProcessors = new ArrayList<>();
_dataSampleProcessors.put(namespace, dataSampleProcessors);
}
dataSampleProcessors.add(dataSampleProcessor);
}
@Reference(
target = "(destination.name=" + DestinationNames.MONITORING + ")",
unbind = "-"
)
protected void setDestination(Destination destination) {
}
protected synchronized void unregisterDataSampleProcessor(
DataSampleProcessor<DataSample> dataSampleProcessor,
Map<String, Object> properties) {
String namespace = (String)properties.get("namespace");
if (Validator.isNull(namespace)) {
if (_log.isWarnEnabled()) {
_log.warn(
"No namespace defined for service " +
dataSampleProcessor.getClass());
}
return;
}
List<DataSampleProcessor<DataSample>> dataSampleProcessors =
_dataSampleProcessors.get(namespace);
if (dataSampleProcessors != null) {
dataSampleProcessors.remove(dataSampleProcessor);
}
}
private static final Log _log = LogFactoryUtil.getLog(
MonitoringMessageListener.class);
private final Map<String, List<DataSampleProcessor<DataSample>>>
_dataSampleProcessors = new ConcurrentHashMap<>();
private final Map<String, Level> _levels = new ConcurrentHashMap<>();
}