text:
# FetcheableOnApi

FetcheableOnApi allows you to quickly and easily set up a filter system based on the JSONAPI specification for ActiveRecord objects.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'fetcheable_on_api'
```

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install fetcheable_on_api

Finally, run the install generator:

    $ rails generate fetcheable_on_api:install

It will create the following initializer `config/initializers/fetcheable_on_api.rb`.
This file contains all the informations about the existing configuration options.

## Usage

Imagine the following models called question and answer:

```ruby
class Question < ApplicationRecord
  #
  # Validations
  #
  validates :content,
            presence: true

  #
  # Associations
  #
  has_one :answer,
          class_name: 'Answer',
          foreign_key: 'question_id',
          dependent: :destroy,
          inverse_of: :question

  belongs_to :category,
             class_name: 'Category',
             inverse_of: :questions,
             optional: true
end

# == Schema Information
#
# Table name: questions
#
#  id          :bigint(8)        not null, primary key
#  content     :text             not null
#  position    :integer
#  category_id :bigint(8)
#  created_at  :datetime         not null
#  updated_at  :datetime         not null
#
```

```ruby
class Answer < ApplicationRecord
  #
  # Validations
  #
  validates :content,
            presence: true

  #
  # Associations
  #
  belongs_to :question,
             class_name: 'Question',
             foreign_key: 'question_id',
             inverse_of: :answer
end

# == Schema Information
#
# Table name: answers
#
#  id          :bigint(8)        not null, primary key
#  content     :text             not null
#  question_id :bigint(8)
#  created_at  :datetime         not null
#  updated_at  :datetime         not null
#
```

```ruby
class Category < ApplicationRecord
  #
  # Validations
  #
  validates :name,
            presence: true

  #
  # Associations
  #
  has_many :questions,
           class_name: 'Question',
           inverse_of: :category
end

# == Schema Information
#
# Table name: categories
#
#  id          :bigint(8)        not null, primary key
#  name        :text             not null
#  created_at  :datetime         not null
#  updated_at  :datetime         not null
#
```

And controller:

```ruby
class QuestionsController < ActionController::Base
  # GET /questions
  def index
    questions = Question.joins(:answer).includes(:answer).all
    render json: questions
  end
end
```

### Sorting

You can now define the allowed attribute(s) in the sorting of the collection like this:

```ruby
class QuestionsController < ActionController::Base
  #
  # FetcheableOnApi
  #
  sort_by :position

  # GET /questions
  def index
    questions = apply_fetcheable(Question.joins(:answer).includes(:answer).all)
    render json: questions
  end
end
```

This allows you to pass a new parameter in the query:

```bash
$ curl -X GET \
  'http://localhost:3000/questions?sort=position'

[
    {
        "id": 3,
        "position": 1,
        "category_id": 1,
        "content": "How to simply sort a collection with this gem ?",
        "answer": "Just add sort_by in your controller and call the apply_fetcheable method"
    },
    {
        "id": 4,
        "position": 2,
        "category_id": 2,
        "content": "Is it so simple?",
        "answer": "Yes"
    },
    {
        "id": 5,
        "position": 3,
        "category_id": 2,
        "content": "Is this real life?",
        "answer": "Yes this is real life"
    }
]
```

FetcheableOnApi support multiple sort fields by allowing comma-separated (U+002C COMMA, “,”) sort fields:

```ruby
class QuestionsController < ActionController::Base
  #
  # FetcheableOnApi
  #
  sort_by :position, :id

  # GET /questions
  def index
    questions = apply_fetcheable(Question.joins(:answer).includes(:answer).all)
    render json: questions
  end
end
```

```bash
$ curl -X GET \
  'http://localhost:3000/questions?sort=position,id'

[
    {
        "id": 3,
        "position": 1,
        "category_id": 1,
        "content": "How to simply sort a collection with this gem ?",
        "answer": "Just add sort_by in your controller and call the apply_fetcheable method"
    },
    {
        "id": 4,
        "position": 2,
        "category_id": 2,
        "content": "Is it so simple?",
        "answer": "Yes"
    },
    {
        "id": 5,
        "position": 3,
        "category_id": 2,
        "content": "Is this real life?",
        "answer": "Yes this is real life"
    }
]
```

The default sort order for each sort field is ascending unless it is prefixed with a minus (U+002D HYPHEN-MINUS, “-“), in which case it is descending:

```bash
$ curl -X GET \
  'http://localhost:3000/questions?sort=-position'

