示例#1
0
  public List<Config> getCurrentConfigList() throws ConfigException {

    ConfigReader configReader = null;

    switch (agentConfig.getConfigInitTypeParam()) {
      case CONFIG_BY_EXPLICIT_PARAMS:
        configReader = getConfigViaExplicitParams();
        break;
      case CONFIG_BY_CORE_TYPE_VIA_GALAXY_OUTPUT:
        configReader = getConfigViaGalaxyAndCoreTypeConfig();
        break;
      case CONFIG_BY_DISCOVERY_VIA_GALAXY_OUTPUT:
        configReader = getConfigViaGalaxyAndDiscovery();
        break;
    }

    List<Config> configList = null;

    if (configReader != null) {
      configList = configReader.getConfigurations();
    }

    if (configList != null && configList.size() > 0) {
      return configList;
    } else {
      log.info("No monitoring configurations initialized");
      return null;
    }
  }
示例#2
0
  private void updateEventStream(EventDefinition def) {
    log.info("removing registration for event type %s", def.getEventType());
    notifyEventUnRegistered(def);

    log.info("updating event type stream %s", def.getEventType());
    for (String ns : namespaces) {
      EPAdministrator admin = EsperProvider.getProvider(ns).getEPAdministrator();

      HashMap<String, Object> m = new HashMap<String, Object>();
      for (Map.Entry<String, Class> entry : def.getProperties().entrySet()) {
        m.put(entry.getKey(), entry.getValue());
      }

      admin.getConfiguration().updateMapEventType(def.getEventType(), m);
      inputEventRegistrationsValid.add(def.getEventType());
    }
    notifyEventRegistered(def);
  }
  public SortableConfDataProvider(List<T> dataList, String initialSortId, Class<T> clazz) {

    // pain in the ass to assign a newInstance from a generic type param
    try {
      if (clazz != null) filterObject = clazz.newInstance();
    } catch (Exception ex) {
      log.warn(ex);
      filterObject = null;
    }

    if (dataList == null) dataList = new ArrayList<T>();

    this.dataList = dataList;

    // set default sort
    setSort(initialSortId, true);
  }
示例#4
0
  private boolean logPropertyDifferences(
      String message, SortedMap<String, Class> prevMap, SortedMap<String, Class> newMap) {
    boolean foundDifference = false;
    for (String prevKey : prevMap.keySet()) {

      if (nonVersionSpecificAttributes.contains(prevKey)) continue;

      Class prevClass = prevMap.get(prevKey);
      Class newClass = newMap.get(prevKey);

      if (prevClass != null && prevClass != newClass) {
        if (newClass == null) {
          if (!foundDifference) {
            log.info(message);
            foundDifference = true;
          }
          log.info(
              "\tnew event missing field in prev event: %s = %s",
              prevKey, prevClass.getSimpleName());
        } else {
          if (!foundDifference) {
            log.info(message);
            foundDifference = true;
          }
          // should fail in subsequent esper update anyway
          log.warn(
              "\tnew event has new type for %s, prev: %s, new: %s",
              prevKey, prevClass.getSimpleName(), newClass.getSimpleName());
        }
      }
    }

    for (String newKey : newMap.keySet()) {

      if (nonVersionSpecificAttributes.contains(newKey)) continue;

      Class newClass = newMap.get(newKey);
      Class prevClass = prevMap.get(newKey);

      if (newClass != null && prevClass != newClass) {
        if (prevClass == null) {
          if (!foundDifference) {
            log.info(message);
            foundDifference = true;
          }
          log.info("\tnew event has new field: %s = %s", newKey, newClass.getSimpleName());
        }
      }
    }

    return foundDifference;
  }
