text:
"""
	PLUGIN for print function

	- action : ACTION_NAME
	  print

	  will print the result of action execution to STDOUT

"""

#import logging
#logger = logging.getLogger()

############################################

# Exec if comman execution was NOT successful
def grep( output, lines ):
	result = []
	for line in output:
		if line in lines:
			result.append(line)
	return result

#############################################
#  HELP FUNCTION
############################################
def help( params ):
	print( "" )
	print( " FUNCTION grep:" )
	print( "\t" )
	print( "\tIt works with last command output." )
	print( "\tFunction keeps all lines contained in the list of grep command")
	print( "\tand drops all lines that doesn't")
	print( "\t" )
	print( "\tHow to define:          " )
	print( "\t\t- action : SOME_ACTION" )
	print( "\t\t  grep   :            " )
	print( "\t\t    - 'line1'         " )
	print( "\t\t    - 'line2'         " )
	print( "\t\t    - 'line3'         " )
	print( "\t" )
	print( "\tEXAMPLE:" )
	print( "\t\t- action : start_VM" )
	print( "\t\t  grep   :         " )
	print( "\t\t    - 'ERROR'      " )
	print( "\t\t    - 'Started'    " )
	print( "\t\t-                  " )
	print( "\t\t  print            " )
	print( "\t" )

#############################################
#  MAIN EXECUTOR FOR PLUGIN
############################################

def run( action, config, data):
	exec_function = exec_parameters.get( data["param"], "default" )
	output_old = data["lastOutput"]
	output_new = grep( output=output_old, lines=data["param"] )
	data["lastOutput"] = output_new


text:
<?xml version="1.0" ?>
<INPUT>

	<MEDALS>
		<MEDAL Id="1" MEDAL_THRESHOLD="52000" TYPE="Gold"/>
		<MEDAL Id="2" MEDAL_THRESHOLD="79000" TYPE="Silver"/>
		<MEDAL Id="3" MEDAL_THRESHOLD="102000" TYPE="Bronze"/>

	</MEDALS>

	<SpeedSettings Default="18" Max="150" Min="0"/>

	<PenaltySettings SpeedLost="0.1" TimeLost="15"/>

	<PROBLEM_SET>
		<PROBLEM_SUBSET>
			<TARGET TYPE="Fraction">
				<ContentSettings denominator="12" numerator="13"/>
			</TARGET>
			<QUESTION INDEX="1">
				<Content TYPE="String">
					<ContentSettings string="0.416"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="1.416"/>
				</Content>
				<Answer VALUE="1"/>
			</QUESTION>
			<QUESTION INDEX="2">
				<Content TYPE="String">
					<ContentSettings string="1.333"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="1.75"/>
				</Content>
				<Answer VALUE="0"/>
			</QUESTION>
			<QUESTION INDEX="3">
				<Content TYPE="String">
					<ContentSettings string="0.416"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="1.166"/>
				</Content>
				<Answer VALUE="1"/>
			</QUESTION>
		</PROBLEM_SUBSET>
		<PROBLEM_SUBSET>
			<TARGET TYPE="Fraction">
				<ContentSettings denominator="1000" numerator="1222"/>
			</TARGET>
			<QUESTION INDEX="4">
				<Content TYPE="String">
					<ContentSettings string="0.297"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="0.695"/>
				</Content>
				<Answer VALUE="2"/>
			</QUESTION>
			<QUESTION INDEX="5">
				<Content TYPE="String">
					<ContentSettings string="0.066"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="1.007"/>
				</Content>
				<Answer VALUE="2"/>
			</QUESTION>
			<QUESTION INDEX="6">
				<Content TYPE="String">
					<ContentSettings string="1.315"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="1.433"/>
				</Content>
				<Answer VALUE="0"/>
			</QUESTION>
		</PROBLEM_SUBSET>
		<PROBLEM_SUBSET>
			<TARGET TYPE="Fraction">
				<ContentSettings denominator="5" numerator="9"/>
			</TARGET>
			<QUESTION INDEX="7">
				<Content TYPE="String">
					<ContentSettings string="0.2"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="1.4"/>
				</Content>
				<Answer VALUE="2"/>
			</QUESTION>
			<QUESTION INDEX="8">
				<Content TYPE="String">
					<ContentSettings string="2"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="2.2"/>
				</Content>
				<Answer VALUE="0"/>
			</QUESTION>
			<QUESTION INDEX="9">
				<Content TYPE="String">
					<ContentSettings string="0"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="2"/>
				</Content>
				<Answer VALUE="1"/>
			</QUESTION>
		</PROBLEM_SUBSET>
		<PROBLEM_SUBSET>
			<TARGET TYPE="Fraction">
				<ContentSettings denominator="5" numerator="6"/>
			</TARGET>
			<QUESTION INDEX="10">
				<Content TYPE="String">
					<ContentSettings string="2"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="2.2"/>
				</Content>
				<Answer VALUE="0"/>
			</QUESTION>
			<QUESTION INDEX="11">
				<Content TYPE="String">
					<ContentSettings string="0"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="1.8"/>
				</Content>
				<Answer VALUE="1"/>
			</QUESTION>
			<QUESTION INDEX="12">
				<Content TYPE="String">
					<ContentSettings string="1.4"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="2.2"/>
				</Content>
				<Answer VALUE="0"/>
			</QUESTION>
		</PROBLEM_SUBSET>
		<PROBLEM_SUBSET>
			<TARGET TYPE="Fraction">
				<ContentSettings denominator="12" numerator="21"/>
			</TARGET>
			<QUESTION INDEX="13">
				<Content TYPE="String">
					<ContentSettings string="2"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="2.083"/>
				</Content>
				<Answer VALUE="0"/>
			</QUESTION>
			<QUESTION INDEX="14">
				<Content TYPE="String">
					<ContentSettings string="0"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="1.416"/>
				</Content>
				<Answer VALUE="2"/>
			</QUESTION>
			<QUESTION INDEX="15">
				<Content TYPE="String">
					<ContentSettings string="1.5"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="2.083"/>
				</Content>
				<Answer VALUE="1"/>
			</QUESTION>
		</PROBLEM_SUBSET>
		<PROBLEM_SUBSET>
			<TARGET TYPE="Fraction">
				<ContentSettings denominator="5" numerator="7"/>
			</TARGET>
			<QUESTION INDEX="16">
				<Content TYPE="String">
					<ContentSettings string="1.8"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="2.2"/>
				</Content>
				<Answer VALUE="0"/>
			</QUESTION>
			<QUESTION INDEX="17">
				<Content TYPE="String">
					<ContentSettings string="0"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="1"/>
				</Content>
				<Answer VALUE="2"/>
			</QUESTION>
			<QUESTION INDEX="18">
				<Content TYPE="String">
					<ContentSettings string="0.4"/>
				</Content>
				<Content TYPE="String">
					<ContentSettings string="1.6"/>
				</Content>
				<Answer VALUE="1"/>
			</QUESTION>
		</PROBLEM_SUBSET>

	</PROBLEM_SET>

</INPUT>

redpajama_set_name: RedPajamaGithub


text:
<component name="libraryTable">
  <library name="Gradle: org.springframework:spring-expression:5.0.6.RELEASE">
    <CLASSES>
      <root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.springframework/spring-expression/5.0.6.RELEASE/dec57ae5e6f0dfd4c6cfc199aa13ed268c3e1a65/spring-expression-5.0.6.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC />
    <SOURCES>
      <root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.springframework/spring-expression/5.0.6.RELEASE/3f138684cb7b5a8842d23e764591f4add83512a4/spring-expression-5.0.6.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>


text:
<?php

namespace Anax\Questions;

/**
 * A controller for users and admin related events.
 *
 */
class TagsController implements \Anax\DI\IInjectionAware
{
    use \Anax\DI\TInjectable;

   /**
     * Initialize the controller.
     *
     * @return void
     */
    public function initialize()
    {

        $this->questions = new \Anax\Questions\Question();
        $this->questions->setDI($this->di);

        $this->tagslist = new \Anax\Questions\Tags();
        $this->tagslist->setDI($this->di);

        $this->tags = new \Anax\Questions\TagsView();
        $this->tags->setDI($this->di);

   }
 /**
     * View all tags.
     *
     * @return void
     */
    public function viewAction($pagekey)
    {

    $alltags = $this->tagslist->query('tags')
            ->execute();
        $this->views->add('tags/taggar', [
            'tags'  => $alltags,
        ]);

    }

  /**
 * List Tags with id.
 *
 * @param int $id of tag to display
 *
 * @return void
 */
public function tagAction($tag = null)
{

    $this->initialize();
    $taggen = $this->tags->query()
        ->where('tags = ?')
        ->limit('1')
        ->execute(array($tag));

    if (empty($taggen)){
    $tagname = null;
    }
    else{
         $tagname = $taggen[0]->tags;
    }

    if ($tagname == NULL) {
      $this->views->add('default/pageback', [
            'title' => 'Ojdå',
            'content' => 'Det finns inga frågor med denna tagg ännu',
    ]);
    }

    $alltagsid = $this->tags->query('questionId')
            ->where('tags = ?')
            ->execute(array($tagname));

    $allquestions = $this->questions->query()
             ->execute();

    $this->theme->setTitle("Frågor ställda till: " . $tagname);

    $this->views->add('tags/tags', [
            'tagid' => $alltagsid,
            'questions' => $allquestions,
            'tagname' => $tagname,
    ]);

}

}


text:
/*
 * 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.
 */
/*
 * This code was generated by https://github.com/googleapis/google-api-java-client-services/
 * Modify at your own risk.
 */

package com.google.api.services.datastore.v1.model;

/**
 * A property of an index.
 *
 *
 This is the Java data model class that specifies how to parse/serialize into the JSON that is
 * transmitted over HTTP when working with the Cloud Datastore API. For a detailed explanation see:
 * https://developers.google.com/api-client-library/java/google-http-java-client/json
 *

 *
 * @author Google, Inc.
 */
@SuppressWarnings("javadoc")
public final class GoogleDatastoreAdminV1IndexedProperty extends com.google.api.client.json.GenericJson {

  /**
   * Required. The indexed property's direction. Must not be DIRECTION_UNSPECIFIED.
   * The value may be {@code null}.
   */
  @com.google.api.client.util.Key
  private java.lang.String direction;

  /**
   * Required. The property name to index.
   * The value may be {@code null}.
   */
  @com.google.api.client.util.Key
  private java.lang.String name;

  /**
   * Required. The indexed property's direction. Must not be DIRECTION_UNSPECIFIED.
   * @return value or {@code null} for none
   */
  public java.lang.String getDirection() {
    return direction;
  }

  /**
   * Required. The indexed property's direction. Must not be DIRECTION_UNSPECIFIED.
   * @param direction direction or {@code null} for none
   */
  public GoogleDatastoreAdminV1IndexedProperty setDirection(java.lang.String direction) {
    this.direction = direction;
    return this;
  }

  /**
   * Required. The property name to index.
   * @return value or {@code null} for none
   */
  public java.lang.String getName() {
    return name;
  }

  /**
   * Required. The property name to index.
   * @param name name or {@code null} for none
   */
  public GoogleDatastoreAdminV1IndexedProperty setName(java.lang.String name) {
    this.name = name;
    return this;
  }

  @Override
  public GoogleDatastoreAdminV1IndexedProperty set(String fieldName, Object value) {
    return (GoogleDatastoreAdminV1IndexedProperty) super.set(fieldName, value);
  }

  @Override
  public GoogleDatastoreAdminV1IndexedProperty clone() {
    return (GoogleDatastoreAdminV1IndexedProperty) super.clone();
  }

}


text:
// Copyright 2016 Howard C. Shaw III. All rights reserved.
// Use of this source code is governed by the MIT-license
// as defined in the LICENSE file.

package renderview

import (
	"image"
	"math"
	"sync"
)

// RenderModel is the interface you will implement to stand between your visualization code
// and the RenderView. You are primarily responsible for providing a set of RenderParameters
// and providing an Image upon request via Render.
type RenderModel interface {
	Lock()
	Unlock()

	GetParameterNames() []string
	GetHintedParameterNames(hint int) []string
	GetHintedParameterNamesWithFallback(hint int) []string
	GetParameter(name string) RenderParameter
	Render() image.Image
	SetRequestPaintFunc(func())
	GetRequestPaintFunc() func()
}