[
    {
        "id": 5,
        "position": 3,
        "category_id": 2,
        "content": "Is this real life?",
        "answer": "Yes this is real life"
    },
    {
        "id": 4,
        "position": 2,
        "category_id": 2,
        "content": "Is it so simple?",
        "answer": "Yes"
    },
    {
        "id": 3,
        "position": 1,
        "category_id": 1,
        "content": "How to simply sort a collection with this gem ?",
        "answer": "Just add sort_by in your controller and call the apply_fetcheable method"
    }
]
```

You can also sort through an association like this:

```ruby
class QuestionsController < ActionController::Base
  #
  # FetcheableOnApi
  #
  sort_by :position, :id
  sort_by :answer,
          class_name: Answer,
          as: 'content'

  # GET /questions
  def index
    questions = apply_fetcheable(Question.joins(:answer).includes(:answer).all)
    render json: questions
  end
end
```

```bash
$ curl -X GET \
  'http://localhost:3000/questions?sort=answer'

[
    {
        "id": 3,
        "position": 1,
        "category_id": 1,
        "content": "How to simply sort a collection with this gem ?",
        "answer": "Just add sort_by in your controller and call the apply_fetcheable method"
    },
    {
        "id": 4,
        "position": 2,
        "category_id": 2,
        "content": "Is it so simple?",
        "answer": "Yes"
    },
    {
        "id": 5,
        "position": 3,
        "category_id": 2,
        "content": "Is this real life?",
        "answer": "Yes this is real life"
    }
]
```

Furthermore you can sort on `lowered` attributes using the `:lower` option:

```ruby
class QuestionsController < ActionController::Base
  #
  # FetcheableOnApi
  #
  sort_by :answer, lower: true

  # GET /questions
  def index
    questions = apply_fetcheable(Question.joins(:answer).includes(:answer).all)
    render json: questions
  end
end
```

```bash
$ curl -X GET \
  'http://localhost:3000/questions?sort=answer'

[
    {
        "id": 3,
        "position": 1,
        "category_id": 1,
        "content": "How to simply sort a collection with this gem ?",
        "answer": "Just add sort_by in your controller and call the apply_fetcheable method"
    },
    {
        "id": 6,
        "position": 4,
        "category_id": 1,
        "content": "Why am I here?",
        "answer": "just to demonstrate lowered sort",
    },
    {
        "id": 4,
        "position": 2,
        "category_id": 2,
        "content": "Is it so simple?",
        "answer": "Yes"
    },
    {
        "id": 5,
        "position": 3,
        "category_id": 2,
        "content": "Is this real life?",
        "answer": "Yes this is real life"
    }
]
```

### Pagination

Pagination is automatically set on the controller and allows the use of a new parameter `page`.
The pagination is page-based strategy, it can use query parameters such as `page[number]` and `page[size]`

```bash
$ curl -X GET \
  'http://localhost:3000/questions?page[number]=1&page[size]=2'

[
    {
        "id": 3,
        "position": 1,
        "category_id": 1,
        "content": "How to simply sort a collection with this gem ?",
        "answer": "Just add sort_by in your controller and call the apply_fetcheable method"
    },
    {
        "id": 4,
        "position": 2,
        "category_id": 2,
        "content": "Is it so simple?",
        "answer": "Yes"
    }
]

$ curl -X GET \
  'http://localhost:3000/questions?page[number]=2&page[size]=2'

[
    {
        "id": 5,
        "position": 3,
        "category_id": 2,
        "content": "Is this real life?",
        "answer": "Yes this is real life"
    }
]
```

When you use pagination, additional information is returned in the Header

- `Pagination-Current-Page`: the current page number
- `Pagination-Per`: the number of records per page
- `Pagination-Total-Pages`: the total number of pages
- `Pagination-Total-Count`: the total number of records

### Filtering

The `filter` query parameter is reserved for filtering data and the controller must set the attributes allowed to be filtered.

```ruby
class QuestionsController < ActionController::Base
  #
  # FetcheableOnApi
  #
  sort_by :position, :id
  filter_by :content

  # GET /questions
  def index
    questions = apply_fetcheable(Question.joins(:answer).includes(:answer).all)
    render json: questions
  end