public class SortableConfDataProvider<T extends ConfDataObject> extends SortableDataProvider<T>
    implements IFilterStateLocator {
  private static final Logger log = Logger.getLogger(SortableConfDataProvider.class);

  private List<T> dataList;
  private List<T> filteredList;
  private T filterObject = null;

  public SortableConfDataProvider(List<T> dataList, String initialSortId) {
    this(dataList, initialSortId, null);
  }

  public SortableConfDataProvider(List<T> dataList, String initialSortId, Class<T> clazz) {

    // pain in the ass to assign a newInstance from a generic type param
    try {
      if (clazz != null) filterObject = clazz.newInstance();
    } catch (Exception ex) {
      log.warn(ex);
      filterObject = null;
    }

    if (dataList == null) dataList = new ArrayList<T>();

    this.dataList = dataList;

    // set default sort
    setSort(initialSortId, true);
  }

  public synchronized void updateDataList(List<T> dataList) {
    this.dataList = dataList;
  }

  @Override
  public synchronized Iterator<T> iterator(int first, int count) {
    SortParam sp = getSort();
    Collections.sort(filteredList, new ConfDataComparator<T>(sp.getProperty(), sp.isAscending()));
    return new ListIterator<T>(filteredList, first, count);
  }

  @Override
  public IModel<T> model(T object) {
    return new Model<T>(object);
  }

  @Override
  public synchronized int size() {
    updateFilteredList();
    return filteredList.size();
  }

  @Override
  public Object getFilterState() {
    return filterObject;
  }

  @Override
  public void setFilterState(Object state) {
    filterObject = (T) state;
  }

  private void updateFilteredList() {

    if (this.filterObject == null) {
      this.filteredList = this.dataList;
    } else {
      this.filteredList = new ArrayList<T>();
      for (T t : this.dataList) {
        if (this.filterObject.filterMatchesDataObject(t)) {
          this.filteredList.add(t);
        }
      }
    }
  }

  private class ConfDataComparator<T> implements Comparator<T> {

    private final String property;
    private final boolean isAscending;

    public ConfDataComparator(String property, Boolean isAscending) {
      this.property = property;
      this.isAscending = isAscending;
    }

    @Override
    public int compare(T o1, T o2) {

      try {
        String val1 = BeanUtils.getProperty(o1, property);
        String val2 = BeanUtils.getProperty(o2, property);

        if (isAscending) {
          if (val1 == null) {
            if (val2 == null) {
              return 0;
            } else {
              return 1;
            }
          } else if (val2 == null) {
            return -1;
          } else return val1.toLowerCase().compareTo(val2.toLowerCase());
        } else {
          if (val2 == null) {
            if (val1 == null) {
              return 0;
            } else {
              return 1;
            }
          } else if (val1 == null) {
            return -1;
          } else return val2.toLowerCase().compareTo(val1.toLowerCase());
        }
      } catch (Exception ex) {
        throw new RuntimeException(ex);
      }
    }
  }

  private class ListIterator<T extends ConfDataObject> implements Iterator<T> {

    private final List<T> filteredList;
    private final int first;
    private final int count;

    private int current;

    public ListIterator(List<T> filteredList, int first, int count) {
      this.filteredList = filteredList;
      this.first = first;
      this.count = count;
      this.current = first;
    }

    @Override
    public boolean hasNext() {
      if (current > first + count) return false;

      if (filteredList.size() <= current) return false;

      return true;
    }

    @Override
    public T next() {
      if (!hasNext()) throw new NoSuchElementException();

      return this.filteredList.get(this.current++);
    }

    @Override
    public void remove() {
      throw new UnsupportedOperationException();
    }
  }
}
示例#6
0
  private ConfigReader getConfigViaExplicitParams() throws ConfigException {
    // This mode is primarily for testing
    //
    // Get config params from lists of local monitoring config filenames, host names, and config
    // paths...
    //  if the number of entries in one of the lists is less than the others, the last entry in the
    // shorter list will
    //  be replicated for each remaining config set.
    //  Thus if there is only one config file name, but 10 hostnames, then the same config file will
    // be applied to all 10 hosts, etc.
    //  (Note it's a bit inefficient therefore, as it will repeatedly open and close the same input
    // file)...
    //
    if (agentConfig.getExplicitConfigFiles().isEmpty()
        || agentConfig.getExplicitTypes().isEmpty()
        || agentConfig.getExplicitPaths().isEmpty()) {
      log.debug(
          "Could not configure via explicit params, must have non-null params for hostList, typeList and pathList");
      return null;
    }

    Iterator<String> configFileIter = agentConfig.getExplicitConfigFiles().iterator();
    Iterator<String> hostIter = agentConfig.getExplicitHosts().iterator();
    Iterator<String> pathIter = agentConfig.getExplicitPaths().iterator();
    Iterator<String> typeIter = agentConfig.getExplicitTypes().iterator();

    String configFile = null;
    String host = null;
    String path = null;
    String type = null;

    CompoundConfigReader configReader = new CompoundConfigReader();

    while (hostIter.hasNext() || typeIter.hasNext() || pathIter.hasNext()) {

      if (configFileIter.hasNext()) {
        configFile = configFileIter.next();
      }

      if (hostIter.hasNext()) {
        host = hostIter.next();
      }

      if (pathIter.hasNext()) {
        path = pathIter.next();
      }

      if (typeIter.hasNext()) {
        type = typeIter.next();
      }

      try {
        if (configFile != null) {
          log.info(
              "Adding initial configuration with config file '"
                  + configFile
                  + "', host '"
                  + host
                  + "', path '"
                  + path
                  + "', type '"
                  + type);
          Reader configFileReader = new FileReader(configFile);

          configReader.addConfigReader(
              new ConfigStreamReader(
                  configFileReader, host, path, type, guiceDefaultsForDataSources));
        } else {
          log.info(
              "Adding initial configuration with host '"
                  + host
                  + "', path '"
                  + path
                  + "', type '"
                  + type);
          List<InputStream> configResourceStreams =
              configFileUtils.getMonitoringTypeConfigStreamList(type, path, false);
          for (InputStream configResourceStream : configResourceStreams) {
            InputStreamReader configStreamReader = new InputStreamReader(configResourceStream);

            configReader.addConfigReader(
                new ConfigStreamReader(
                    configStreamReader, host, path, type, guiceDefaultsForDataSources));
          }
        }

        if (guiceDefaultsForDataSources.isJMXMonitoringProfilePollingEnabled()) {
          configReader.addConfigReader(
              new JMXMonitoringProfilePoller(host, path, type, guiceDefaultsForDataSources));
        }
      } catch (FileNotFoundException fnfEx) {
        log.warn("Could not open file %s: %s", configFile, fnfEx);
        throw new ConfigException("Could not open file " + configFile, fnfEx);
      }
    }

    return configReader;
  }