// EmptyRenderModel concretizes the most important elements of the RenderModel, the bag of Parameters (Params)
// and the RequestPaint function (which the view sets) - call this latter function to inform the view
// that you have provided a new image or set of information needing a render. It is not usable as a RenderModel
// by itself, as the implementation of Render simply returns nil. Embed it in your RenderModel struct.
type EmptyRenderModel struct {
	sync.Mutex

	Params       []RenderParameter
	RequestPaint func()
}

// GetParameterNames returns a list of valid parameter names
func (e *EmptyRenderModel) GetParameterNames() []string {
	s := make([]string, len(e.Params))
	for i := 0; i < len(e.Params); i++ {
		s[i] = e.Params[i].GetName()
	}
	return s
}

// GetHintedParameterNames returns a list of parameters with one of the passed hints
func (e *EmptyRenderModel) GetHintedParameterNames(hints int) []string {
	s := make([]string, 0, len(e.Params))
	for i := 0; i < len(e.Params); i++ {
		if e.Params[i].GetHint()&hints > 0 {
			s = append(s, e.Params[i].GetName())
		}
	}
	return s
}

// GetHintedParameterNamesWithFallback retrieves the names of parameters matching hints,
// if that is the empty set, it retrieves the names of parameters with no hints
func (e *EmptyRenderModel) GetHintedParameterNamesWithFallback(hints int) []string {
	s := make([]string, 0, len(e.Params))
	for i := 0; i < len(e.Params); i++ {
		if e.Params[i].GetHint()&hints > 0 {
			s = append(s, e.Params[i].GetName())
		}
	}
	if len(s) == 0 {
		for i := 0; i < len(e.Params); i++ {
			if e.Params[i].GetHint() == 0 {
				s = append(s, e.Params[i].GetName())
			}
		}
	}
	return s
}

// GetParameter returns a named parameter. If you implement your own RenderModel from scratch,
// without using the EmptyRenderModel as a basis, you must either include ALL the default
// parameters, or duplicate the behavior of EmptyRenderModel in returning an EmptyParameter
// when a non-existent parameter is requested.
func (e *EmptyRenderModel) GetParameter(name string) RenderParameter {
	for _, p := range e.Params {
		if name == p.GetName() {
			return p
		}
	}

	return &EmptyParameter{}
}

func (e *EmptyRenderModel) Render() image.Image {
	return nil
}

// AddParameters accepts any number of parameters and adds them to the Params bag.
// It does not do ANY checking for duplication!
func (e *EmptyRenderModel) AddParameters(Params ...RenderParameter) {
	e.Params = append(e.Params, Params...)
}

// Included for completeness. In general, there is no need for your code to use
// the RenderModel interface instead of a concrete form, so you can simply
// access e.RequestPaint directly.
func (e *EmptyRenderModel) GetRequestPaintFunc() func() {
	return e.RequestPaint
}

// Used by the RenderView to supply a function you can call to inform the view
// that it should perform a repaint.
func (e *EmptyRenderModel) SetRequestPaintFunc(f func()) {
	e.RequestPaint = f
}

/*
// EmptyRenderModel is not functional by itself
func NewEmptyRenderModel() *EmptyRenderModel {
	return &EmptyRenderModel{
		Params: make([]RenderParameter, 0, 10),
	}
}*/

// InitializeEmptyRenderModel should be called to initialize the EmptyRenderModel
// when embedded in your own struct.
func InitializeEmptyRenderModel(m *EmptyRenderModel) {
	m.Params = make([]RenderParameter, 0, 10)
}

// BasicRenderModel should suffice for many users, and can be embedded to provide its
// functionality to your own models. It provides an easy way to attach your own
// rendering implementation that will be called in a separate goroutine.
type BasicRenderModel struct {
	EmptyRenderModel

	RequestRender chan interface{}
	NeedsRender   bool
	Rendering     bool
	Img           image.Image

	started bool

	InnerRender func()
}

// Called by RenderView
func (m *BasicRenderModel) Render() image.Image {
	m.Lock()
	defer m.Unlock()
	rendering := m.Rendering
	if !rendering {
		m.RequestRender <- true
		m.NeedsRender = false
	} else {
		m.NeedsRender = true
	}
	return m.Img
}

// GoRender is called by Start and calls your provided InnerRender function when needed.
func (m *BasicRenderModel) GoRender() {
	for {
		select {
		case <-m.RequestRender:
			if !(m.InnerRender == nil) {
				m.InnerRender()
				if m.NeedsRender {
					m.NeedsRender = false
					m.InnerRender()
				}
			}
		}
	}
}

// Start only needs to be called if you have embedded BasicRenderModel in your own struct.
func (m *BasicRenderModel) Start() {
	if !m.started {
		m.started = true
		go m.GoRender()
	}
}

func NewBasicRenderModel() *BasicRenderModel {
	m := BasicRenderModel{
		EmptyRenderModel: EmptyRenderModel{
			Params: make([]RenderParameter, 0, 10),
		},
		RequestRender: make(chan interface{}, 10),
	}
	m.started = true
	go m.GoRender()
	return &m
}

// Use Initialize to set up a BasicRenderModel when you have embedded it in
// your own model
// Remember to add a go m.GoRender() or call Start()
func InitializeBasicRenderModel(m *BasicRenderModel) {
	m.Params = make([]RenderParameter, 0, 10)
	m.RequestRender = make(chan interface{}, 10)
}

func DefaultParameters(useint bool, hint int, options int, left float64, top float64, right float64, bottom float64) []RenderParameter {
	if useint {
		return SetHints(hint,
			NewIntRP("left", int(math.Floor(left))),
			NewIntRP("top", int(math.Floor(top))),
			NewIntRP("right", int(math.Floor(right))),
			NewIntRP("bottom", int(math.Floor(bottom))),
			NewIntRP("width", 100),
			NewIntRP("height", 100),
			NewIntRP("options", options))
	} else {
		return SetHints(hint,
			NewFloat64RP("left", left),
			NewFloat64RP("top", top),
			NewFloat64RP("right", right),
			NewFloat64RP("bottom", bottom),
			NewIntRP("width", 100),
			NewIntRP("height", 100),
			NewIntRP("options", options))
	}
}


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Aegins</title>

<form  action="?c=session&a=login" method="post">

                <input type="text" name="user" placeholder="用户名" style="border:none;background-color:transparent;width: 410px;height: 32px;color:#ffffff;font-size: 16px;float:none;padding: 6px;" autocomplete="off">

                <input type="password" name="passwd" placeholder="密码" style="border:none;background-color:transparent;width: 410px;height: 32px;color:#ffffff;font-size: 16px;float:none;padding: 6px;" autocomplete="off">

忘记密码?
            	{[if $errormsg]}
				{[$errormsg]}
				{[/if]}

<input  type="submit"  onclick="btnUpdate_Click()" style="width:240px;height:50px;line-height:50px;background:#ff6760;color:#fff;border:none;font-size: 14px;" value="登陆" />

<input type="button" onclick="window.location.href='?c=public&a=registerForm'"  style="width:240px; height:50px; line-height:50px; background:#e5e5e5; color:#ff6760; border:none; font-size: 14px;" value="注册" />

       </form>

© 2016 Aegins Technologies, Inc. All rights reserved.


text:
<!DOCTYPE html>

    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="Date-Revision-yyyymmdd" content="20180607" />
    <meta http-equiv="Content-Language" content="en" />
    <title>Metron – Metron REST</title>
    <link rel="stylesheet" href="../../css/apache-maven-fluido-1.7.min.css" />
    <link rel="stylesheet" href="../../css/site.css" />
    <link rel="stylesheet" href="../../css/print.css" media="print" />

Apache/

Metron/

Documentation/

Metron REST

| Last Published: 2018-06-07

Version: 0.5.0

User Documentation

Metron

CONTRIBUTING

Upgrading

Analytics

Docker

Performance

Deployment

Alerts

Config

Rest

Platform

Sensors

Stellar-3rd-party-example

Stellar-common

Stellar-zeppelin

Use-cases

Metron REST

This module provides a RESTful API for interacting with Metron.

Prerequisites

A running Metron cluster

Java 8 installed

Storm CLI and Metron topology scripts (start_parser_topology.sh, start_enrichment_topology.sh, start_elasticsearch_topology.sh) installed

A relational database

Installation

From Source

Package the application with Maven:

mvn clean package

Untar the archive in the $METRON_HOME directory.  The directory structure will look like:

config
  rest_application.yml
bin
  metron-rest
lib
  metron-rest-$METRON_VERSION.jar

Copy the <tt>$METRON_HOME/bin/metron-rest</tt> script to <tt>/etc/init.d/metron-rest</tt>

From Package Manager

Deploy the RPM at <tt>/metron/metron-deployment/packaging/docker/rpm-docker/target/RPMS/noarch/metron-rest-$METRON_VERSION-*.noarch.rpm</tt>

Install the RPM with:

rpm -ih metron-rest-$METRON_VERSION-*.noarch.rpm

Configuration

The REST application depends on several configuration parameters:

REQUIRED

