/** * Helios, OpenSource Monitoring * Brought to you by the Helios Development Group * * Copyright 2012, Helios Development Group and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This 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 software 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. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.helios.apmrouter.subscription.impls.jmx; import java.util.HashSet; import java.util.Set; import javax.management.NotificationFilter; import javax.management.NotificationFilterSupport; import javax.management.ObjectName; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import org.helios.apmrouter.dataservice.json.JsonRequest; import org.helios.apmrouter.jmx.JMXHelper; import org.helios.apmrouter.subscription.criteria.SubscriptionCriteria; import org.helios.apmrouter.subscription.criteria.builder.AbstractSubscriptionCriteriaBuilder; import org.json.JSONArray; import org.json.JSONException; /** * <p>Title: JMXSubscriptionCriteriaBuilder</p> * <p>Description: A subscription criteria builder for JMX</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.subscription.impls.jmx.JMXSubscriptionCriteriaBuilder</code></p> */ public class JMXSubscriptionCriteriaBuilder extends AbstractSubscriptionCriteriaBuilder<String, ObjectName, NotificationFilter> { /** The script engine manager for compiling notification filters */ protected static final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); /** The script engine for compiling notification filters */ protected static final ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript"); /** * {@inheritDoc} * @see org.helios.apmrouter.subscription.criteria.builder.SubscriptionCriteriaBuilder#build(org.helios.apmrouter.dataservice.json.JsonRequest) */ @Override public SubscriptionCriteria<String, ObjectName, NotificationFilter> build(JsonRequest subRequest) { String eventSource = subRequest.getArgument(JSON_EVENT_SOURCE, ""); // e.g. "jmx" if(eventSource.isEmpty()) throw new RuntimeException("No event source type provided", new Throwable()); String eventSourceName = subRequest.getArgument(JSON_EVENT_SOURCE_NAME, ""); // e.g. "service:jmx:local://DefaultDomain" if(eventSource.isEmpty()) throw new RuntimeException("No event source name provided", new Throwable()); ObjectName objectName = JMXHelper.objectName(subRequest.getArgument(JSON_EVENT_FILTER, "")); String filterExpression = subRequest.getArgumentOrNull(JSON_EXTENDED_EVENT_FILTER, String.class); JSONArray simpleFilterExpression = subRequest.getArgumentOrNull(JSON_SIMPLE_TYPE_FILTER, JSONArray.class); NotificationFilter filter = null; Set<String> enabledTypes = new HashSet<String>(); if(simpleFilterExpression!=null) { filter = new NotificationFilterSupport(); for(int i = 0; i < simpleFilterExpression.length(); i++) { try { ((NotificationFilterSupport)filter).enableType(simpleFilterExpression.getString(i).trim()); enabledTypes.add(simpleFilterExpression.getString(i).trim()); } catch (IllegalArgumentException iex) { throw new RuntimeException("Failed to parse simple filter expression", iex); } catch (JSONException jex) { throw new RuntimeException("Failed to parse simple filter expression", jex); } } } else if(filterExpression!=null && !filterExpression.trim().isEmpty()) { filter = compileFilter(filterExpression); } JMXSubscriptionCriteria criteria = new JMXSubscriptionCriteria(this, eventSourceName, objectName, filter); if(!enabledTypes.isEmpty()) { criteria.setSubcriptionKey(enabledTypes.toArray(new String[enabledTypes.size()])); } return criteria; } /** * Compiles the filter expression into a NotificationFilter * @param filterExpression the supplied expression * @return a NotificationFilter */ protected NotificationFilter compileFilter(String filterExpression) { try { scriptEngine.eval(filterExpression); Invocable inv = (Invocable)scriptEngine; return inv.getInterface(NotificationFilter.class); } catch (Exception ex) { throw new RuntimeException("Failed to compile filter [" + filterExpression + "]", ex); } } }