示例#7
0
public class ConfigInitializer {
  private static final Logger log = Logger.getLogger(ConfigInitializer.class);

  private final AgentConfig agentConfig;
  private final GuiceDefaultsForDataSources guiceDefaultsForDataSources;
  private final GalaxyCorePicker galaxyCorePicker;
  private final ConfigFileUtils configFileUtils;

  @Inject
  public ConfigInitializer(
      AgentConfig agentConfig,
      GalaxyCorePicker galaxyCorePicker,
      ConfigFileUtils configFileUtils,
      GuiceDefaultsForDataSources guiceDefaultsForDataSources) {
    this.agentConfig = agentConfig;
    this.galaxyCorePicker = galaxyCorePicker;
    this.configFileUtils = configFileUtils;
    this.guiceDefaultsForDataSources = guiceDefaultsForDataSources;
  }

  private ConfigReader getConfigViaExplicitParams() throws ConfigException {
    // This mode is primarily for testing
    //
    // Get config params from lists of local monitoring config filenames, host names, and config
    // paths...
    //  if the number of entries in one of the lists is less than the others, the last entry in the
    // shorter list will
    //  be replicated for each remaining config set.
    //  Thus if there is only one config file name, but 10 hostnames, then the same config file will
    // be applied to all 10 hosts, etc.
    //  (Note it's a bit inefficient therefore, as it will repeatedly open and close the same input
    // file)...
    //
    if (agentConfig.getExplicitConfigFiles().isEmpty()
        || agentConfig.getExplicitTypes().isEmpty()
        || agentConfig.getExplicitPaths().isEmpty()) {
      log.debug(
          "Could not configure via explicit params, must have non-null params for hostList, typeList and pathList");
      return null;
    }

    Iterator<String> configFileIter = agentConfig.getExplicitConfigFiles().iterator();
    Iterator<String> hostIter = agentConfig.getExplicitHosts().iterator();
    Iterator<String> pathIter = agentConfig.getExplicitPaths().iterator();
    Iterator<String> typeIter = agentConfig.getExplicitTypes().iterator();

    String configFile = null;
    String host = null;
    String path = null;
    String type = null;

    CompoundConfigReader configReader = new CompoundConfigReader();

    while (hostIter.hasNext() || typeIter.hasNext() || pathIter.hasNext()) {

      if (configFileIter.hasNext()) {
        configFile = configFileIter.next();
      }

      if (hostIter.hasNext()) {
        host = hostIter.next();
      }

      if (pathIter.hasNext()) {
        path = pathIter.next();
      }

      if (typeIter.hasNext()) {
        type = typeIter.next();
      }

      try {
        if (configFile != null) {
          log.info(
              "Adding initial configuration with config file '"
                  + configFile
                  + "', host '"
                  + host
                  + "', path '"
                  + path
                  + "', type '"
                  + type);
          Reader configFileReader = new FileReader(configFile);

          configReader.addConfigReader(
              new ConfigStreamReader(
                  configFileReader, host, path, type, guiceDefaultsForDataSources));
        } else {
          log.info(
              "Adding initial configuration with host '"
                  + host
                  + "', path '"
                  + path
                  + "', type '"
                  + type);
          List<InputStream> configResourceStreams =
              configFileUtils.getMonitoringTypeConfigStreamList(type, path, false);
          for (InputStream configResourceStream : configResourceStreams) {
            InputStreamReader configStreamReader = new InputStreamReader(configResourceStream);

            configReader.addConfigReader(
                new ConfigStreamReader(
                    configStreamReader, host, path, type, guiceDefaultsForDataSources));
          }
        }

        if (guiceDefaultsForDataSources.isJMXMonitoringProfilePollingEnabled()) {
          configReader.addConfigReader(
              new JMXMonitoringProfilePoller(host, path, type, guiceDefaultsForDataSources));
        }
      } catch (FileNotFoundException fnfEx) {
        log.warn("Could not open file %s: %s", configFile, fnfEx);
        throw new ConfigException("Could not open file " + configFile, fnfEx);
      }
    }

    return configReader;
  }