end
```

```bash
$ curl -X GET \
  'http://localhost:3000/questions?filter[content]=gem'

[
    {
        "id": 3,
        "position": 1,
        "category_id": 1,
        "content": "How to simply sort a collection with this gem ?",
        "answer": "Just add sort_by in your controller and call the apply_fetcheable method"
    }
]
```

Multiple filter values can be combined in a comma-separated list.

```bash
$ curl -X GET \
  'http://localhost:3000/questions?filter[content]=real,simple'

[
    {
        "id": 4,
        "position": 2,
        "category_id": 2,
        "content": "Is it so simple?",
        "answer": "Yes"
    },
    {
        "id": 5,
        "position": 3,
        "category_id": 2,
        "content": "Is this real life?",
        "answer": "Yes this is real life"
    }
]
```

You can also define a filter through an association like this:

```ruby
class QuestionsController < ActionController::Base
  #
  # FetcheableOnApi
  #
  sort_by :position, :id
  filter_by :content
  filter_by :answer,
            class_name: Answer,
            as: 'content'

  # GET /questions
  def index
    questions = apply_fetcheable(Question.joins(:answer).includes(:answer).all)
    render json: questions
  end
end
```

```bash
$ curl -X GET \
  'http://localhost:3000/questions?filter[answer]=apply_fetcheable'

[
    {
        "id": 3,
        "position": 1,
        "category_id": 1,
        "content": "How to simply sort a collection with this gem ?",
        "answer": "Just add sort_by in your controller and call the apply_fetcheable method"
    }
]
```

By default fetcheable_on_api will join the associated model using the
`class_name` option you have provided. If another association should be used as
the target, use the `association:` option instead.

Furthermore you can specify one of the supported `Arel` predicate.

```ruby
class QuestionsController < ActionController::Base
  #
  # FetcheableOnApi
  #
  filter_by :category_id, with: :eq

  # GET /questions
  def index
    questions = apply_fetcheable(Question.includes(:answer).all)
    render json: questions
  end
end
```

```bash
$ curl -X GET \
  'http://localhost:3000/questions?filter[category_id]=1'

[
    {
        "id": 3,
        "position": 1,
        "category_id": 1,
        "content": "How to simply sort a collection with this gem ?",
        "answer": "Just add sort_by in your controller and call the apply_fetcheable method"
    }
]
```

Currently 33 predicates are supported ([more details here](https://github.com/fabienpiette/fetcheable_on_api/wiki/Predicates)):

+ `:between`
+ `:does_not_match`
+ `:does_not_match_all`
+ `:does_not_match_any`
+ `:eq` which matches the parameter with the SQL fragment `= 'foo'`.
+ `:eq_all`
+ `:eq_any`
+ `:gt`
+ `:gt_all`
+ `:gt_any`
+ `:gteq`
+ `:gteq_all`
+ `:gteq_any`
+ `:ilike` which is the default behaviour and will match the parameter with the SQL fragment `ILIKE '%foo%'`.
+ `:in`
+ `:in_all`
+ `:in_any`
+ `:lt`
+ `:lt_all`
+ `:lt_any`
+ `:lteq`
+ `:lteq_all`
+ `:lteq_any`
+ `:matches`
+ `:matches_all`
+ `:matches_any`
+ `:not_between`
+ `:not_eq`
+ `:not_eq_all`
+ `:not_eq_any`
+ `:not_in`
+ `:not_in_all`
+ `:not_in_any`

+ `lamdba` wich take two arguments: a collection and a value, then return an Arel predicate.
  ```ruby
  filter_by :name, with: -> (collection, value) do
    collection.arel_table[:first_name].matches("%#{value}%").or(
      collection.arel_table[:last_name].matches("%#{value}%"),
    )
  end
  ```

You can also use an array as a parameter for some predicate

```ruby
class QuestionsController < ActionController::Base
  #
  # FetcheableOnApi
  #
  filter_by :id, with: :between

  # GET /questions
  def index
    questions = apply_fetcheable(Question.includes(:answer).all)
    render json: questions
  end