No optional parameter has a default.

 Environment Variable
 Description

 METRON_JDBC_DRIVER
 JDBC driver class

 METRON_JDBC_URL
 JDBC url

 METRON_JDBC_USERNAME
 JDBC username

 METRON_JDBC_PLATFORM
 JDBC platform (one of h2, mysql, postgres, oracle

 ZOOKEEPER
 Zookeeper quorum (ex. node1:2181,node2:2181)

 BROKERLIST
 Kafka Broker list (ex. node1:6667,node2:6667)

 HDFS_URL
 HDFS url or <tt>fs.defaultFS</tt> Hadoop setting (ex. hdfs://node1:8020)

Optional - With Defaults

 Environment Variable
 Description
 Required
 Default

 METRON_LOG_DIR
 Directory where the log file is written
 Optional
 /var/log/metron/

 METRON_PID_FILE
 File where the pid is written
 Optional
 /var/run/metron/

 METRON_REST_PORT
 REST application port
 Optional
 8082

 METRON_JDBC_CLIENT_PATH
 Path to JDBC client jar
 Optional
 H2 is bundled

 METRON_TEMP_GROK_PATH
 Temporary directory used to test grok statements
 Optional
 ./patterns/temp

 METRON_DEFAULT_GROK_PATH
 Defaults HDFS directory used to store grok statements
 Optional
 /apps/metron/patterns

 SECURITY_ENABLED
 Enables Kerberos support
 Optional
 false

Optional - Blank Defaults

 Environment Variable
 Description
 Required

 METRON_JVMFLAGS
 JVM flags added to the start command
 Optional

 METRON_SPRING_PROFILES_ACTIVE
 Active Spring profiles (see below)
 Optional

 METRON_SPRING_OPTIONS
 Additional Spring input parameters
 Optional

 METRON_PRINCIPAL_NAME
 Kerberos principal for the metron user
 Optional

 METRON_SERVICE_KEYTAB
 Path to the Kerberos keytab for the metron user
 Optional

These are set in the <tt>/etc/default/metron</tt> file.

Database setup

The REST application persists data in a relational database and requires a dedicated database user and database (see https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html for more detail).

Spring uses Hibernate as the default ORM framework but another framework is needed becaused Hibernate is not compatible with the Apache 2 license.  For this reason Metron uses EclipseLink.  See the Spring Data JPA - EclipseLink project for an example on how to configure EclipseLink in Spring.

Development

The REST application comes with embedded database support for development purposes.

For example, edit these variables in <tt>/etc/default/metron</tt> before starting the application to configure H2:

METRON_JDBC_DRIVER="org.h2.Driver"
METRON_JDBC_URL="jdbc:h2:file:~/metrondb"
METRON_JDBC_USERNAME="root"
METRON_JDBC_PLATFORM="h2"

Production

The REST application should be configured with a production-grade database outside of development.

Ambari Install

Installing with Ambari is recommended for production deployments. Ambari handles setup, configuration, and management of the REST component. This includes managing the PID file, directing logging, etc.

Manual Install

The following configures the application for MySQL:

Install MySQL if not already available (this example uses version 5.7, installation instructions can be found here)

Create a metron user and REST database and permission the user for that database:

CREATE USER 'metron'@'node1' IDENTIFIED BY 'Myp@ssw0rd';
CREATE DATABASE IF NOT EXISTS metronrest;
GRANT ALL PRIVILEGES ON metronrest.* TO 'metron'@'node1';

Create the security tables as described in the Spring Security Guide.

Install the MySQL JDBC client onto the REST application host and configurate the METRON_JDBC_CLIENT_PATH variable:

cd $METRON_HOME/lib
wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.41.tar.gz
tar xf mysql-connector-java-5.1.41.tar.gz

Edit these variables in <tt>/etc/default/metron</tt> to configure the REST application for MySQL:

METRON_JDBC_DRIVER="com.mysql.jdbc.Driver"
METRON_JDBC_URL="jdbc:mysql://mysql_host:3306/metronrest"
METRON_JDBC_USERNAME="metron"
METRON_JDBC_PLATFORM="mysql"
METRON_JDBC_CLIENT_PATH=$METRON_HOME/lib/mysql-connector-java-5.1.41/mysql-connector-java-5.1.41-bin.jar

Switch to the metron user

sudo su - metron

Start the REST API. Adjust the password as necessary.

set -o allexport;
source /etc/default/metron;
set +o allexport;
export METRON_JDBC_PASSWORD='Myp@ssw0rd';
$METRON_HOME/bin/metron-rest.sh
unset METRON_JDBC_PASSWORD;

Usage

The REST application can be accessed with the Swagger UI at http://host:port/swagger-ui.html#/.  The default port is 8082.

Security

Authentication

The metron-rest module uses Spring Security for authentication and stores user credentials in the relational database configured above.  The required tables are created automatically the first time the application is started so that should be done first.  For example (continuing the MySQL example above), users can be added by connecting to MySQL and running:

use metronrest;
insert into users (username, password, enabled) values ('your_username','your_password',1);
insert into authorities (username, authority) values ('your_username', 'ROLE_USER');

Kerberos

Metron REST can be configured for a cluster with Kerberos enabled.  A client JAAS file is required for Kafka and Zookeeper and a Kerberos keytab for the metron user principal is required for all other services.  Configure these settings in the <tt>/etc/default/metron</tt> file:

SECURITY_ENABLED=true
METRON_JVMFLAGS="-Djava.security.auth.login.config=$METRON_HOME/client_jaas.conf"
METRON_PRINCIPAL_NAME="metron@EXAMPLE.COM"
METRON_SERVICE_KEYTAB="/etc/security/keytabs/metron.keytab"

Spring Profiles

The REST application comes with a few Spring Profiles to aid in testing and development.

 Profile
 Description

 test
 adds test users <tt>[user, user1, user2, admin]</tt> to the database with password “<tt>password</tt>”. sets variables to in-memory services, only used for integration testing

 dev
 adds test users <tt>[user, user1, user2, admin]</tt> to the database with password “<tt>password</tt>”

 vagrant
 sets configuration variables to match the Metron vagrant environment

 docker
 sets configuration variables to match the Metron docker environment

Setting active profiles is done with the METRON_SPRING_PROFILES_ACTIVE variable.  For example, set this variable in <tt>/etc/default/metron</tt> to configure the REST application for the Vagrant environment and add a test user:

METRON_SPRING_PROFILES_ACTIVE="vagrant,dev"

API

Request and Response objects are JSON formatted.  The JSON schemas are available in the Swagger UI.

  <tt>POST /api/v1/alerts/ui/escalate</tt>

  <tt>GET /api/v1/alerts/ui/settings</tt>

  <tt>GET /api/v1/alerts/ui/settings/all</tt>

  <tt>DELETE /api/v1/alerts/ui/settings</tt>

  <tt>POST /api/v1/alerts/ui/settings</tt>

  <tt>GET /api/v1/global/config</tt>

  <tt>DELETE /api/v1/global/config</tt>

  <tt>POST /api/v1/global/config</tt>

  <tt>GET /api/v1/grok/get/statement</tt>

  <tt>GET /api/v1/grok/list</tt>

  <tt>POST /api/v1/grok/validate</tt>

  <tt>POST /api/v1/hdfs</tt>

  <tt>GET /api/v1/hdfs</tt>

  <tt>DELETE /api/v1/hdfs</tt>

  <tt>GET /api/v1/hdfs/list</tt>

  <tt>GET /api/v1/kafka/topic</tt>

  <tt>POST /api/v1/kafka/topic</tt>

  <tt>GET /api/v1/kafka/topic/{name}</tt>

  <tt>DELETE /api/v1/kafka/topic/{name}</tt>

  <tt>GET /api/v1/kafka/topic/{name}/sample</tt>

  <tt>POST /api/v1/kafka/topic/{name}/produce</tt>

  <tt>GET /api/v1/metaalert/searchByAlert</tt>

  <tt>GET /api/v1/metaalert/create</tt>

  <tt>GET /api/v1/metaalert/add/alert</tt>

  <tt>GET /api/v1/metaalert/remove/alert</tt>

  <tt>GET /api/v1/metaalert/update/status/{guid}/{status}</tt>

  <tt>GET /api/v1/search/search</tt>

  <tt>POST /api/v1/search/search</tt>

  <tt>POST /api/v1/search/group</tt>

  <tt>GET /api/v1/search/findOne</tt>

  <tt>GET /api/v1/search/column/metadata</tt>

  <tt>GET /api/v1/sensor/enrichment/config</tt>

  <tt>GET /api/v1/sensor/enrichment/config/list/available/enrichments</tt>

  <tt>GET /api/v1/sensor/enrichment/config/list/available/threat/triage/aggregators</tt>

  <tt>DELETE /api/v1/sensor/enrichment/config/{name}</tt>

  <tt>POST /api/v1/sensor/enrichment/config/{name}</tt>

  <tt>GET /api/v1/sensor/enrichment/config/{name}</tt>

  <tt>GET /api/v1/sensor/indexing/config</tt>

  <tt>DELETE /api/v1/sensor/indexing/config/{name}</tt>

  <tt>POST /api/v1/sensor/indexing/config/{name}</tt>

  <tt>GET /api/v1/sensor/indexing/config/{name}</tt>

  <tt>POST /api/v1/sensor/parser/config</tt>

  <tt>GET /api/v1/sensor/parser/config</tt>

  <tt>GET /api/v1/sensor/parser/config/list/available</tt>

  <tt>POST /api/v1/sensor/parser/config/parseMessage</tt>

  <tt>GET /api/v1/sensor/parser/config/reload/available</tt>

  <tt>DELETE /api/v1/sensor/parser/config/{name}</tt>

  <tt>GET /api/v1/sensor/parser/config/{name}</tt>

  <tt>POST /api/v1/stellar/apply/transformations</tt>

  <tt>GET /api/v1/stellar/list</tt>

  <tt>GET /api/v1/stellar/list/functions</tt>

  <tt>GET /api/v1/stellar/list/simple/functions</tt>

  <tt>POST /api/v1/stellar/validate/rules</tt>

  <tt>GET /api/v1/storm</tt>

  <tt>GET /api/v1/storm/client/status</tt>

  <tt>GET /api/v1/storm/enrichment</tt>

  <tt>GET /api/v1/storm/enrichment/activate</tt>

  <tt>GET /api/v1/storm/enrichment/deactivate</tt>

  <tt>GET /api/v1/storm/enrichment/start</tt>

  <tt>GET /api/v1/storm/enrichment/stop</tt>

  <tt>GET /api/v1/storm/indexing/batch</tt>

  <tt>GET /api/v1/storm/indexing/batch/activate</tt>

  <tt>GET /api/v1/storm/indexing/batch/deactivate</tt>

  <tt>GET /api/v1/storm/indexing/batch/start</tt>

  <tt>GET /api/v1/storm/indexing/batch/stop</tt>

  <tt>GET /api/v1/storm/indexing/randomaccess</tt>

  <tt>GET /api/v1/storm/indexing/randomaccess/activate</tt>

  <tt>GET /api/v1/storm/indexing/randomaccess/deactivate</tt>

  <tt>GET /api/v1/storm/indexing/randomaccess/start</tt>

  <tt>GET /api/v1/storm/indexing/randomaccess/stop</tt>

  <tt>GET /api/v1/storm/parser/activate/{name}</tt>

  <tt>GET /api/v1/storm/parser/deactivate/{name}</tt>

  <tt>GET /api/v1/storm/parser/start/{name}</tt>

  <tt>GET /api/v1/storm/parser/stop/{name}</tt>

  <tt>GET /api/v1/storm/{name}</tt>

  <tt>GET /api/v1/storm/supervisors</tt>

  <tt>PATCH /api/v1/update/patch</tt>

  <tt>PUT /api/v1/update/replace</tt>

  <tt>GET /api/v1/user</tt>

<tt>POST /api/v1/alerts/ui/escalate</tt>

Description: Escalates a list of alerts by producing it to the Kafka escalate topic

Input:

alerts - The alerts to be escalated

Returns:

200 - Alerts were escalated

<tt>GET /api/v1/alerts/ui/settings</tt>

Description: Retrieves the current user’s settings

Returns:

200 - User settings

404 - he current user does not have settings

<tt>GET /api/v1/alerts/ui/settings/all</tt>

Description: Retrieves all users’ settings.  Only users that are part of the “ROLE_ADMIN” role are allowed to get all user settings.

Returns:

200 - List of all user settings

403 - The current user does not have permission to get all user settings

<tt>DELETE /api/v1/alerts/ui/settings</tt>

Description: Deletes a user’s settings.  Only users that are part of the “ROLE_ADMIN” role are allowed to delete user settings.

Input:

user - The user whose settings will be deleted

Returns:

200 - User settings were deleted

403 - The current user does not have permission to delete user settings

404 - User settings could not be found

<tt>POST /api/v1/alerts/ui/settings</tt>

Description: Creates or updates the current user’s settings

Input:

alertsUIUserSettings - The user settings to be saved

Returns:

200 - User settings updated. Returns saved settings.

201 - User settings created. Returns saved settings.

<tt>GET /api/v1/global/config</tt>

Description: Retrieves the current Global Config from Zookeeper

Returns:

200 - Returns current Global Config JSON in Zookeeper

404 - Global Config JSON was not found in Zookeeper

<tt>DELETE /api/v1/global/config</tt>

Description: Deletes the current Global Config from Zookeeper

Returns:

200 - Global Config JSON was deleted

404 - Global Config JSON was not found in Zookeeper

<tt>POST /api/v1/global/config</tt>

Description: Creates or updates the Global Config in Zookeeper

Input:

globalConfig - The Global Config JSON to be saved

Returns:

200 - Global Config updated. Returns saved Global Config JSON

201 - Global Config created. Returns saved Global Config JSON

<tt>GET /api/v1/grok/get/statement</tt>

Description: Retrieves a Grok statement from the classpath

Input:

path - Path to classpath resource

Returns:

200 - Grok statement

<tt>GET /api/v1/grok/list</tt>

Description: Lists the common Grok statements available in Metron

Returns:

200 - JSON object containing pattern label/Grok statements key value pairs

<tt>POST /api/v1/grok/validate</tt>

Description: Applies a Grok statement to a sample message

Input:

grokValidation - Object containing Grok statement and sample message

Returns:

200 - JSON results

<tt>POST /api/v1/hdfs</tt>

Description: Writes contents to an HDFS file.  Warning: this will overwrite the contents of a file if it already exists. Permissions must be set for all three groups if they are to be set. If any are missing, the default permissions will be used, and if any are invalid an exception will be thrown.

Input:

path - Path to HDFS file

contents - File contents

userMode - [optional] symbolic permission string for user portion of the permissions to be set on the file written. For example ‘rwx’ or read, write, execute. The symbol ‘-’ is used to exclude that permission such as ‘rw-’ for read, write, no execute

groupMode - [optional] symbolic permission string for group portion of the permissions to be set on the file written. For example ‘rwx’ or read, write, execute. The symbol ‘-’ is used to exclude that permission such as ‘rw-’ for read, write, no execute

otherMode - [optional] symbolic permission string for other portion of the permissions to be set on the file written. For example ‘rwx’ or read, write, execute. The symbol ‘-’ is used to exclude that permission such as ‘rw-’ for read, write, no execute

Returns:

200 - Contents were written

<tt>GET /api/v1/hdfs</tt>

Description: Reads a file from HDFS and returns the contents

Input:

path - Path to HDFS file

Returns:

200 - Returns file contents

<tt>DELETE /api/v1/hdfs</tt>

Description: Deletes a file from HDFS

Input:

path - Path to HDFS file

recursive - Delete files recursively

Returns:

200 - File was deleted

404 - File was not found in HDFS

<tt>GET /api/v1/hdfs/list</tt>

Description: Lists an HDFS directory

Input:

path - Path to HDFS directory

Returns:

200 - HDFS directory list

<tt>GET /api/v1/kafka/topic</tt>

Description: Retrieves all Kafka topics

Returns:

200 - Returns a list of all Kafka topics

<tt>POST /api/v1/kafka/topic</tt>

Description: Creates a new Kafka topic

Input:

topic - Kafka topic

Returns:

200 - Returns saved Kafka topic

<tt>GET /api/v1/kafka/topic/{name}</tt>

Description: Retrieves a Kafka topic

Input:

name - Kafka topic name

Returns:

200 - Returns Kafka topic

404 - Kafka topic is missing

<tt>DELETE /api/v1/kafka/topic/{name}</tt>

Description: Deletes a Kafka topic

Input:

name - Kafka topic name

Returns:

200 - Kafka topic was deleted

404 - Kafka topic is missing

<tt>GET /api/v1/kafka/topic/{name}/sample</tt>

Description: Retrieves a sample message from a Kafka topic using the most recent offset

Input:

name - Kafka topic name

Returns:

200 - Returns sample message

404 - Either Kafka topic is missing or contains no messages

<tt>POST /api/v1/kafka/topic/{name}/produce</tt>

Description: Produces a message to a Kafka topic

Input:

name - Kafka topic name

message - message to be published

Returns:

200 - Published

404 - Kafka topic is missing

<tt>POST /api/v1/metaalert/searchByAlert</tt>

Description: Get all meta alerts that contain an alert.

Input:

guid - GUID of the alert

Returns:

200 - Search results

<tt>POST /api/v1/metaalert/create</tt>

Description: Creates a new meta alert from a list of existing alerts.  The meta alert status will initially be set to ‘ACTIVE’ and summary statistics will be computed from the list of alerts.  A list of groups included in the request are also added to the meta alert.

Input:

request - Meta alert create request which includes a list of alert get requests and a list of custom groups used to annotate a meta alert.

Returns:

200 - The GUID of the new meta alert

<tt>POST /api/v1/metaalert/add/alert</tt>

Description: Adds an alert to an existing meta alert.  An alert will not be added if it is already contained in a meta alert.

Input:

request - Meta alert add request which includes a meta alert GUID and list of alert get requests

Returns:

200 - Returns ‘true’ if the alert was added and ‘false’ if the meta alert did not change.

<tt>POST /api/v1/metaalert/remove/alert</tt>

Description: Removes an alert from an existing meta alert.  If the alert to be removed is not in a meta alert, ‘false’ will be returned.

Input:

request - Meta alert remove request which includes a meta alert GUID and list of alert get requests

Returns:

200 - Returns ‘true’ if the alert was removed and ‘false’ if the meta alert did not change.

<tt>POST /api/v1/metaalert/update/status/{guid}/{status}</tt>

Description: Updates the status of a meta alert to either ‘ACTIVE’ or ‘INACTIVE’.

Input:

guid - Meta alert GUID

status - Meta alert status with a value of either ‘ACTIVE’ or ‘INACTIVE’

Returns:

200 - Returns ‘true’ if the status changed and ‘false’ if it did not.

<tt>POST /api/v1/search/search</tt>

Description: Searches the indexing store. GUIDs must be quoted to ensure correct results.

Input:

searchRequest - Search request

Returns:

200 - Search response

<tt>POST /api/v1/search/group</tt>

Description: Searches the indexing store and returns field groups. GUIDs must be quoted to ensure correct results. Groups are hierarchical and nested in the order the fields appear in the ‘groups’ request parameter. The default sorting within groups is by count descending.  A groupOrder type of count will sort based on then number of documents in a group while a groupType of term will sort by the groupBy term.

Input:

groupRequest - Group request

indices - list of indices to search

query - lucene query

scoreField - field used to compute a total score for each group

groups - List of groups (field name and sort order)

Returns:

200 - Group response

<tt>GET /api/v1/search/findOne</tt>

Description: Returns latest document for a guid and sensor

Input:

getRequest - Get request

guid - message UUID

sensorType - Sensor Type

Example: Return <tt>bro</tt> document with UUID of <tt>000-000-0000</tt>

{
  "guid" : "000-000-0000",
  "sensorType" : "bro"
}

Returns:

200 - Document representing the output

404 - Document with UUID and sensor type not found

<tt>GET /api/v1/search/column/metadata</tt>

Description: Get index column metadata for a list of sensor types with duplicates removed.  Column names and types for each sensor are retrieved from the most recent index.  Columns that exist in multiple indices with different types will default to type ‘other’.

Input:

sensorTypes - Sensor Types

Returns:

200 - Column Metadata

<tt>GET /api/v1/sensor/enrichment/config</tt>

Description: Retrieves all SensorEnrichmentConfigs from Zookeeper

Returns:

200 - Returns all SensorEnrichmentConfigs

<tt>GET /api/v1/sensor/enrichment/config/list/available/enrichments</tt>

Description: Lists the available enrichments

Returns:

200 - Returns a list of available enrichments

<tt>GET /api/v1/sensor/enrichment/config/list/available/threat/triage/aggregators</tt>

Description: Lists the available threat triage aggregators

Returns:

200 - Returns a list of available threat triage aggregators

<tt>DELETE /api/v1/sensor/enrichment/config/{name}</tt>

Description: Deletes a SensorEnrichmentConfig from Zookeeper

Input:

name - SensorEnrichmentConfig name

Returns:

200 - SensorEnrichmentConfig was deleted

404 - SensorEnrichmentConfig is missing

<tt>POST /api/v1/sensor/enrichment/config/{name}</tt>

Description: Updates or creates a SensorEnrichmentConfig in Zookeeper

Input:

sensorEnrichmentConfig - SensorEnrichmentConfig

name - SensorEnrichmentConfig name

Returns:

200 - SensorEnrichmentConfig updated. Returns saved SensorEnrichmentConfig

201 - SensorEnrichmentConfig created. Returns saved SensorEnrichmentConfig

<tt>GET /api/v1/sensor/enrichment/config/{name}</tt>

Description: Retrieves a SensorEnrichmentConfig from Zookeeper

Input:

name - SensorEnrichmentConfig name

Returns:

200 - Returns SensorEnrichmentConfig

404 - SensorEnrichmentConfig is missing

<tt>GET /api/v1/sensor/indexing/config</tt>

Description: Retrieves all SensorIndexingConfigs from Zookeeper

Returns:

200 - Returns all SensorIndexingConfigs

<tt>DELETE /api/v1/sensor/indexing/config/{name}</tt>

Description: Deletes a SensorIndexingConfig from Zookeeper

Input:

name - SensorIndexingConfig name

Returns:

200 - SensorIndexingConfig was deleted

404 - SensorIndexingConfig is missing

<tt>POST /api/v1/sensor/indexing/config/{name}</tt>

Description: Updates or creates a SensorIndexingConfig in Zookeeper

Input:

sensorIndexingConfig - SensorIndexingConfig

name - SensorIndexingConfig name

Returns:

200 - SensorIndexingConfig updated. Returns saved SensorIndexingConfig

201 - SensorIndexingConfig created. Returns saved SensorIndexingConfig

<tt>GET /api/v1/sensor/indexing/config/{name}</tt>

Description: Retrieves a SensorIndexingConfig from Zookeeper

Input:

name - SensorIndexingConfig name

Returns:

200 - Returns SensorIndexingConfig

404 - SensorIndexingConfig is missing

<tt>POST /api/v1/sensor/parser/config/{name}</tt>

Description: Updates or creates a SensorParserConfig in Zookeeper

Input:

sensorParserConfig - SensorParserConfig

name - SensorEnrichmentConfig name

Returns:

200 - SensorParserConfig updated. Returns saved SensorParserConfig

201 - SensorParserConfig created. Returns saved SensorParserConfig

<tt>GET /api/v1/sensor/parser/config</tt>

Description: Retrieves all SensorParserConfigs from Zookeeper

Returns:

200 - Returns all SensorParserConfigs

<tt>GET /api/v1/sensor/parser/config/list/available</tt>

Description: Lists the available parser classes that can be found on the classpath

Returns:

200 - Returns a list of available parser classes

<tt>POST /api/v1/sensor/parser/config/parseMessage</tt>

Description: Parses a sample message given a SensorParserConfig

Input:

parseMessageRequest - Object containing a sample message and SensorParserConfig

Returns:

200 - Returns parsed message

<tt>GET /api/v1/sensor/parser/config/reload/available</tt>

Description: Scans the classpath for available parser classes and reloads the cached parser class list

Returns:

200 - Returns a list of available parser classes

<tt>DELETE /api/v1/sensor/parser/config/{name}</tt>

Description: Deletes a SensorParserConfig from Zookeeper

Input:

name - SensorParserConfig name

Returns:

200 - SensorParserConfig was deleted

404 - SensorParserConfig is missing

<tt>GET /api/v1/sensor/parser/config/{name}</tt>

Description: Retrieves a SensorParserConfig from Zookeeper

Input:

name - SensorParserConfig name

Returns:

200 - Returns SensorParserConfig

404 - SensorParserConfig is missing

<tt>POST /api/v1/stellar/apply/transformations</tt>

Description: Executes transformations against a sample message

Input:

transformationValidation - Object containing SensorParserConfig and sample message

Returns:

200 - Returns transformation results

<tt>GET /api/v1/stellar/list</tt>

Description: Retrieves field transformations

Returns:

200 - Returns a list field transformations

<tt>GET /api/v1/stellar/list/functions</tt>

Description: Lists the Stellar functions that can be found on the classpath

Returns:

200 - Returns a list of Stellar functions

<tt>GET /api/v1/stellar/list/simple/functions</tt>

Description: Lists the simple Stellar functions (functions with only 1 input) that can be found on the classpath

Returns:

200 - Returns a list of simple Stellar functions

<tt>POST /api/v1/stellar/validate/rules</tt>

Description: Tests Stellar statements to ensure they are well-formed

Input:

statements - List of statements to validate

Returns:

200 - Returns validation results

<tt>GET /api/v1/storm</tt>

Description: Retrieves the status of all Storm topologies

Returns:

200 - Returns a list of topologies with status information

<tt>GET /api/v1/storm/client/status</tt>

Description: Retrieves information about the Storm command line client

Returns:

200 - Returns storm command line client information

<tt>GET /api/v1/storm/enrichment</tt>

Description: Retrieves the status of the Storm enrichment topology

Returns:

200 - Returns topology status information

404 - Topology is missing

<tt>GET /api/v1/storm/enrichment/activate</tt>

Description: Activates a Storm enrichment topology

Returns:

200 - Returns activate response message

<tt>GET /api/v1/storm/enrichment/deactivate</tt>

Description: Deactivates a Storm enrichment topology

Returns:

200 - Returns deactivate response message

<tt>GET /api/v1/storm/enrichment/start</tt>

Description: Starts a Storm enrichment topology

Returns:

200 - Returns start response message

<tt>GET /api/v1/storm/enrichment/stop</tt>

Description: Stops a Storm enrichment topology

Input:

stopNow - Stop the topology immediately

Returns:

200 - Returns stop response message

<tt>GET /api/v1/storm/indexing/batch</tt>

Description: Retrieves the status of the Storm batch indexing topology

Returns:

200 - Returns topology status information

404 - Topology is missing

<tt>GET /api/v1/storm/indexing/batch/activate</tt>

Description: Activates a Storm batch indexing topology

Returns:

200 - Returns activate response message

<tt>GET /api/v1/storm/indexing/batch/deactivate</tt>

Description: Deactivates a Storm batch indexing topology

Returns:

200 - Returns deactivate response message

<tt>GET /api/v1/storm/indexing/batch/start</tt>

Description: Starts a Storm batch indexing topology

Returns:

200 - Returns start response message

<tt>GET /api/v1/storm/indexing/batch/stop</tt>

Description: Stops a Storm batch indexing topology

Input:

stopNow - Stop the topology immediately

Returns:

200 - Returns stop response message

<tt>GET /api/v1/storm/indexing/randomaccess</tt>

Description: Retrieves the status of the Storm randomaccess indexing topology

Returns:

200 - Returns topology status information

404 - Topology is missing

<tt>GET /api/v1/storm/indexing/randomaccess/activate</tt>

Description: Activates a Storm randomaccess indexing topology

Returns:

200 - Returns activate response message

<tt>GET /api/v1/storm/indexing/randomaccess/deactivate</tt>

Description: Deactivates a Storm randomaccess indexing topology

Returns:

200 - Returns deactivate response message

<tt>GET /api/v1/storm/indexing/randomaccess/start</tt>

Description: Starts a Storm randomaccess indexing topology

Returns:

200 - Returns start response message

<tt>GET /api/v1/storm/indexing/randomaccess/stop</tt>

Description: Stops a Storm randomaccess indexing topology

Input:

stopNow - Stop the topology immediately

Returns:

200 - Returns stop response message

<tt>GET /api/v1/storm/parser/activate/{name}</tt>

Description: Activates a Storm parser topology

Input:

name - Parser name

Returns:

200 - Returns activate response message

<tt>GET /api/v1/storm/parser/deactivate/{name}</tt>

Description: Deactivates a Storm parser topology

Input:

name - Parser name

Returns:

200 - Returns deactivate response message

<tt>GET /api/v1/storm/parser/start/{name}</tt>

Description: Starts a Storm parser topology

Input:

name - Parser name

Returns:

200 - Returns start response message

<tt>GET /api/v1/storm/parser/stop/{name}</tt>

Description: Stops a Storm parser topology

Input:

name - Parser name

stopNow - Stop the topology immediately

Returns:

200 - Returns stop response message

<tt>GET /api/v1/storm/{name}</tt>

Description: Retrieves the status of a Storm topology

Input:

name - Topology name

Returns:

200 - Returns topology status information

404 - Topology is missing

<tt>GET /api/v1/storm/supervisors</tt>

Description: Retrieves the status of all Storm Supervisors

Returns:

200 - Returns a list of the status of all Storm Supervisors

<tt>PATCH /api/v1/update/patch</tt>

Description: Update a document with a patch

Input:

request - Patch Request

guid - The Patch UUID

sensorType - The sensor type

patch - An array of RFC 6902 patches.

Example adding a field called <tt>project</tt> with value <tt>metron</tt> to the <tt>bro</tt> message with UUID of <tt>000-000-0000</tt> :

{
   "guid" : "000-000-0000",
   "sensorType" : "bro",
   "patch" : [
    {
              "op": "add"
             , "path": "/project"
             , "value": "metron"
    }
            ]
 }

Returns:

200 - nothing

404 - document not found

<tt>PUT /api/v1/update/replace</tt>

Description: Replace a document

Input:

request - Replacement request

guid - The Patch UUID

sensorType - The sensor type

replacement - A Map representing the replaced document

Example replacing a <tt>bro</tt> message with guid of <tt>000-000-0000</tt> :

{
  "guid" : "000-000-0000",
  "sensorType" : "bro",
  "replacement" : {
    "source:type": "bro",
    "guid" : "bro_index_2017.01.01.01:1",
    "ip_src_addr":"192.168.1.2",
    "ip_src_port": 8009,
    "timestamp":200,
    "rejected":false
  }
}

Returns:

200 - Current user

<tt>GET /api/v1/user</tt>

Description: Retrieves the current user

Returns:

200 - Current user

Testing

Profiles are includes for both the metron-docker and Full Dev environments.

metron-docker

Start the metron-docker environment.  Build the metron-rest module and start it with the Spring Boot Maven plugin:

mvn clean package
mvn spring-boot:run -Drun.profiles=docker,dev

The metron-rest application will be available at http://localhost:8080/swagger-ui.html#/.

Full Dev

Start the development environment.  Build the metron-rest module and start it with the Spring Boot Maven plugin:

mvn clean package
mvn spring-boot:run -Drun.profiles=vagrant,dev

The metron-rest application will be available at http://localhost:8080/swagger-ui.html#/.

To run the application locally on the Full Dev host (node1), follow the Installation instructions above.  Then set the METRON_SPRING_PROFILES_ACTIVE variable in <tt>/etc/default/metron</tt>:

METRON_SPRING_PROFILES_ACTIVE="vagrant,dev"

and start the application:

service metron-rest start

In a cluster with Kerberos enabled, update the security settings in <tt>/etc/default/metron</tt>.  Security is disabled by default in the <tt>vagrant</tt> Spring profile so that setting must be overriden with the METRON_SPRING_OPTIONS variable:

METRON_SPRING_PROFILES_ACTIVE="vagrant,dev"
METRON_JVMFLAGS="-Djava.security.auth.login.config=$METRON_HOME/client_jaas.conf"
METRON_SPRING_OPTIONS="--kerberos.enabled=true"

The metron-rest application will be available at http://node1:8082/swagger-ui.html#/.

License

This project depends on the Java Transaction API.  See https://java.net/projects/jta-spec/ for more details.

© 2015-2016 The Apache Software Foundation. Apache Metron, Metron, Apache, the Apache feather logo,
            and the Apache Metron project logo are trademarks of The Apache Software Foundation.


text:
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _

from reversion.admin import VersionAdmin

from .models import Team, Membership
from .hooks import hookset

def members_count(obj):
    return obj.memberships.count()
members_count.short_description = _("Members Count")

admin.site.register(
    Team,
    list_display=["name", "member_access", "manager_access", members_count, "creator"],
    fields=[
        "name",
        "slug",
        "avatar",
        "description",
        "member_access",
        "manager_access",
        "creator"
    ],
    prepopulated_fields={"slug": ("name",)},
    raw_id_fields=["creator"]
)

class MembershipAdmin(VersionAdmin):
    raw_id_fields = ["user"]
    list_display = ["team", "user", "state", "role"]
    list_filter = ["team"]
    search_fields = hookset.membership_search_fields

admin.site.register(Membership, MembershipAdmin)


text:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorAccent">

    <com.jjoe64.graphview.GraphView
        android:id="@+id/graph"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"/>

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminateTint="@color/text_normal"
        android:indeterminate="true"
        android:layout_centerInParent="true"/>

    <TextView
        android:id="@+id/empty_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/text_normal"
        android:text="@string/error_when_fetching"
        android:layout_centerInParent="true"
        android:visibility="gone"/>

</RelativeLayout>


text:
    <title>Intermediate SDO Samples</title>

Intermediate Service Data Object (SDO) Sample Programs

Running the Samples
 See the main overview for instructions on how to run these
samples.


text:
//#region License
//
//#endregion
//namespace System.Primitives.Codecs
//{
//    /// <summary>
//    /// Provides standardized encode/decode functionality to/from an encrypted format.
//    /// </summary>
//    public class CryptCodec : ICodec
//    {
//        /// <summary>
//        /// Initializes a new instance of the <see cref="CryptCodec"/> class.
//        /// </summary>
//        public CryptCodec()
//        {
//            //Configuration.KernelApplicationUnitConfiguration applicationUnitConfig;
//            //if ((KernelFactory.s_applicationUnitConfigHash.Count == 0) || ((applicationUnitConfig = KernelFactory.s_applicationUnitConfigHash[Kernel.ApplicationUnit]) == null))
//            //{
//            //    throw new InvalidOperationException(string.Format(Kernel.Local.UndefinedApplicationUnitA, Kernel.ApplicationUnit));
//            //}
//            //Crypt = new Crypt(applicationUnitConfig.CryptConfigPath, applicationUnitConfig.CryptPublicKey);
//        }

//        ///// <summary>
//        ///// Gets the crypt.
//        ///// </summary>
//        ///// <value>The crypt.</value>
//        //public Crypt Crypt { get; private set; }

//        /// <summary>
//        /// Abstract member whose implementation by the derived class decodes a string into another string.
//        /// </summary>
//        /// <param name="text">String to decode.</param>
//        /// <returns>
//        /// Returns results of decoding <paramref name="text"/> object instance.
//        /// </returns>
//        public static string Decode(string text)
//        {
//            throw new NotImplementedException();
//            //return Crypt.Decode(text);
//        }

//        /// <summary>
//        /// Abstract member whose implementation by the derived class encodes a string into another string.
//        /// </summary>
//        /// <param name="text">String to decode.</param>
//        /// <returns>
//        /// Returns results of decoding <paramref name="text"/> object instance.
//        /// </returns>
//        public static string Encode(string text)
//        {
//            throw new NotImplementedException();
//            //return Crypt.Encode(text);
//        }

//        /// <summary>
//        /// Abstract member whose implementation by the derived class decodes a string into another string.
//        /// </summary>
//        /// <param name="text">String to decode.</param>
//        /// <returns>
//        /// Returns results of decoding <paramref name="text"/> object instance.
//        /// </returns>
//        string ICodec.Decode(string text) { return Decode(text); }

//        /// <summary>
//        /// Abstract member whose implementation by the derived class encodes a string into another string.
//        /// </summary>
//        /// <param name="text">String to decode.</param>
//        /// <returns>
//        /// Returns results of decoding <paramref name="text"/> object instance.
//        /// </returns>
//        string ICodec.Encode(string text) { return Encode(text); }
//    }
//}


text:
.class Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings$1;
.super Landroid/database/ContentObserver;
.source "NavigationBarHideButtonAppsSettings.java"

# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
    value = Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = null
.end annotation

# instance fields
.field final synthetic this$0:Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;

# direct methods
.method constructor <init>(Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;Landroid/os/Handler;)V
    .locals 0

    iput-object p1, p0, Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings$1;->this$0:Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;

    invoke-direct {p0, p2}, Landroid/database/ContentObserver;-><init>(Landroid/os/Handler;)V

    return-void
.end method

# virtual methods
.method public onChange(Z)V
    .locals 4

    iget-object v1, p0, Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings$1;->this$0:Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;

    invoke-static {v1}, Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;->-get10(Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;)Lcom/android/settings/widget/SwitchBar;

    move-result-object v1

    if-eqz v1, :cond_0

    iget-object v1, p0, Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings$1;->this$0:Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;

    invoke-static {v1}, Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;->-wrap0(Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;)Landroid/content/ContentResolver;

    move-result-object v1

    const-string/jumbo v2, "navigationbar_hide_bar"

    const/4 v3, 0x1

    invoke-static {v1, v2, v3}, Landroid/provider/Settings$Global;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I

    move-result v1

    if-eqz v1, :cond_1

    const/4 v0, 0x1

    :goto_0
    iget-object v1, p0, Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings$1;->this$0:Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;

    invoke-static {v1}, Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;->-get10(Lcom/samsung/android/settings/navigationbar/NavigationBarHideButtonAppsSettings;)Lcom/android/settings/widget/SwitchBar;

    move-result-object v1

    invoke-virtual {v1, v0}, Lcom/android/settings/widget/SwitchBar;->setChecked(Z)V

    :cond_0
    return-void

    :cond_1
    const/4 v0, 0x0

    goto :goto_0
.end method


text:
package org.apache.camel.component.aws.cloudtrail;

import org.apache.camel.Category;
import org.apache.camel.Consumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.component.aws.cloudtrail.client.CloudtrailClientFactory;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.support.ScheduledPollEndpoint;
import org.apache.camel.util.ObjectHelper;
import software.amazon.awssdk.services.cloudtrail.CloudTrailClient;

/**
 * Consume events from Amazon Cloudtrail using AWS SDK version 2.x.
 */
@UriEndpoint(firstVersion = "3.19.0", scheme = "aws-cloudtrail", title = "AWS Cloudtrail", syntax = "aws-cloudtrail:label",
             consumerOnly = true,
             category = { Category.CLOUD, Category.EVENTBUS }, headersClass = CloudtrailConstants.class)
public class CloudtrailEndpoint extends ScheduledPollEndpoint {

    @UriParam
    private CloudtrailConfiguration configuration;

    private CloudTrailClient cloudTrailClient;

    public CloudtrailEndpoint(String uri, CloudtrailConfiguration configuration, CloudtrailComponent component) {
        super(uri, component);
        this.configuration = configuration;
    }

    @Override
    protected void doStart() throws Exception {
        super.doStart();
        cloudTrailClient = configuration.getCloudTrailClient() != null
                ? configuration.getCloudTrailClient()
                : CloudtrailClientFactory.getCloudtrailClient(configuration).getCloudtrailClient();
    }

    @Override
    public void doStop() throws Exception {
        if (ObjectHelper.isEmpty(configuration.getCloudTrailClient())) {
            if (cloudTrailClient != null) {
                cloudTrailClient.close();
            }
        }
        super.doStop();
    }

    @Override
    public Producer createProducer() throws Exception {
        throw new UnsupportedOperationException("You cannot produce messages to this endpoint");
    }

    @Override
    public Consumer createConsumer(Processor processor) throws Exception {
        final CloudtrailConsumer consumer = new CloudtrailConsumer(this, processor);
        consumer.setSchedulerProperties(getSchedulerProperties());
        configureConsumer(consumer);
        return consumer;
    }

    public CloudTrailClient getClient() {
        return cloudTrailClient;
    }

    public CloudtrailConfiguration getConfiguration() {
        return configuration;
    }
}


text:
[![Circle CI](https://circleci.com/gh/ahamidi/glasses.svg?style=svg)](https://circleci.com/gh/ahamidi/glasses)
[![GoDoc](https://godoc.org/github.com/ahamidi/glasses?status.svg)](https://godoc.org/github.com/ahamidi/glasses)

![Glasses by Kyle Scott] (https://s3.amazonaws.com/ahamidi-public/glasses.png)
## Glasses
Go package for the [Google Cloud Vision API](https://cloud.google.com/vision/)

### TODO

- [x] Auth
- [x] Request
- [ ] Tests
- [ ] Docs
- [ ] CI

### Usage

#### CLI Tool

* Build: `go build ./cmd/glasses`
* Run: `./glasses -f image.jpg`

### Requirements

* Authentication:
    Authentication depends on [Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials). Setting that up is beyond the scope of this project, but essentially requires the creation of a `Service Account`, download the JSON formatted credentials and setting an Env Var to point at it.

### Logo
Glasses Icon by Kyle Scott from Noun Project


text:
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <parameters>
        <parameter key="assetic.filter.uglifyjs2.class">Assetic\Filter\UglifyJs2Filter</parameter>
        <parameter key="assetic.filter.uglifyjs2.bin">/usr/bin/uglifyjs</parameter>
        <parameter key="assetic.filter.uglifyjs2.node">%assetic.node.bin%</parameter>
        <parameter key="assetic.filter.uglifyjs2.node_paths">%assetic.node.paths%</parameter>
        <parameter key="assetic.filter.uglifyjs2.compress">false</parameter>
        <parameter key="assetic.filter.uglifyjs2.beautify">false</parameter>
        <parameter key="assetic.filter.uglifyjs2.mangle">false</parameter>
    </parameters>

    <services>
        <service id="assetic.filter.uglifyjs2" class="%assetic.filter.uglifyjs2.class%">
            <tag name="assetic.filter" alias="uglifyjs2" />
            <argument>%assetic.filter.uglifyjs2.bin%</argument>
            <argument>%assetic.filter.uglifyjs2.node%</argument>
            <call method="setNodePaths">
                <argument>%assetic.filter.uglifyjs2.node_paths%</argument>
            </call>
            <call method="setCompress">
                <argument>%assetic.filter.uglifyjs2.compress%</argument>
            </call>
            <call method="setBeautify">
                <argument>%assetic.filter.uglifyjs2.beautify%</argument>
            </call>
            <call method="setMangle">
                <argument>%assetic.filter.uglifyjs2.mangle%</argument>
            </call>
        </service>
    </services>
</container>


text:
CREATE TABLE IF NOT EXISTS `comment` (
	`id` int(11) NULL DEFAULT 0,
	`tstamp` int(11) NULL DEFAULT 0,
	`name` varchar(60) NULL DEFAULT '0',
	`comment` TEXT(255) NULL,
	`link` varchar(255) NULL DEFAULT '0'
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

ALTER TABLE `comment` ADD PRIMARY KEY (`id`);
ALTER TABLE `comment` MODIFY `id` int(11) unsigned NOT NULL AUTO_INCREMENT;


text:
'use strict';
const buildAngularFile = require('./lib/baseTypes/buildAngularFile');
const codeStyleContext = require('./lib/codeStyling/codeStyleContext');

const components = new Map();
components.set('factory', (options) => buildAngularFile.buildFunctionFile(options, 'factory'));
components.set('controller', (options) => buildAngularFile.buildFunctionFile(options, 'controller'));
components.set('service', (options) => buildAngularFile.buildFunctionFile(options, 'service'));
components.set('directive', (options) => buildAngularFile.buildFunctionFile(options, 'directive'));
components.set('constant', (options) => buildAngularFile.buildValueFile(options, 'constant'));
components.set('value', (options) => buildAngularFile.buildValueFile(options, 'value'));
components.set('config', (options) => buildAngularFile.buildFunctionFile(options, 'config'));
components.set('run', (options) => buildAngularFile.buildFunctionFile(options, 'config'));
components.set('route', (options) => buildAngularFile.buildFunctionFile(options, 'route'));
components.set('provider', (options) => buildAngularFile.buildFunctionFile(options, 'provider'));
components.set('filter', (options) => buildAngularFile.buildFunctionFile(options, 'filter'));
components.set('component', (options) => buildAngularFile.buildValueFile(options, 'component'));

module.exports = {
    setPreferences: codeStyleContext.setPreferences,
    buildFactory: (options) => components.get('factory')(options),
    buildController: (options) => components.get('controller')(options),
    buildService: (options) => components.get('service')(options),
    buildDirective: (options) => components.get('directive')(options),
    buildConstant: (options) => components.get('constant')(options),
    buildValue: (options) => components.get('value')(options),
    buildConfig: (options) => components.get('config')(options),
    buildRun: (options) => components.get('run')(options),
    buildRoute: (options) => components.get('route')(options),
    buildProvider: (options) => components.get('provider')(options),
    buildFilter: (options) => components.get('filter')(options),
    buildComponent: (options) => components.get('component')(options),
    buildModule: (options) => buildAngularFile.buildModuleFile(options),
    buildModuleExports: (options) => buildAngularFile.buildModuleExportFile(options),
    buildExternalModuleExports: (options) => buildAngularFile.buildExternalModuleExportFile(options),
    buildAngularComponent: (type, options) => {
        if (components.has(type)) {
            return components.get(type)(options);
        }
        throw new Error(`type ${type} not a defined component.`);
    }
};


text:
package scaladex.core.api

import endpoints4s.algebra

// Autocompletion endpoints are implemented by the server and invoked by the web client.
// There definition is shared here, for consistency.
trait SearchEndpoints extends algebra.Endpoints with algebra.JsonEntitiesFromSchemas {

  implicit val autocompletionResponse: JsonSchema[AutocompletionResponse] =
    field[String]("organization")
      .zip(field[String]("repository"))
      .zip(field[String]("description"))
      .xmap[AutocompletionResponse] {
        case (organization, repository, description) => AutocompletionResponse(organization, repository, description)
      } { autocompletionResponse =>
        (autocompletionResponse.organization, autocompletionResponse.repository, autocompletionResponse.description)
      }

  // Definition of the autocompletion query format
  val autocompletionParams: QueryString[AutocompletionParams] = (
    qs[String]("q", docs = Some("Main query (e.g., 'json', 'testing', etc.)")) &
      qs[Option[String]]("you", docs = Some("Used internally by Scaladex web user interface"))
        .xmap[Boolean](_.contains("✓"))(Option.when(_)("✓")) &
      qs[Seq[String]]("topics", docs = Some("Filter the results matching the given topics only")) &
      qs[Seq[String]](
        "languages",
        docs = Some(
          "Filter the results matching the given language versions only (e.g., '3', '2.13', '2.12', '2.11', 'java')"
        )
      ) &
      qs[Seq[String]](
        "platforms",
        docs = Some("Filter the results matching the given platforms only (e.g., 'jvm', 'sjs1', 'native0.4', 'sbt1.0')")
      ) &
      qs[Option[Boolean]]("contributingSearch").xmap(_.getOrElse(false))(Option.when(_)(true))
  ).xmap((AutocompletionParams.apply _).tupled)(Function.unlift(AutocompletionParams.unapply))

  // Autocomplete endpoint definition
  val autocomplete: Endpoint[AutocompletionParams, Seq[AutocompletionResponse]] =
    endpoint(
      get(path / "api" / "autocomplete" /? autocompletionParams),
      ok(jsonResponse[Seq[AutocompletionResponse]])
    )

}


text:
package apple.phase.enums;

import org.moe.natj.general.ann.Generated;
import org.moe.natj.general.ann.NInt;

/**
 * [@enum] PHASEPlaybackMode
 * <p>
 * Playback mode.
 * [@constant] PHASEPlaybackModeOneShot
 * Play the sound asset once, then stop.
 * [@constant] PHASEPlaybackModeLooping
 * Loop the sound asset indefinitely.
 */
@Generated
public final class PHASEPlaybackMode {
    @Generated
    private PHASEPlaybackMode() {
    }

    @Generated @NInt public static final long OneShot = 0x0000000000000000L;
    @Generated @NInt public static final long Looping = 0x0000000000000001L;
}


text:
package nginx

import (
	"archive/tar"
	"compress/gzip"
	"fmt"
	"io"
	"net/http"
	"os"
	"path"
	"strings"
)

// MaxmindLicenseKey maxmind license key to download databases
var MaxmindLicenseKey = ""

// MaxmindEditionIDs maxmind editions (GeoLite2-City, GeoLite2-Country, GeoIP2-ISP, etc)
var MaxmindEditionIDs = ""

// MaxmindEditionFiles maxmind databases on disk
var MaxmindEditionFiles []string

// MaxmindMirror maxmind database mirror url (http://geoip.local)
var MaxmindMirror = ""

const (
	geoIPPath   = "/etc/nginx/geoip"
	dbExtension = ".mmdb"

	maxmindURL = "https://download.maxmind.com/app/geoip_download?license_key=%v&edition_id=%v&suffix=tar.gz"
)

// GeoLite2DBExists checks if the required databases for
// the GeoIP2 NGINX module are present in the filesystem
func GeoLite2DBExists() bool {
	for _, dbName := range strings.Split(MaxmindEditionIDs, ",") {
		if !fileExists(path.Join(geoIPPath, dbName+dbExtension)) {
			return false
		}
	}

	return true
}

// DownloadGeoLite2DB downloads the required databases by the
// GeoIP2 NGINX module using a license key from MaxMind.
func DownloadGeoLite2DB() error {
	for _, dbName := range strings.Split(MaxmindEditionIDs, ",") {
		err := downloadDatabase(dbName)
		if err != nil {
			return err
		}
		MaxmindEditionFiles = append(MaxmindEditionFiles, dbName+dbExtension)
	}
	return nil
}

func createURL(mirror, licenseKey, dbName string) string {
	if len(mirror) > 0 {
		return fmt.Sprintf("%s/%s.tar.gz", mirror, dbName)
	}
	return fmt.Sprintf(maxmindURL, licenseKey, dbName)
}

func downloadDatabase(dbName string) error {
	url := createURL(MaxmindMirror, MaxmindLicenseKey, dbName)
	req, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		return err
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}

	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("HTTP status %v", resp.Status)
	}

	archive, err := gzip.NewReader(resp.Body)
	if err != nil {
		return err
	}
	defer archive.Close()

	mmdbFile := dbName + dbExtension

	tarReader := tar.NewReader(archive)
	for true {
		header, err := tarReader.Next()
		if err == io.EOF {
			break
		}

		if err != nil {
			return err
		}

		switch header.Typeflag {
		case tar.TypeReg:
			if !strings.HasSuffix(header.Name, mmdbFile) {
				continue
			}

			outFile, err := os.Create(path.Join(geoIPPath, mmdbFile))
			if err != nil {
				return err
			}

			defer outFile.Close()

			if _, err := io.CopyN(outFile, tarReader, header.Size); err != nil {
				return err
			}

			return nil
		}
	}

	return fmt.Errorf("the URL %v does not contains the database %v",
		fmt.Sprintf(maxmindURL, "XXXXXXX", dbName), mmdbFile)
}

// ValidateGeoLite2DBEditions check provided Maxmind database editions names
func ValidateGeoLite2DBEditions() error {
	allowedEditions := map[string]bool{
		"GeoIP2-Anonymous-IP":    true,
		"GeoIP2-Country":         true,
		"GeoIP2-City":            true,
		"GeoIP2-Connection-Type": true,
		"GeoIP2-Domain":          true,
		"GeoIP2-ISP":             true,
		"GeoIP2-ASN":             true,
		"GeoLite2-ASN":           true,
		"GeoLite2-Country":       true,
		"GeoLite2-City":          true,
	}

	for _, edition := range strings.Split(MaxmindEditionIDs, ",") {
		if !allowedEditions[edition] {
			return fmt.Errorf("unknown Maxmind GeoIP2 edition name: '%s'", edition)
		}
	}
	return nil
}

func fileExists(filePath string) bool {
	info, err := os.Stat(filePath)
	if os.IsNotExist(err) {
		return false
	}

	return !info.IsDir()
}


text:
import Ember from 'ember';

export default Ember.Service.extend({
  tezViewURL: null,
  // replace used to avoid slash duplication by proxy
  tezApiURL: '/api/v1/views/TEZ'.replace(/^\/\//, '/'),
  tezURLPrefix: '/views/TEZ',
  tezDagPath: '?viewPath=/#/dag/',
  getTezViewInfo: function () {
    this.set('error', null);
    if (this.get('isTezViewAvailable')) {
      return;
    }

    var self = this;
    Ember.$.getJSON(this.get('tezApiURL'))
      .then(function (response) {
        self.getTezViewInstance(response);
      })
      .fail(function (response) {
        self.setTezViewError(response);
      });
  },

  getTezViewInstance: function (data) {
    var self = this;
    var url = this.get('tezApiURL') + '/versions/' + data.versions[0].ViewVersionInfo.version;

    Ember.$.getJSON(url)
      .then(function (response) {
        if (!response.instances.length) {
          self.setTezViewError(response);
          return;
        }

        self.set('isTezViewAvailable', true);

        var instance = response.instances[0].ViewInstanceInfo;
        self.setTezViewURL(instance);
      });
  },

  setTezViewURL: function (instance) {
    var url = "%@/%@/%@/".fmt(
      this.get('tezURLPrefix'),
      instance.version,
      instance.instance_name
    );
    this.set('tezViewURL', url);
  },
  setTezViewError: function (data) {
    // status: 404 => Tev View isn't deployed
    if (data.status && data.status === 404) {
      this.set('error', 'tez.errors.not.deployed');
      this.set('errorMsg', 'Tez view not deployed');
    } else if (data.instances && !data.instances.length) { // no instance created
      this.set('error', 'tez.errors.no.instance');
      this.set('errorMsg', 'Tez view instance not created');
    } else {
      this.set('error', 'error');
      this.set('errorMsg', 'Error occurred while dispaying TEZ UI');
    }
  },
  getTezViewData(){
    let tezData = {};
    if(this.get('error')){
      tezData.error = this.get('error');
      tezData.errorMsg = this.get('errorMsg');
    } else {
      tezData.tezUrl = this.get('tezViewURL') + this.get("tezDagPath");
    }
    return tezData;
  }
});


text:
package org.apache.tomcat.jni;

/** ProcErrorCallback Interface
 *
 * @author Mladen Turk
 * @version $Revision: 515 $, $Date: 2008-03-17 22:02:23 +0100 (Mon, 17 Mar 2008) $
 */

public interface ProcErrorCallback {

    /**
     * Called in the child process if APR encounters an error
     * in the child prior to running the specified program.
     * @param pool Pool associated with the apr_proc_t.  If your child
     *             error function needs user data, associate it with this
     *             pool.
     * @param err APR error code describing the error
     * @param description Text description of type of processing which failed
     */
    public void callback(long pool, int err, String description);
}


text:
package org.searchisko.persistence.jpa.model;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.junit.Assert;
import org.junit.Test;
import org.searchisko.api.testtools.TestUtils;
import org.searchisko.persistence.service.ContentTuple;

/**
 * Unit test for {@link ContributorConverter}
 *
 * @author Libor Krzyzanek
 * @author Vlastimil Elias (velias at redhat dot com)
 *
 */
public class ContributorConverterTest {

	@Test
	public void convertToModel() throws IOException {
		ContributorConverter converter = new ContributorConverter();
		Map<String, Object> data = new LinkedHashMap<String, Object>();

		data.put("code", "John Doe<john@doe.com>");
		List<String> emails = new ArrayList<String>();
		emails.add("john@doe.com");
		data.put("email", emails);
		data.put("name", "John Doé");

		Contributor c = converter.convertToModel("10", data);

		TestUtils.assertJsonContent(
				"{\"code\": \"John Doe<john@doe.com>\", \"email\":[\"john@doe.com\"], \"name\": \"John Doé\"}", c.getValue());

	}

	@Test
	public void convertToContentTuple() throws IOException {
		ContributorConverter tested = new ContributorConverter();

		Contributor jpaEntity = new Contributor();
		jpaEntity.setId("myid");
		jpaEntity.setValue("{\"code\": \"John Doe<john@doe.com>\"}");
		ContentTuple<String, Map<String, Object>> result = tested.convertToContentTuple(jpaEntity);
		Assert.assertEquals("myid", result.getId());
		Assert.assertNotNull(result.getContent());
		Assert.assertEquals("John Doe<john@doe.com>", result.getContent().get("code"));
	}
}


text:
<?php

namespace Magento\Tools\Dependency\Report\Dependency\Data;

use Magento\TestFramework\Helper\ObjectManager;

class ModuleTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var \Magento\Tools\Dependency\Report\Dependency\Data\Dependency|\PHPUnit_Framework_MockObject_MockObject
     */
    protected $dependencyFirst;

    /**
     * @var \Magento\Tools\Dependency\Report\Dependency\Data\Dependency|\PHPUnit_Framework_MockObject_MockObject
     */
    protected $dependencySecond;

    /**
     * @var \Magento\Tools\Dependency\Report\Dependency\Data\Module
     */
    protected $module;

    public function setUp()
    {
        $this->dependencyFirst = $this->getMock(
            'Magento\Tools\Dependency\Report\Dependency\Data\Dependency',
            [],
            [],
            '',
            false
        );
        $this->dependencySecond = $this->getMock(
            'Magento\Tools\Dependency\Report\Dependency\Data\Dependency',
            [],
            [],
            '',
            false
        );

        $objectManagerHelper = new ObjectManager($this);
        $this->module = $objectManagerHelper->getObject(
            'Magento\Tools\Dependency\Report\Dependency\Data\Module',
            ['name' => 'name', 'dependencies' => [$this->dependencyFirst, $this->dependencySecond]]
        );
    }

    public function testGetName()
    {
        $this->assertEquals('name', $this->module->getName());
    }

    public function testGetDependencies()
    {
        $this->assertEquals([$this->dependencyFirst, $this->dependencySecond], $this->module->getDependencies());
    }

    public function testGetDependenciesCount()
    {
        $this->assertEquals(2, $this->module->getDependenciesCount());
    }

    public function testGetHardDependenciesCount()
    {
        $this->dependencyFirst->expects($this->once())->method('isHard')->will($this->returnValue(true));
        $this->dependencyFirst->expects($this->never())->method('isSoft');

        $this->dependencySecond->expects($this->once())->method('isHard')->will($this->returnValue(false));
        $this->dependencySecond->expects($this->never())->method('isSoft');

        $this->assertEquals(1, $this->module->getHardDependenciesCount());
    }

    public function testGetSoftDependenciesCount()
    {
        $this->dependencyFirst->expects($this->never())->method('isHard');
        $this->dependencyFirst->expects($this->once())->method('isSoft')->will($this->returnValue(true));

        $this->dependencySecond->expects($this->never())->method('isHard');
        $this->dependencySecond->expects($this->once())->method('isSoft')->will($this->returnValue(false));

        $this->assertEquals(1, $this->module->getSoftDependenciesCount());
    }
}


text:
<?php
Library::import('recess.lang.Annotation');

class RecessReflectionMethod extends ReflectionMethod {
	function getAnnotations() {
		$docstring = $this->getDocComment();
		if($docstring == '') return array();
		else {
			$returns = array();
			try {
				$returns = Annotation::parse($docstring);
			} catch(InvalidAnnotationValueException $e) {
				throw new InvalidAnnotationValueException('In class "' . $this->getDeclaringClass()->name . '" on method "'. $this->name .'".' . $e->getMessage(),0,0,$this->getFileName(),$this->getStartLine(),array());
			} catch(UnknownAnnotationException $e) {
				throw new UnknownAnnotationException('In class "' . $this->getDeclaringClass()->name . '" on method "'. $this->name .'".' . $e->getMessage(),0,0,$this->getFileName(),$this->getStartLine(),array());
			}
		}
		return $returns;
	}

	function isAttached() {
		return false;
	}
}
?>


text:
package graph

import (
	"errors"
	"fmt"
	"io"
	"os"

	"github.com/fabioberger/data-structures/queue"
)

var Output io.Writer = os.Stdout

// Enum of Vertice States (i.e DISCOVERED, UNDISCOVERED, PROCESSED)
type VerticeState int

const (
	UNDISCOVERED = 1 + iota
	DISCOVERED
	PROCESSED
)

// Enum of edge classifications (i.e TREE, BACK, FORWARD, CROSS EDGE)
type EdgeType int

const (
	TREE = 1 + iota
	BACK
	FORWARD
	CROSS
)

// GraphProcessor is an interface that must be satisfied by any specific DFS or BFS
// Processing task.
type GraphProcessor interface {
	processEdge(*Graph, int, int)
	processVertexEarly(*Graph, int)
	processVertexLate(*Graph, int)
}

// An EdgeNode represents a singe vertice of a graphs adjacency list
type EdgeNode struct {
	Y      int
	Weight int
	Next   *EdgeNode
}

// A Graph contains all the data structures necessary to describe the properties of a Graph
type Graph struct {
	Edges             map[int]*EdgeNode    //Adjacency list of edges
	Degree            map[int]int          // degree of each edge
	nVertices         int                  // Number of vertices
	nEdges            int                  // Number of Edges
	Directed          bool                 // Is the graph directed or undirected?
	State             map[int]VerticeState // State of each vertice (discovered, processed, etc.)
	Parent            map[int]int          // Who is the parent of a given vertice
	Time              int                  // Time keeper during graph traversals
	EntryTime         map[int]int          // Time when vertices were first entered
	ExitTime          map[int]int          // Time when vertices were exited
	ReachableAncestor map[int]int          // Earliest reachable ancestor of a vertice
	TreeOutDegree     map[int]int
	Finished          bool  // Graph traversal end condition reached
	Path              []int // Contains shortest path if one calculated
}

// NewGraph instantiates a new Graph struct with sensible default values
func NewGraph(directed bool) *Graph {
	g := new(Graph)
	g.nVertices = 0
	g.nEdges = 0
	g.Directed = directed
	g.Finished = false
	g.Edges = make(map[int]*EdgeNode)
	g.Degree = make(map[int]int)
	return g
}

// InsertEdge adds a node to the adjacency list of the Graph and updates
// the necessary edge and degree counts
// x is adjacent edge to y which is the Id of the new edge being inserted
func (g *Graph) InsertEdge(x, y int, directed bool) {
	p := new(EdgeNode)
	p.Weight = 0
	p.Y = y // value of the new adjacent vertex to x
	p.Next = g.Edges[x]

	g.Edges[x] = p
	g.Degree[x]++

	if directed == false {
		g.InsertEdge(y, x, true)
	} else {
		g.nEdges++
	}
}

// Print outputs a representation of the Graph based on its adjacency list
func (g *Graph) Print() {
	fmt.Fprintf(Output, "Graph num edges: %v and num vertices: %v \n", g.nEdges, g.nVertices)
	fmt.Fprintf(Output, "Directed? %v\n", g.Directed)
	fmt.Fprintf(Output, "Adjacency List:\n")
	var temp *EdgeNode
	for i := 1; i <= g.nVertices; i++ {
		fmt.Fprintf(Output, "Vert. %v ->", i)
		temp = g.Edges[i]
		for temp != nil {
			fmt.Fprintf(Output, " %v", temp.Y)
			temp = temp.Next
		}
		fmt.Fprintln(Output, "")
	}
}

// Read in values from a file to construct a graph
// The file includes one edge per line described as two ints, the two vertices
// that make up an edge
func (g *Graph) Read(fileName string) {
	file, err := os.Open(fileName)
	if err != nil {
		panic(err.Error())
	}
	defer file.Close()

	seenVertices := make(map[int]bool)

	var x, y int
	for {
		_, err := fmt.Fscanf(file, "%v %v", &x, &y)
		if err == io.EOF {
			break
		}
		g.InsertEdge(x, y, g.Directed)
		if _, ok := seenVertices[x]; !ok {
			seenVertices[x] = true
			g.nVertices++
		}
		if _, ok := seenVertices[y]; !ok {
			seenVertices[y] = true
			g.nVertices++
		}
	}
}

// InitSearch re-initializes the State and Parent relationships of the graph vertices
func (g *Graph) InitSearch() {
	g.EntryTime = make(map[int]int)
	g.ExitTime = make(map[int]int)
	g.ReachableAncestor = make(map[int]int)
	g.TreeOutDegree = make(map[int]int)
	g.State = make(map[int]VerticeState)
	g.Parent = make(map[int]int)
	for i := 1; i <= g.nVertices; i++ {
		g.State[i] = UNDISCOVERED
		g.Parent[i] = -1
	}
	g.Time = 0
	g.Finished = false
	g.Path = []int{}
}

// bfs is a Breadth-first search through a graph while allowing the caller to
// define how to process each iteration of the traversal by passing in a struct
// that implements GraphProcessor
// Runs in linear O(n+m) time
// Used a queue (FIFO) as node discovery order
func (g *Graph) bfs(start int, t GraphProcessor) {
	q := queue.NewQueue(start)
	g.State[start] = DISCOVERED

	var v, y int
	var edgeNode *EdgeNode
	for !q.IsEmpty() {
		v, _ = q.Dequeue() //shouldnt hit an error here b/c of surrounding for loop
		t.processVertexEarly(g, v)
		g.State[v] = PROCESSED
		edgeNode = g.Edges[v]
		for edgeNode != nil { // Now process all of the vertex's adjacent vertices
			y = edgeNode.Y
			// If edge not processed yet or its a directed graph (now exploring the edge
			// in the correct direction) then process it
			if g.State[y] != PROCESSED || g.Directed {
				t.processEdge(g, v, y)
			}
			if g.State[y] == UNDISCOVERED {
				q.Enqueue(y)
				g.State[y] = DISCOVERED
				g.Parent[y] = v
			}
			edgeNode = edgeNode.Next
		}
		t.processVertexLate(g, v)
	}
}

// QuietTraversal implements the GraphProcessor interface without outputing anything
// during the traversal. It still sets the correct State & Parent relationships for the vertices
type QuietTraversal struct {
}

func (t *QuietTraversal) processVertexEarly(g *Graph, v int) {
	// Do nothing here
}

func (t *QuietTraversal) processVertexLate(g *Graph, v int) {
	// Do nothing here
}

func (t *QuietTraversal) processEdge(g *Graph, x int, y int) {
	// Do nothing here
}

// FindPath finds the shortest path between start and end in an unweighted graph
func (g *Graph) FindPath(start, end int) ([]int, error) {
	t := new(QuietTraversal)
	g.InitSearch()
	g.bfs(start, t)
	err := g.traversePath(start, end)
	if err != nil {
		return nil, err
	}
	return g.Path, nil
}

// Traverse the shortest path between two nodes recursively printing the path
func (g *Graph) traversePath(start, end int) error {
	if g.Parent[end] == -1 && start != end { // Must make sure a path is possible
		fmt.Fprintln(Output, "No path exists...")
		return errors.New("No Path exists")
	}
	if start == end || end == -1 {
		g.Path = append(g.Path, start)
		fmt.Fprintf(Output, "%v", start)
	} else {
		if err := g.traversePath(start, g.Parent[end]); err != nil {
			return err
		}
		g.Path = append(g.Path, end)
		fmt.Fprintf(Output, " %v", end)
	}
	return nil
}

// BreadthFirstSearch performs a vanilla BFS traversal of the graph using the
// Traversal struct as is GraphProcessor
func (g *Graph) BreadthFirstSearch(start int) [][]int {
	t := new(Traversal)
	g.bfs(start, t)
	return t.Visits
}

// Traversal implements the GraphProcessor interface in such a way to allow
// simple BFS and DFS traversals
type Traversal struct {
	Visits [][]int
}

func (t *Traversal) processVertexEarly(g *Graph, v int) {
	t.Visits = append(t.Visits, []int{v})
}

func (t *Traversal) processVertexLate(g *Graph, v int) {
	// Do nothing here
}

func (t *Traversal) processEdge(g *Graph, x int, y int) {
	edge := []int{x, y}
	t.Visits = append(t.Visits, edge)
}

// ConnectedComponentTraversal implements the GraphProcessor interface so as to
// identify connected components while employing BFS
type ConnectedComponentTraversal struct {
	Current    int
	Components map[int][]int
}

func NewConnectedComponentTraversal() *ConnectedComponentTraversal {
	t := new(ConnectedComponentTraversal)
	t.Components = make(map[int][]int)
	return t
}

func (t *ConnectedComponentTraversal) processVertexEarly(g *Graph, v int) {
	if _, ok := t.Components[t.Current]; !ok {
		t.Components[t.Current] = []int{}
	}
	t.Components[t.Current] = append(t.Components[t.Current], v)
}

func (t *ConnectedComponentTraversal) processVertexLate(g *Graph, v int) {
	// Do nothing here
}

func (t *ConnectedComponentTraversal) processEdge(g *Graph, x int, y int) {
	// Do nothing here
}

// ConnectedComponents discovers all connected components of a graph
func (g *Graph) ConnectedComponents() map[int][]int {
	t := NewConnectedComponentTraversal()
	g.InitSearch()
	c := 1 // component number
	for i := 1; i <= g.nVertices; i++ {
		if g.State[i] == UNDISCOVERED {
			t.Current = c
			g.bfs(i, t)
			c++
		}
	}
	return t.Components
}

// CycleFindTraversal implements GraphProcessor in order to find graph cycles
// with the help of DFS
type CycleFindTraversal struct {
	CycleEdge [2]int
}

func (t *CycleFindTraversal) processVertexEarly(g *Graph, v int) {
	// Do nothing here
}

func (t *CycleFindTraversal) processVertexLate(g *Graph, v int) {
	// Do nothing here
}

func (t *CycleFindTraversal) processEdge(g *Graph, x int, y int) {
	if g.Parent[y] != x { // Found back edge
		t.CycleEdge = [2]int{y, x}
		fmt.Fprintf(Output, "Cycle exists from %v to %v \n", y, x)
		fmt.Fprintf(Output, "Path is: ")
		g.FindPath(y, x)
		fmt.Fprintf(Output, "\n\n")
		g.Finished = true
	}
}

// FindCycles figures out if there are any cycles in the graph (nodes which connect in a cyclic fashion)
// It returns an array of two ints, defining the edge where the cycle begins
func (g *Graph) FindCycles(start int) ([2]int, error) {
	t := new(CycleFindTraversal)
	g.dfs(start, t)
	if t.CycleEdge[0] == 0 {
		emptyValue := [2]int{0, 0}
		return emptyValue, errors.New("No cycle exists")
	}
	return t.CycleEdge, nil
}

// ArticulationVectorTraversal implements the interface GraphProcessor in order to
// find articulator vectors using DFS
type ArticulationVectorTraversal struct {
	ArticulationVectors []int
}

func (t *ArticulationVectorTraversal) processVertexEarly(g *Graph, v int) {
	g.ReachableAncestor[v] = v
}

func (t *ArticulationVectorTraversal) processEdge(g *Graph, x int, y int) {
	class := g.edgeClassification(x, y)
	if class == TREE {
		g.TreeOutDegree[x]++
	}
	if class == BACK && g.Parent[x] != y {
		if g.EntryTime[y] < g.EntryTime[g.ReachableAncestor[x]] {
			g.ReachableAncestor[x] = y
		}
	}
}

func (t *ArticulationVectorTraversal) processVertexLate(g *Graph, v int) {
	if g.Parent[v] == -1 { // Test if v is root
		if g.TreeOutDegree[v] > 1 { // root has more then one child
			fmt.Fprintln(Output, "Root articulation vertex: ", v)
			t.ArticulationVectors = append(t.ArticulationVectors, v)
		}
		return
	}
	root := (g.Parent[g.Parent[v]] < 1) // Is the parent of v the root vertex?
	if g.ReachableAncestor[v] == g.Parent[v] && !root {
		fmt.Fprintln(Output, "Parent Articulation Vector: ", g.Parent[v])
		t.ArticulationVectors = append(t.ArticulationVectors, g.Parent[v])
	}
	if g.ReachableAncestor[v] == v {
		// fmt.Println("Bridge Articulation Vertex: ", g.Parent[v])
		if g.TreeOutDegree[v] > 0 { // Check that v is not a leaf
			fmt.Fprintln(Output, "Bridge Articulation Vertex: ", v)
			t.ArticulationVectors = append(t.ArticulationVectors, v)
		}
	}

	timeV := g.EntryTime[g.ReachableAncestor[v]]
	timeParent := g.EntryTime[g.ReachableAncestor[g.Parent[v]]]
	if timeV < timeParent {
		g.ReachableAncestor[g.Parent[v]] = g.ReachableAncestor[v]
	}
}

// FindArticulationVectors finds all the articulator vectors in a Graph
func (g *Graph) FindArticulationVectors(start int) []int {
	t := new(ArticulationVectorTraversal)
	g.dfs(start, t)
	return t.ArticulationVectors
}

// DepthFirstSearch performs a DFS from a starting graph vertice
func (g *Graph) DepthFirstSearch(start int) [][]int {
	t := new(Traversal)
	g.dfs(start, t)
	return t.Visits
}

// dfs performs a general purpose Depth-first search through a graph
// processing each iteration as per the passed in GraphProcessor
// Implicitly uses a stack (via recursion) to prioritize node discovery
func (g *Graph) dfs(start int, p GraphProcessor) {

	if g.Finished {
		return
	}

	g.State[start] = DISCOVERED
	g.Time++
	g.EntryTime[start] = g.Time
	p.processVertexEarly(g, start)

	edgeNode := g.Edges[start]
	for edgeNode != nil {
		y := edgeNode.Y
		if g.State[y] == UNDISCOVERED {
			g.Parent[y] = start
			p.processEdge(g, start, y)
			g.dfs(y, p)
		} else if g.State[y] != PROCESSED || g.Directed {
			p.processEdge(g, start, y)
		}
		if g.Finished {
			return
		}
		edgeNode = edgeNode.Next
	}
	p.processVertexLate(g, start)
	g.Time++
	g.ExitTime[start] = g.Time
	g.State[start] = PROCESSED

}

// edgeClassification classifies an edge into a TREE, BACK, FORWARD or CROSS edge
func (g *Graph) edgeClassification(x, y int) EdgeType {
	if g.Parent[y] == x {
		return TREE
	}
	if g.State[y] == DISCOVERED {
		return BACK
	} else if g.State[y] == PROCESSED && (g.EntryTime[y] > g.EntryTime[x]) {
		return FORWARD
	} else if g.State[y] == PROCESSED && (g.EntryTime[y] < g.EntryTime[x]) {
		return CROSS
	}
	panic("Unclassified Edge")
}

var edgeTypes = [...]string{
	"TREE",
	"BACK",
	"FORWARD",
	"CROSS",
}

// String for the EdgeType enables this enum to appear as a string when passed to fmt
func (edgeType EdgeType) String() string {
	return edgeTypes[edgeType-1]
}

var states = [...]string{
	"UNDISCOVERED",
	"DISCOVERED",
	"PROCESSED",
}

// String for the VerticeState enables this enum to appear as a string when passed to fmt
func (state VerticeState) String() string {
	return states[state-1]
}