  private ConfigReader getConfigViaGalaxyAndCoreTypeConfig() throws ConfigException {
    ConfigReader configReader =
        new GalaxyOutputConfigReader(
            guiceDefaultsForDataSources, galaxyCorePicker, configFileUtils);

    return configReader;
  }

  private ConfigReader getConfigViaGalaxyAndDiscovery() throws ConfigException {
    GalaxyJMXDiscoveryConfigReader galaxyDiscoverer =
        new GalaxyJMXDiscoveryConfigReader(guiceDefaultsForDataSources, galaxyCorePicker);

    return galaxyDiscoverer;
  }

  public List<Config> getCurrentConfigList() throws ConfigException {

    ConfigReader configReader = null;

    switch (agentConfig.getConfigInitTypeParam()) {
      case CONFIG_BY_EXPLICIT_PARAMS:
        configReader = getConfigViaExplicitParams();
        break;
      case CONFIG_BY_CORE_TYPE_VIA_GALAXY_OUTPUT:
        configReader = getConfigViaGalaxyAndCoreTypeConfig();
        break;
      case CONFIG_BY_DISCOVERY_VIA_GALAXY_OUTPUT:
        configReader = getConfigViaGalaxyAndDiscovery();
        break;
    }

    List<Config> configList = null;

    if (configReader != null) {
      configList = configReader.getConfigurations();
    }

    if (configList != null && configList.size() > 0) {
      return configList;
    } else {
      log.info("No monitoring configurations initialized");
      return null;
    }
  }

  public List<Config> getExclusionList() throws ConfigException {
    try {

      InputStream inputStream = this.configFileUtils.getDefaultConfigSteam(ConfigType.EXCLUSION);

      try {
        InputStreamReader streamReader = null;
        try {
          streamReader = new InputStreamReader(inputStream);

          ConfigReader configReader = new ConfigStreamReader(streamReader, null, null, null, null);
          return configReader.getConfigurations();
        } finally {
          if (streamReader != null) {
            streamReader.close();
          }
        }
      } finally {
        if (inputStream != null) {
          inputStream.close();
        }
      }
    } catch (IOException ioEx) {
      throw new ConfigException("Problem retrieving exclusion config list", ioEx);
    }
  }
}
示例#8
0
/** A dictionary of Auto-generated Events */
public class EventDictionary implements EventPreProcessorListener {
  private static final Logger log = Logger.getLogger(EventDictionary.class);

  final ConcurrentHashMap<String, EventDefinition> inputEvents =
      new ConcurrentHashMap<String, EventDefinition>();
  final ConcurrentHashMap<String, EventDefinition> outputEvents =
      new ConcurrentHashMap<String, EventDefinition>();
  final ConcurrentHashMap<String, List<String>> inputEventSignatures =
      new ConcurrentHashMap<String, List<String>>();
  final ConcurrentSkipListSet<String> inputEventRegistrationsValid =
      new ConcurrentSkipListSet<String>();
  final CopyOnWriteArrayList<EventRegistrationListener> listeners =
      new CopyOnWriteArrayList<EventRegistrationListener>();
  private final String[] namespaces;

  // TODO: this list needs to be defined by different plugins, and used on a per-plugin basis
  // TODO: this is just a temporary hack to have it by rote here
  // TODO: Or else make a system of reserved words, that all plugins can use and respect?
  private static final String[] NON_VERSION_SPECIFIC_ATTRIBUTES = {
    "datapoints", "eventType", "numHosts", "sourceUUID"
  };
  private static final Set<String> nonVersionSpecificAttributes = new TreeSet<String>();