end
```

```bash
curl -X GET \
  'http://localhost:3000/questions?filter[id]=[1]'

[
    {
        "id": 1,
        "position": 1,
        "content": "Je peux boire ou cuisiner avec l'eau de pluie ?",
        "answer": "Faux : l'eau de pluie que vous récupérez est strictement interdite pour une consommation alimentaire car elle n'est pas potable.\nVous ne devez donc pas la boire, ni l'utiliser pour cuisiner ou laver la vaisselle.\n",
        "base_value": false
    }
]
```

Date manipulation is a special case and can be solved by specifically indicating the expected format for the parameter.

```ruby
class QuestionsController < ActionController::Base
  #
  # FetcheableOnApi
  #
  filter_by :created_at,
            with: :between,
            format: :datetime

  # GET /questions
  def index
    questions = apply_fetcheable(Question.includes(:answer).all)
    render json: questions
  end
end
```

```bash
curl -X GET \
  'http://localhost:3000/questions?filter[created_at]=[1541428932,1541428933]'
```

By default the format used is epoch time, but you can redefine it by overriding the method `foa_string_to_datetime`

```ruby
class QuestionsController < ActionController::Base
  #
  # FetcheableOnApi
  #
  filter_by :created_at,
            with: :between,
            format: :datetime

  # GET /questions
  def index
    questions = apply_fetcheable(Question.includes(:answer).all)
    render json: questions
  end

  protected

  def foa_string_to_datetime(string)
    DateTime.strptime(string, '%s')
  end
end
```

And that's all !

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/FabienPiette/fetcheable_on_api. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.

## License

The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).

## Code of Conduct

Everyone interacting in the FetcheableOnApi project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/FabienPiette/fetcheable_on_api/blob/master/CODE_OF_CONDUCT.md).


text:
# Haventec Authenticate Web SDK

A collection of javascript functions to facilitate client-side integration with Haventec Authenticate.

## Installation

`npm install @haventec/authenticate-web-sdk`

## General Usage

The authenticate-web-sdk is not exported as a default export and an instance of it should be created for each user.
```
import { HaventecAuthenticate } from '@haventec/authenticate-web-sdk'
let haventecAuthenticate = new HaventecAuthenticate('username');
```
The implementation requires window object (browser) and wouldn't function in a node.js environment.

## Methods

* **updateStorage:** It updates the storage with the object passed as parameter.

* **getDeviceName:** It returns device-name set by default.

* **clearAccessToken:** It clears the access-token for the active user.
* **getAccessToken:** It returns the access-token of the user.

* **getUsername:** It returns username of the current user.

* **getDeviceUuid:** It returns the uuid of the device generated through authenticate.
* **getUserUuid:** It returns the uuid of the current user.

* **getAuthKey:** It returns the current authKey of the current user from the Storage.

* **clearUserStorage:** It clears the entire local and session storage used by the user.
* **hashPin:** It returns a SHA-512 Hashing of the PIN passed as argument.
* **getDeviceInfo:** It returns the information about device including the fingerprint.

## Development

 To build and publish locally, clone the project and run the following:
 ```
 npm install
 npm pack / npm publish
  ```

## License

This code is available under the MIT license. A copy of the license can be found in the LICENSE file included with the distribution.

license: MIT

repository: zip-code/authenticate-web-sdk

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: zip-code/authenticate-web-sdk


text:
# build-2020-msgraph-whatsnew-demos
Demonstrations that we need to build for the build 2020 Microsoft Graph What's new session.

## Users and security demonstrations

### Pre-requisites

- [Microsoft Graph PowerShell](https://www.powershellgallery.com/packages/Microsoft.Graph)
- Demonstration tenant with Azure AD P2 licenses
- [PowerShell 7](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows?view=powershell-7#installing-the-msi-package)

### Phone-auth method

1. Run `demos/phone-auth/script.ps1`.
1. Go over what each command does.
1. Signal we'll see the result in the conditional access demo.

#### Additional resources

- [Phone auth method reference](https://docs.microsoft.com/en-us/graph/api/resources/phoneauthenticationmethod?view=graph-rest-beta)

### Conditional access

>Note: this demonstration requires MFA settings to be configured on the user being demonstrated.

1. Open an in-private browser.
1. Sign-in to [outlook online](https://outlook.office.com/mail/inbox).
1. Signal to attendance that the user accessed outlook only with a password.
1. Close the browser.
1. Run `demos/conditional-access/script.ps1`.
1. Go over what each command does.
1. Open an in-private browser.
1. Sign-in to [outlook online](https://outlook.office.com/mail/inbox).
1. Signal to attendance that this time another factor of authentication was required to access outlook, improving security.
1. Tell attendance that policies can be customized based on the:
    - app being accessed
    - the context (browser or native app, location...)
    - the user (groups, type of users)

>Note: we could also show up the newly created policy in [Azure Portal](https://portal.azure.com) > Azure AD > Security > Conditional Access

#### Additional resources

- [building a conditional access policy](https://docs.microsoft.com/en-us/azure/active-directory/conditional-access/concept-conditional-access-policies)
- [conditional access policy reference](https://docs.microsoft.com/en-us/graph/api/conditionalaccessroot-post-policies?view=graph-rest-beta&tabs=http)

### Improved query capabilities for Directory Objects (preview)

> This demo is optional, we'll see if we have time during recording.

1. Open the Graph Explorer.
1. Add the following request header `ConsistencyLevel` set to `eventual`.
1. GET `https://graph.microsoft.com/beta/users/$count?$filter=startsWith(officeLocation, '18')` (Raw User Count with Filtering)
1. GET `https://graph.microsoft.com/beta/users?$count=true&$select=displayName,Id&$orderby=displayName&$search="displayName:queen"` (Search, Sort & Count Users)
1. GET `https://graph.microsoft.com/beta/groups/792be2c1-1b38-4083-b5d0-d49c8a3b8f2d/transitiveMembers/microsoft.graph.user?$count=true&$select=displayName,Id&$search="displayName:queen"&$orderby=displayName` (Search & Count Group members transitively)


text:
### [CVE-2021-33543](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-33543)
![](https://img.shields.io/static/v1?label=Product&message=E2%20Series&color=blue)
![](https://img.shields.io/static/v1?label=Product&message=Encoder%20G-Code&color=blue)
![](https://img.shields.io/static/v1?label=Version&message=EBC-21xx%3C%3D%<IP_ADDRESS>%20&color=brighgreen)
![](https://img.shields.io/static/v1?label=Version&message=EEC-2xx%3C%3D%<IP_ADDRESS>%20&color=brighgreen)
![](https://img.shields.io/static/v1?label=Vulnerability&message=CWE-306%20Missing%20Authentication%20for%20Critical%20Function&color=brighgreen)

### Description

Multiple camera devices by UDP Technology, Geutebrück and other vendors allow unauthenticated remote access to sensitive files due to default user authentication settings. This can lead to manipulation of the device and denial of service.

### POC

#### Reference
- https://www.randorisec.fr/fr/udp-technology-ip-camera-vulnerabilities/

#### Github
- https://github.com/ARPSyndicate/cvemon

repository: trickest/cve

branch_name: refs/heads/main

gha_language: HTML

gha_license_id: MIT

repo_name: trickest/cve


text:
# DIYStarter

A durable Android REST based client built on the principle of Less Code, Better Quality using:

 - [Retrofit] (http://square.github.io/retrofit/)
 - [EventBus] (https://github.com/greenrobot/EventBus)
 - [Picasso] (http://square.github.io/picasso/)
 - [GSon] (https://code.google.com/p/google-gson/) - comes packaged within Retrofit
 - [OkHttp] (http://square.github.io/okhttp/)
 - [DIY.org REST API] (http://docs.diy.org/)

This is a starter application so the UI is primitive with basic error handling. The intent is not to show UI/UX excellency but code design and best practices

### Architecture

The project was built with Android Studio and studying the architecture and code of the project you'll be able to learn:

- Consuming a web API and displaying images fetched over the network in a List View
- Moving network request outside of the Activity lifecyle.
- Clear and safe communication between multiple independent component i.e. configuration changes (rotation, phone-call etc.) will not crash the app. We don't take a defensive programming approach or null checks spread out everywhere in the code. If you have done anything with Fragments you know what I am talking about.
- All Activities (or any similar component for that matter) registers on the Event Bus and use it to communicate.
- When you want to load data you post an event on the Event Bus which will cause the Data Service to start the network request.
- When network request finishes, Data Service will post the result back on the Event Bus for any listening Activites to handle.
- The UI is completely agnostic to who is the data provider meaning you can plug-play any type of UI. The source of data can be an in-memory cache or local database that syncs with a web API.

### Study Guide

Make sure to have basic familiarity on how to use the open-source libraries linked above. Given you done that studying the project in following order will probably be more helpful:

1. [DIYApi.java] (https://github.com/tabishfayyaz/diy-starter/blob/master/DIYStarter/app/src/main/java/tabishfayyaz/apps/samples/diystarter/rest/DIYApi.java) communicates with the REST API utilizing RetroFit
2. [StarterApp.java] (https://github.com/tabishfayyaz/diy-starter/blob/master/DIYStarter/app/src/main/java/tabishfayyaz/apps/samples/diystarter/StarterApp.java) is where Data Service is initialized and registered on the Event Bus
3. [DataService.java] (https://github.com/tabishfayyaz/diy-starter/blob/master/DIYStarter/app/src/main/java/tabishfayyaz/apps/samples/diystarter/manager/DataService.java) is the pipe through which data travels back & forth between the UI layer and REST layer. The UI is completely agnostic to who is the data provider meaning you can plug-play any type of UI without changing anything in other packages
4. [SelectionActivity.java] (https://github.com/tabishfayyaz/diy-starter/blob/master/DIYStarter/app/src/main/java/tabishfayyaz/apps/samples/diystarter/ui/SelectionActivity.java) is the first view of the app and lets the user choose between seeing his projects or his followers projects
5. Continue studying the other Activities

#### Questions?

Tweet me: [@tabishfayyaz](https://twitter.com/tabishfayyaz)

## License

DIYStarter is available under the MIT license. See the [LICENSE](https://github.com/tabishfayyaz/diy-starter/blob/master/LICENSE).

repository: tabishfayyaz/diy-starter

repo_name: tabishfayyaz/diy-starter


text:
[kaspresso](../../../index.md) / [com.kaspersky.kaspresso.kaspresso](../../index.md) / [Kaspresso](../index.md) / [Builder](index.md) / [language](./language.md)

# language

`var language: `[`Language`](../../../com.kaspersky.kaspresso.device.languages/-language/index.md)

Holds an implementation of [Language](../../../com.kaspersky.kaspresso.device.languages/-language/index.md) interface. If it was not specified, the default implementation is used.

repository: aartikov/Kaspresso

repo_name: aartikov/Kaspresso


text:
# MySQL plugin for New Relic
Find the New Relic MySQL plugin in the [New Relic storefront](http://newrelic.com/plugins/new-relic-inc/52)

Find the New Relic MySQL plugin in [Plugin Central](https://rpm.newrelic.com/extensions/com.newrelic.plugins.mysql.instance)

----
**Your New Relic MySQL plugin can be operational in just a few minutes when following these steps.**

----
## Prerequisites
The MySQL plugin for New Relic requires the following:

- A New Relic account. Signup for a free account at http://newrelic.com
- A server running MySQL Version 5.0 or greater. Download MySQL for free at http://dev.mysql.com/downloads
- A configured Java Runtime (JRE) environment Version 1.6 or better
- Network access to New Relic (authenticated proxies are not currently supported, but see workaround below)

## Download
Download and unpack the [New Relic plugin for MySQL from Plugin Central](https://rpm.newrelic.com/extensions/com.newrelic.plugins.mysql.instance)

Linux example:

    $ mkdir /path/to/newrelic-plugin
    $ cd /path/to/newrelic-plugin
    $ tar zxvf newrelic_mysql_plugin*.tar.gz

## Create MySQL user if necessary
The MySQL plugin requires a MySQL user with limited privileges. To use the New Relic default, run the following SQL script located at [/scripts/mysql_user.sql](https://github.com/newrelic-platform/newrelic_mysql_java_plugin/blob/master/scripts/mysql_user.sql).

`$ mysql -uroot -p < mysql_user.sql`

This script will create the following user:

    username: newrelic
    host: localhost or <IP_ADDRESS>
    password: *B8B274C6AF8165B631B4B517BD0ED2694909F464 (hashed value)

*You can choose to use a different MySQL user name and password. See [MYSQL.TXT](https://github.com/newrelic-platform/newrelic_mysql_java_plugin/blob/master/MYSQL.TXT) for more info.*

If your MySQL Server is bound to an externally visible IP address, both localhost and <IP_ADDRESS> will not be accessible via TCP as the host for the MySQL Plugin. In order for the plugin to connect, you will need to create a user for your IP address. Due to security concerns in this case, we strongly recommend **not** using the default password and instead setting it to some other value.

    CREATE USER newrelic@<INSERT_IP_ADDRESS_HERE> IDENTIFIED BY '<INSERT_PASSWORD_HERE>';
    GRANT PROCESS, REPLICATION CLIENT ON *.* TO newrelic@<INSERT_IP_ADDRESS_HERE>;

## Configuring your agent environment
The New Relic plugin for MySQL runs an agent process to collect and report MySQL metrics to New Relic. Configure your New Relic license and MySQL databases.

### Configure your New Relic license
Specify your license key in the necessary properties file.
Your license key can be found under Account Settings at https://rpm.newrelic.com see https://newrelic.com/docs/subscriptions/license-key for more help.

Linux example:

    $ cp config/template_newrelic.properties config/newrelic.properties
    # Edit config/newrelic.properties and paste in your license key

### Configure your MySQL properties
Each running MySQL plugin agent requires a JSON configuration file which defines the access to the monitored MySQL instance(s). An example file is provided in the config directory.

Linux example:

    $ cp config/template_mysql.instance.json config/mysql.instance.json
    # Edit config/mysql.instance.json

If using your localhost MySQL instance, add your user name and password as well as a meaningful name which will appear in the New Relic user interface for the MySQL instance. Set the value for the "name" attribute to match your MySQL databases purpose, e.g. "Production Master".

    [
      {
        "name" : "Production Master",
        "host" : "localhost",
        "metrics" : "status,newrelic",
        "user" : "USER_NAME_HERE",
        "passwd" : "USER_PASSWD_HERE"
      }
    ]

#### Externally Visible IP Address

If your MySQL Server is bound to an externally visible IP address, set the 'host' to your IP address and use the username and password that you created above. See the 'Create MySQL user if necessary' section above.

#### Metrics

The MySQL Plugin is capable of reporting different sets of metrics by configuring the 'metrics' attribute. E.g., add the 'slave' category to report replication metrics.
*See [CATEGORIES.TXT](https://github.com/newrelic-platform/newrelic_mysql_java_plugin/blob/master/CATEGORIES.TXT) for more info.*

## Running the agent
To run the plugin from the command line:
`$ java -jar newrelic_mysql_plugin*.jar`

If your host needs a proxy server to access the Internet, you can specify a proxy server & port:
`$ java -Dhttps.proxyHost=proxyhost -Dhttps.proxyPort=8080 -jar newrelic_mysql_plugin*.jar`

To run the plugin from the command line and detach the process so it will run in the background:
`$ nohup java -jar newrelic_mysql_plugin*.jar &`

## Keep this process running
You can use services like these to manage this process.

- [Upstart](http://upstart.ubuntu.com/)
- [Systemd](http://www.freedesktop.org/wiki/Software/systemd/)
- [Runit](http://smarden.org/runit/)
- [Monit](http://mmonit.com/monit/)

## For support
Plugin support and troubleshooting assistance can be obtained by visiting [support.newrelic.com](https://support.newrelic.com)

## Fork me!
The MySQL plugin uses an extensible architecture that allows you to define new MySQL metrics beyond the provided defaults. To expose more data about your MySQL servers, fork this repository, create a new GUID, add the metrics you would like to collect to config/metric.category.json and then build summary metrics and dashboards to expose your newly collected metrics.

*See [CATEGORIES.TXT](https://github.com/newrelic-platform/newrelic_mysql_java_plugin/blob/master/CATEGORIES.TXT) for more info.*

## Credits
The MySQL plugin was originally authored by [Ronald Bradford](http://ronaldbradford.com/) of [EffectiveMySQL](http://effectivemysql.com/). Subsequent updates and support are provided by [New Relic](http://new