  static {
    nonVersionSpecificAttributes.addAll(Arrays.asList(NON_VERSION_SPECIFIC_ATTRIBUTES));
  }

  @Inject
  public EventDictionary(@AggregatorNamespaces String[] namespaces) {
    this.namespaces = namespaces;
  }

  @MonitorableManaged(monitored = true)
  public int getInputEventTypeCount() {
    return inputEvents.size();
  }

  @MonitorableManaged(monitored = true)
  public int getOutputEventTypeCount() {
    return outputEvents.size();
  }

  public void reset() {
    inputEvents.clear();
    inputEventSignatures.clear();
    inputEventRegistrationsValid.clear();
    outputEvents.clear();
    listeners.clear();
  }

  public String[] getNamespaces() {
    return namespaces;
  }

  @Override
  public void preProcessEvent(Map<String, Object> map) {
    // remove entries with null values
    Iterator<String> iter = map.keySet().iterator();
    while (iter.hasNext()) {
      if (map.get(iter.next()) == null) {
        iter.remove();
      }
    }

    // rename attributes that are esper reserved words
    EsperNamingUtils.checkWordsAreLegalEsperNamesInMapKeys(map);
  }

  // use this method if you only have the input event
  public String registerEvent(Event event, Map<String, Object> attributes) {
    return registerEventOrDefinition(event, attributes, null);
  }

  // use this method if you already have an EventDefinition
  public String registerDefinition(EventDefinition def) {
    return registerEventOrDefinition(null, null, def);
  }

  // use this method if you only have the input event
  private String registerEventOrDefinition(
      Event event, Map<String, Object> attributes, EventDefinition inputDef) {

    boolean gotInputDef = (inputDef != null);

    String escapedEventType;
    SortedMap<String, Class> map;

    if (gotInputDef) {
      map = inputDef.getProperties();
      escapedEventType = EsperNamingUtils.checkWordIsLegalEsperName(inputDef.getEventType());
    } else if (event == null || attributes == null) {
      log.warn("Got null input event or attributes in registerEventOrDefinition");
      return null;
    } else {
      // create map from attributes, throw out nulls
      map = new TreeMap<String, Class>();
      for (String name : attributes.keySet()) {
        Object attr = attributes.get(name);
        if (attr == null) continue;
        Class propertyClass = attr.getClass();
        map.put(name, propertyClass);
      }
      escapedEventType = EsperNamingUtils.checkWordIsLegalEsperName(event.getEventType());
    }

    // prepare event signature
    String eventSignature = getInputEventSignature(map);

    // see if we've seen this event before at all
    if (!inputEvents.containsKey(escapedEventType)) {

      log.info("registering new event definition: %s", escapedEventType);
      addInputEventSignature(escapedEventType, eventSignature);

      // first see if we have a pre-existing outputEvent, and if so, we need to merge properties
      // in case our new upper level event is narrower than previously registered base event
      // TODO: this is just a guard for the case where we have prevOutputDef one level down
      // TODO: (it won't help in case for multi-level distance, need to replace this with plugin
      // specific handling,
      // TODO:  to possibly find an ancestor prev def to use)
      EventDefinition prevOutputDef = this.getOutputEventDefinition(escapedEventType);
      EventDefinition newDef = null;
      if (prevOutputDef != null) {
        String msg =
            String.format(
                "detected differences with previously registered outputEvent: %s",
                escapedEventType);
        if (logPropertyDifferences(msg, prevOutputDef.getProperties(), map)) {

          if (gotInputDef) {
            // make a copy of def props
            map = new TreeMap<String, Class>();
            map.putAll(inputDef.getProperties());
            updateMapWithPrevOutputProperties(map, prevOutputDef.getProperties());
            newDef =
                new EventDefinition(
                    inputDef.getSourceEventClass(), escapedEventType, inputDef.getEvtClass(), map);
          } else {
            updateMapWithPrevOutputProperties(map, prevOutputDef.getProperties());
            newDef = new EventDefinition(event, escapedEventType, event.getClass(), map);
          }

          String updatedEventSignature = getInputEventSignature(map);
          addInputEventSignature(escapedEventType, updatedEventSignature);
        }
      }

      if (newDef == null) {
        if (!gotInputDef)
          newDef = new EventDefinition(event, escapedEventType, event.getClass(), map);
        else newDef = inputDef;
      }

      inputEvents.put(escapedEventType, newDef);
      registerEventStream(newDef);
    } else if (eventSignature != null
        && !checkInputEventSignatureRegistered(escapedEventType, eventSignature)) {
      log.info("got new signature for event type: %s", escapedEventType);

      // see if we have a new variant signature for a previously registered event
      if (gotInputDef) {
        // make a copy of def props
        map = new TreeMap<String, Class>();
        map.putAll(inputDef.getProperties());
      }

      String combinedEventSignature = null;
      EventDefinition prevDef = inputEvents.get(escapedEventType);
      String msg = String.format("detected updated event definition: %s", escapedEventType);

      if (logPropertyDifferences(msg, prevDef.getProperties(), map)) {
        map.putAll(prevDef.getProperties());
        combinedEventSignature = getInputEventSignature(map);
      } else {
        combinedEventSignature = eventSignature;
      }

      if (!checkInputEventSignatureRegistered(escapedEventType, combinedEventSignature)) {

        log.info("updating event definition registration: %s", escapedEventType);

        addInputEventSignature(escapedEventType, combinedEventSignature);

        EventDefinition combinedDef;
        if (gotInputDef) {
          combinedDef =
              new EventDefinition(
                  inputDef.getSourceEventClass(), escapedEventType, inputDef.getEvtClass(), map);
        } else {
          combinedDef = new EventDefinition(event, escapedEventType, event.getClass(), map);
        }
        inputEvents.put(escapedEventType, combinedDef);

        updateEventStream(combinedDef);
      }
      addInputEventSignature(escapedEventType, eventSignature);
    } else if (!inputEventRegistrationsValid.contains(escapedEventType)) {
      // this is a previously registered stream, but no currently valid EPL statements
      log.info("revalidating event type: %s", escapedEventType);
      inputEventRegistrationsValid.add(escapedEventType);
      notifyEventRegistered(inputEvents.get(escapedEventType));
    }

    return escapedEventType;
  }

  public EventDefinition getInputEventDefinition(String inputEvent) {
    return inputEvents.get(inputEvent);
  }

  private String getInputEventSignature(SortedMap<String, Class> typeMap) {
    try {
      MessageDigest md5 = MessageDigest.getInstance("MD5");
      for (SortedMap.Entry<String, Class> entry : typeMap.entrySet()) {
        md5.update(entry.getKey().getBytes());
        md5.update(entry.getValue().getSimpleName().getBytes());
      }
      byte[] d = md5.digest();

      return UUIDUtil.md5ToString(d);
    } catch (NoSuchAlgorithmException e) {
      return null;
    }
  }

  private boolean logPropertyDifferences(
      String message, SortedMap<String, Class> prevMap, SortedMap<String, Class> newMap) {
    boolean foundDifference = false;
    for (String prevKey : prevMap.keySet()) {

      if (nonVersionSpecificAttributes.contains(prevKey)) continue;

      Class prevClass = prevMap.get(prevKey);
      Class newClass = newMap.get(prevKey);

      if (prevClass != null && prevClass != newClass) {
        if (newClass == null) {
          if (!foundDifference) {
            log.info(message);
            foundDifference = true;
          }
          log.info(
              "\tnew event missing field in prev event: %s = %s",
              prevKey, prevClass.getSimpleName());
        } else {
          if (!foundDifference) {
            log.info(message);
            foundDifference = true;
          }
          // should fail in subsequent esper update anyway
          log.warn(
              "\tnew event has new type for %s, prev: %s, new: %s",
              prevKey, prevClass.getSimpleName(), newClass.getSimpleName());
        }
      }
    }

    for (String newKey : newMap.keySet()) {

      if (nonVersionSpecificAttributes.contains(newKey)) continue;

      Class newClass = newMap.get(newKey);
      Class prevClass = prevMap.get(newKey);

      if (newClass != null && prevClass != newClass) {
        if (prevClass == null) {
          if (!foundDifference) {
            log.info(message);
            foundDifference = true;
          }
          log.info("\tnew event has new field: %s = %s", newKey, newClass.getSimpleName());
        }
      }
    }

    return foundDifference;
  }

  private boolean checkInputEventSignatureRegistered(String eventType, String eventSignature) {

    List<String> signatures = inputEventSignatures.get(eventType);

    if (signatures == null) return false;

    return (signatures.contains(eventSignature));
  }

  private void addInputEventSignature(String eventType, String eventSignature) {
    List<String> signatures = inputEventSignatures.get(eventType);

    if (signatures == null) {
      signatures = new ArrayList<String>();
      inputEventSignatures.put(eventType, signatures);
    }

    if (!signatures.contains(eventSignature)) {
      signatures.add(eventSignature);
    }
  }

  private void registerEventStream(EventDefinition def) {
    log.info("registering event type stream %s", def.getEventType());
    for (String ns : namespaces) {
      EPAdministrator admin = EsperProvider.getProvider(ns).getEPAdministrator();

      HashMap<String, Object> m = new HashMap<String, Object>();
      for (Map.Entry<String, Class> entry : def.getProperties().entrySet()) {
        m.put(entry.getKey(), entry.getValue());
      }

      admin.getConfiguration().addEventType(def.getEventType(), m);
      inputEventRegistrationsValid.add(def.getEventType());
    }
    notifyEventRegistered(def);
  }

  private void updateEventStream(EventDefinition def) {
    log.info("removing registration for event type %s", def.getEventType());
    notifyEventUnRegistered(def);

    log.info("updating event type stream %s", def.getEventType());
    for (String ns : namespaces) {
      EPAdministrator admin = EsperProvider.getProvider(ns).getEPAdministrator();

      HashMap<String, Object> m = new HashMap<String, Object>();
      for (Map.Entry<String, Class> entry : def.getProperties().entrySet()) {
        m.put(entry.getKey(), entry.getValue());
      }

      admin.getConfiguration().updateMapEventType(def.getEventType(), m);
      inputEventRegistrationsValid.add(def.getEventType());
    }
    notifyEventRegistered(def);
  }

  static String toLowerCamelCase(String name) {
    return name.substring(0, 1).toLowerCase() + name.substring(1);
  }

  private void notifyEventRegistered(EventDefinition def) {
    for (EventRegistrationListener l : listeners) {
      l.eventRegistered(def);
    }
  }

  private void notifyEventUnRegistered(EventDefinition def) {
    for (EventRegistrationListener l : listeners) {
      l.eventUnRegistered(def);
    }
  }

  // For arbitrary events
  // TODO: Need to make this aware of Esper reserved words
  public void registerEventClass(Event event) {
    Class evtClass = event.getClass();
    if (!inputEvents.containsKey(evtClass.getName())) {
      EventDefinition def = new EventDefinition(event, evtClass.getSimpleName(), evtClass);
      EventDefinition v = inputEvents.putIfAbsent(evtClass.getName(), def);
      if (v == null) {
        registerEventStream(def);
      }
    }
  }

  public void registerOutputEvent(String outputEvent, EventType eventType) {
    EventDefinition def = new EventDefinition(outputEvent, eventType);
    outputEvents.put(outputEvent, def);
  }

  public void unregisterOutputEvent(String outputEvent) {
    outputEvents.remove(outputEvent);
  }

  public void addEventRegistrationListener(EventRegistrationListener listener) {
    listeners.add(listener);
  }

  public EventDefinition getInputEventDefintion(String name) {
    if (inputEventRegistrationsValid.contains(name)) return inputEvents.get(name);
    else return null;
  }

  public void invalidateInputEventStreams(String name) {
    inputEventRegistrationsValid.remove(name);
  }

  private void updateMapWithPrevOutputProperties(
      Map<String, Class> map, Map<String, Class> prevOutputProperties) {
    for (String prevOutputPropertyKey : prevOutputProperties.keySet()) {
      if (nonVersionSpecificAttributes.contains(prevOutputPropertyKey)) continue;

      if (!map.containsKey(prevOutputPropertyKey)) {
        map.put(prevOutputPropertyKey, prevOutputProperties.get(prevOutputPropertyKey));
      }
    }
  }

  public EventDefinition getOutputEventDefinition(String name) {
    return outputEvents.get(name);
  }

  public EventDefinition getEventDefintion(String name) {
    EventDefinition def = inputEvents.get(name);
    if (def != null) {
      return def;
    } else {
      return outputEvents.get(name);
    }
  }

  public void renderDebugText(PrintWriter pw) {
    pw.printf("-- Event Dictionary --\n\n");
    pw.printf("-- Input Events --\n\n");
    for (Map.Entry<String, EventDefinition> entry : inputEvents.entrySet()) {
      entry.getValue().renderDebugText(pw);
    }

    pw.printf("-- Output Events --\n\n");
    for (Map.Entry<String, EventDefinition> entry : outputEvents.entrySet()) {
      entry.getValue().renderDebugText(pw);
    }

    pw.flush();
  }

  public Set<String> getEventNames() {
    TreeSet<String> set = new TreeSet<String>();
    set.addAll(inputEvents.keySet());
    set.addAll(outputEvents.keySet());
    return set;
  }
}
示例#9
0
  // use this method if you only have the input event
  private String registerEventOrDefinition(
      Event event, Map<String, Object> attributes, EventDefinition inputDef) {

    boolean gotInputDef = (inputDef != null);

    String escapedEventType;
    SortedMap<String, Class> map;

    if (gotInputDef) {
      map = inputDef.getProperties();
      escapedEventType = EsperNamingUtils.checkWordIsLegalEsperName(inputDef.getEventType());
    } else if (event == null || attributes == null) {
      log.warn("Got null input event or attributes in registerEventOrDefinition");
      return null;
    } else {
      // create map from attributes, throw out nulls
      map = new TreeMap<String, Class>();
      for (String name : attributes.keySet()) {
        Object attr = attributes.get(name);
        if (attr == null) continue;
        Class propertyClass = attr.getClass();
        map.put(name, propertyClass);
      }
      escapedEventType = EsperNamingUtils.checkWordIsLegalEsperName(event.getEventType());
    }

    // prepare event signature
    String eventSignature = getInputEventSignature(map);

    // see if we've seen this event before at all
    if (!inputEvents.containsKey(escapedEventType)) {

      log.info("registering new event definition: %s", escapedEventType);
      addInputEventSignature(escapedEventType, eventSignature);

      // first see if we have a pre-existing outputEvent, and if so, we need to merge properties
      // in case our new upper level event is narrower than previously registered base event
      // TODO: this is just a guard for the case where we have prevOutputDef one level down
      // TODO: (it won't help in case for multi-level distance, need to replace this with plugin
      // specific handling,
      // TODO:  to possibly find an ancestor prev def to use)
      EventDefinition prevOutputDef = this.getOutputEventDefinition(escapedEventType);
      EventDefinition newDef = null;
      if (prevOutputDef != null) {
        String msg =
            String.format(
                "detected differences with previously registered outputEvent: %s",
                escapedEventType);
        if (logPropertyDifferences(msg, prevOutputDef.getProperties(), map)) {

          if (gotInputDef) {
            // make a copy of def props
            map = new TreeMap<String, Class>();
            map.putAll(inputDef.getProperties());
            updateMapWithPrevOutputProperties(map, prevOutputDef.getProperties());
            newDef =
                new EventDefinition(
                    inputDef.getSourceEventClass(), escapedEventType, inputDef.getEvtClass(), map);
          } else {
            updateMapWithPrevOutputProperties(map, prevOutputDef.getProperties());
            newDef = new EventDefinition(event, escapedEventType, event.getClass(), map);
          }

          String updatedEventSignature = getInputEventSignature(map);
          addInputEventSignature(escapedEventType, updatedEventSignature);
        }
      }

      if (newDef == null) {
        if (!gotInputDef)
          newDef = new EventDefinition(event, escapedEventType, event.getClass(), map);
        else newDef = inputDef;
      }

      inputEvents.put(escapedEventType, newDef);
      registerEventStream(newDef);
    } else if (eventSignature != null
        && !checkInputEventSignatureRegistered(escapedEventType, eventSignature)) {
      log.info("got new signature for event type: %s", escapedEventType);

      // see if we have a new variant signature for a previously registered event
      if (gotInputDef) {
        // make a copy of def props
        map = new TreeMap<String, Class>();
        map.putAll(inputDef.getProperties());
      }

      String combinedEventSignature = null;
      EventDefinition prevDef = inputEvents.get(escapedEventType);
      String msg = String.format("detected updated event definition: %s", escapedEventType);

      if (logPropertyDifferences(msg, prevDef.getProperties(), map)) {
        map.putAll(prevDef.getProperties());
        combinedEventSignature = getInputEventSignature(map);
      } else {
        combinedEventSignature = eventSignature;
      }

      if (!checkInputEventSignatureRegistered(escapedEventType, combinedEventSignature)) {

        log.info("updating event definition registration: %s", escapedEventType);

        addInputEventSignature(escapedEventType, combinedEventSignature);

        EventDefinition combinedDef;
        if (gotInputDef) {
          combinedDef =
              new EventDefinition(
                  inputDef.getSourceEventClass(), escapedEventType, inputDef.getEvtClass(), map);
        } else {
          combinedDef = new EventDefinition(event, escapedEventType, event.getClass(), map);
        }
        inputEvents.put(escapedEventType, combinedDef);

        updateEventStream(combinedDef);
      }
      addInputEventSignature(escapedEventType, eventSignature);
    } else if (!inputEventRegistrationsValid.contains(escapedEventType)) {
      // this is a previously registered stream, but no currently valid EPL statements
      log.info("revalidating event type: %s", escapedEventType);
      inputEventRegistrationsValid.add(escapedEventType);
      notifyEventRegistered(inputEvents.get(escapedEventType));
    }

    return escapedEventType;
  }