diff --git a/.gitignore b/.gitignore index 9d4f978ae0..755167cb1b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,5 @@ src/.jekyll-cache/ scripts/release/__pycache__/ .bundle/config vendor/* -content +hugo/public .DS_Store diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..55c8fbdbca --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,97 @@ +# AGENTS.md — Hugo Migration Guide + +This document describes the approach and conventions used when migrating the Apache ActiveMQ website from Jekyll (`src/`) to Hugo (`hugo/`). + +## Repository layout + +``` +activemq-website/ +├── src/ # Original Jekyll source (do not modify) +├── hugo/ # Hugo site (migration target) +│ ├── hugo.toml +│ ├── assets/css/main.css +│ ├── content/ +│ ├── data/ +│ ├── layouts/ +│ ├── static/assets/ +│ └── scripts/ +└── AGENTS.md # This file +``` + +## Hugo conventions + +### Layout lookup +Hugo resolves layouts by content type (directory name under `content/`): +- `content/foo/_index.md` → `layouts/foo/list.html` +- `content/foo/bar.md` → `layouts/foo/single.html` +- Falls back to `layouts/_default/single.html` or `list.html` + +### Two-block page structure +Every layout uses two blocks defined in `layouts/_default/baseof.html`: +- `above-main` — full-width content (hero banners, page title banners) rendered **outside** the padded `
` container +- `main` — normal page content inside the max-width container + +### Raw HTML in Markdown +`hugo.toml` sets `[markup.goldmark.renderer] unsafe = true` to allow inline HTML in `.md` files. This is intentional — several pages use HTML tables and `
` blocks ported from Jekyll. + +## Theme + +Single self-contained stylesheet at `hugo/assets/css/main.css`. Key variables: + +```css +--red: #c0392b /* primary accent */ +--surface: #f7f7f8 /* card/banner backgrounds */ +--border: #e5e5e7 +--text: #1a1a1a +--muted: #6b7280 +--max-w: 1100px +``` + +Rules of thumb: +- Nav is white with a bottom border; links turn red on hover +- Page title banners (News, Download, etc.) use `background: var(--red)` with white `h1` +- Component hero banners (ActiveMQ component page) also use red with white text and the vertical logo +- Homepage hero uses `var(--surface)` (light grey) — no red background + +## Pages migrated so far + +| URL | Content file | Layout | +|-----|-------------|--------| +| `/` | `content/_index.md` | `layouts/index.html` | +| `/news/` | `content/news/_index.md` | `layouts/news/list.html` | +| `/news/` | `content/news/*.md` | `layouts/news/single.html` | +| `/components/classic/` | `content/components/classic/_index.md` | `layouts/components/list.html` | +| `/download/` | `content/download/index.md` | `layouts/download/list.html` | + +## Migrating a new page + +1. Find the source in `src/` (usually `src//index.md` or `src/.md`). +2. Create `hugo/content//index.md` (or `.md` for a leaf page). +3. Copy the front matter fields `title` and `date`; drop Jekyll-specific fields (`layout`, `type`, `title-class`). +4. Strip Liquid tags (`{% %}`, `{{ }}`). Replace with static content or Hugo template syntax. +5. If the page needs a banner + breadcrumb, create a layout in `layouts/
/` using the `above-main` / `main` block pattern (copy `layouts/news/list.html` as a starting point). +6. If the page is purely content with no special chrome, the `_default/single.html` layout is sufficient. + +## Importing news / release content in bulk + +Run the import script to convert all Jekyll release collections into Hugo news items: + +```bash +cd hugo +python3 scripts/import_news.py +``` + +The script reads `src/_classic_releases/`, `src/_nms_*_releases/`, and `src/_news/`, extracts `title`, `release_date`, and `shortDescription` front matter, strips Liquid tags from the body, and writes Hugo `.md` files to `content/news/`. Existing files are not overwritten. + +## Static assets + +All images from `src/assets/img/` are copied to `hugo/static/assets/img/` and served verbatim. Reference them as `/assets/img/` in templates and content. + +## Global CSS resets to watch out for + +The global `ul`, `ol`, and `li` rules add `padding-left` and `margin-bottom`. Any nav or UI component that contains a `
    ` must explicitly reset these: + +```css +.my-component ul { padding-left: 0; margin-bottom: 0; } +.my-component li { margin: 0; padding: 0; } +``` diff --git a/hugo/.hugo_build.lock b/hugo/.hugo_build.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hugo/README.md b/hugo/README.md new file mode 100644 index 0000000000..1de34a5554 --- /dev/null +++ b/hugo/README.md @@ -0,0 +1,79 @@ +# Apache ActiveMQ Website — Hugo + +This directory contains the Hugo-based rewrite of the [activemq.apache.org](https://activemq.apache.org/) website. +The original Jekyll source lives in `../src/`. + +## Prerequisites + +Install Hugo (extended edition recommended for SCSS support): + +```bash +# macOS +brew install hugo + +# Linux (snap) +snap install hugo + +# Or download a binary from https://github.com/gohugoio/hugo/releases +``` + +Verify the installation: + +```bash +hugo version +``` + +## Local development + +From this directory (`hugo/`): + +```bash +# Serve with live reload +hugo server + +# Open http://localhost:1313 in your browser +``` + +Useful flags: + +| Flag | Purpose | +|------|---------| +| `--buildDrafts` / `-D` | Include draft content | +| `--port 1314` | Use a different port | +| `--disableFastRender` | Full re-render on every change | + +## Build + +```bash +hugo +``` + +Output is written to `hugo/public/`. To change the output directory: + +```bash +hugo --destination ../output +``` + +## Clean + +```bash +rm -rf public resources +``` + +## Project layout + +``` +hugo/ +├── hugo.toml # Site configuration +├── content/ # Markdown/HTML page sources +│ └── _index.md # Homepage +├── layouts/ +│ ├── _default/ +│ │ ├── baseof.html # Base HTML shell +│ │ └── single.html # Default single-page layout +│ ├── index.html # Homepage layout +│ └── partials/ +│ ├── nav.html +│ └── footer.html +└── static/ # Files copied verbatim to output (images, etc.) +``` diff --git a/hugo/assets/css/main.css b/hugo/assets/css/main.css new file mode 100644 index 0000000000..9a9637b1ef --- /dev/null +++ b/hugo/assets/css/main.css @@ -0,0 +1,525 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); + +:root { + --red: #c0392b; + --red-dark: #96281b; + --bg: #ffffff; + --surface: #f7f7f8; + --border: #e5e5e7; + --text: #1a1a1a; + --muted: #6b7280; + --radius: 6px; + --max-w: 860px; +} + +*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } + +html { font-size: 16px; scroll-behavior: smooth; } + +body { + font-family: 'Inter', system-ui, sans-serif; + background: var(--bg); + color: var(--text); + line-height: 1.7; + -webkit-font-smoothing: antialiased; +} + +/* ── Nav ── */ +.site-nav { + background: #fff; + position: sticky; + top: 0; + z-index: 100; + border-bottom: 1px solid var(--border); +} + +.site-nav .inner { + max-width: 1100px; + margin: 0 auto; + padding: 0 2rem; + height: 64px; + display: flex; + align-items: center; + justify-content: space-between; +} + +.site-nav .brand img { display: block; } +.site-nav .brand { + font-size: .95rem; + font-weight: 500; + color: var(--text); + text-decoration: none; +} + +.site-nav ul { + list-style: none; + display: flex; + align-items: center; + gap: 2rem; + height: 100%; + padding-left: 0; + margin-bottom: 0; +} + +.site-nav ul a { + color: var(--text); + text-decoration: none; + font-size: .95rem; + font-weight: 500; + transition: color .15s; +} + +.site-nav ul a:hover { color: var(--red); } +.site-nav li { margin-bottom: 0; } + +/* ── Main content ── */ +main { + max-width: 1100px; + margin: 0 auto; + padding: 3rem 2rem 4rem; +} + +/* ── Typography ── */ +h1, h2, h3, h4 { + font-weight: 700; + line-height: 1.25; + letter-spacing: -.02em; + margin-top: 2rem; + margin-bottom: .6rem; +} + +h1 { font-size: 2.2rem; } +h2 { font-size: 1.5rem; border-bottom: 2px solid var(--border); padding-bottom: .4rem; } +h3 { font-size: 1.15rem; } + +p { margin-bottom: 1rem; } + +a { color: var(--red); text-decoration: none; } +a:hover { text-decoration: underline; } + +ul, ol { padding-left: 1.4rem; margin-bottom: 1rem; } +li { margin-bottom: .25rem; } + +code { + font-family: 'JetBrains Mono', 'Fira Code', monospace; + font-size: .85em; + background: var(--surface); + border: 1px solid var(--border); + border-radius: 3px; + padding: .1em .35em; +} + +pre { + background: #1e1e1e; + color: #d4d4d4; + border-radius: var(--radius); + padding: 1.2rem 1.4rem; + overflow-x: auto; + margin-bottom: 1.2rem; + font-size: .875rem; + line-height: 1.6; +} + +pre code { background: none; border: none; padding: 0; color: inherit; font-size: inherit; } + +blockquote { + border-left: 3px solid var(--red); + padding: .5rem 1rem; + color: var(--muted); + margin-bottom: 1rem; +} + +/* ── Hero (homepage) ── */ +.hero { + background: var(--red); + padding: 3.5rem 2rem; +} + +.hero .inner { + max-width: 1100px; + margin: 0 auto; + display: flex; + align-items: center; + justify-content: space-between; + gap: 2rem; +} + +.hero-text h1 { + font-size: 2.4rem; + font-weight: 800; + line-height: 1.2; + letter-spacing: -.03em; + margin: 0 0 1.5rem; + color: #fff; +} + +.hero-logo img { + height: 180px; + display: block; + filter: drop-shadow(0 0 8px rgba(255,255,255,.6)) drop-shadow(0 0 2px rgba(255,255,255,.9)); +} + +.btn { + display: inline-block; + background: var(--red); + color: #fff; + padding: .65rem 1.4rem; + border-radius: var(--radius); + font-weight: 600; + font-size: .95rem; + transition: background .15s; + text-decoration: none; +} + +.btn:hover { background: var(--red-dark); text-decoration: none; } + +.btn-outline { + background: transparent; + border: 2px solid #fff; + color: #fff; + margin-left: .75rem; +} + +.btn-outline:hover { background: #fff; color: var(--red); } + +/* ── Intro blurb ── */ +.intro { margin-bottom: 2.5rem; font-size: 1rem; color: var(--text); } + +/* ── News cards ── */ +.news-cards { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + gap: 0; + border: 1px solid var(--border); + border-radius: var(--radius); + overflow: hidden; + margin-bottom: 2.5rem; +} + +.news-card { + padding: 1.25rem 1.5rem; + border-right: 1px solid var(--border); +} + +.news-card:last-child { border-right: none; } + +.news-card h4 { + margin: 0 0 .5rem; + font-size: .95rem; + font-weight: 600; +} + +.news-card h4 a { color: var(--red); } + +.news-card p { font-size: .875rem; color: var(--text); margin-bottom: .5rem; } + +.news-card time { font-size: .8rem; color: var(--muted); display: block; text-align: right; } + +/* ── Component section ── */ +.component { + border-left: 4px solid var(--red); + padding: .25rem 0 .25rem 1.25rem; + margin-bottom: 2rem; +} + +.component h3 { margin-top: 0; color: var(--red); font-size: 1.2rem; } + +/* ── Cards (feature grid) ── */ +.cards { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 1.25rem; + margin-top: 2.5rem; +} + +.card { + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1.5rem; + background: var(--surface); +} + +.card h3 { margin-top: 0; font-size: 1rem; } +.card p { color: var(--muted); font-size: .9rem; margin-bottom: 0; } + +/* ── Component hero ── */ +.component-hero { + background: var(--red); + padding: 3rem 2rem; +} + +.component-hero .inner { + max-width: 1100px; + margin: 0 auto; + display: flex; + align-items: center; + justify-content: space-between; + gap: 2rem; +} + +.component-hero-text h1 { + font-size: 2.6rem; + font-weight: 800; + color: #fff; + margin: 0 0 .5rem; + letter-spacing: -.03em; +} + +.component-hero-sub { + color: rgba(255,255,255,.9); + font-size: 1.1rem; + font-weight: 500; + margin: 0 0 1.5rem; +} + +.component-hero-actions { display: flex; gap: .75rem; } + +.btn-hero { + background: #fff; + color: var(--red); + font-weight: 600; +} + +.btn-hero:hover { background: #f0f0f0; text-decoration: none; } + +.btn-hero-outline { + background: transparent; + border: 2px solid #fff; + color: #fff; + padding: .6rem 1.4rem; + border-radius: var(--radius); + font-weight: 600; + font-size: .95rem; + text-decoration: none; + transition: background .15s; +} + +.btn-hero-outline:hover { background: #fff; color: var(--red); text-decoration: none; } + +.component-body { max-width: 860px; } + +/* Docs card grid */ +.docs-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); + gap: 1.25rem; + padding: 2rem 0; +} +.docs-card { + background: var(--surface); + border: 1px solid var(--border); + border-radius: 8px; + padding: 1.25rem 1.5rem; + transition: box-shadow .15s; +} +.docs-card:hover { box-shadow: 0 4px 16px rgba(0,0,0,.08); } +.docs-card h3 { + font-size: .8rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: .06em; + color: var(--muted); + margin: 0 0 .75rem; +} +.docs-card ul { padding-left: 0; margin: 0; list-style: none; } +.docs-card li { margin-bottom: .4rem; } +.docs-card a { color: var(--red); text-decoration: none; font-size: .95rem; } +.docs-card a:hover { text-decoration: underline; } + +/* NMS feature rows */ +.nms-row { padding: 2.5rem 0; } +.nms-feature { max-width: 680px; } +.nms-feature h2 { font-size: 1.2rem; color: var(--red); margin: 0 0 .25rem; border-bottom: none; padding-bottom: 0; } +.nms-feature h2 a { color: var(--red); text-decoration: none; } +.nms-feature h2 a:hover { text-decoration: underline; } +.nms-feature-sub { font-weight: 600; font-size: .95rem; margin: 0 0 .5rem; color: var(--text); } +.btn-sm-red { + display: inline-block; + margin-top: .75rem; + padding: .4rem 1rem; + background: var(--red); + color: #fff; + border-radius: 4px; + font-size: .875rem; + text-decoration: none; +} +.btn-sm-red:hover { opacity: .88; } + +.feature-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 1rem; + margin-top: 1.5rem; +} + +.feature-card { + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1.25rem; + background: var(--surface); +} + +.feature-card h4 { + margin: 0 0 .4rem; + font-size: .95rem; + font-weight: 700; + color: var(--text); +} + +.feature-card p { + margin: 0; + font-size: .875rem; + color: var(--muted); + line-height: 1.55; +} + +/* ── Nav dropdown ── */ +.site-nav .dropdown { position: relative; } + +.site-nav .dropdown-menu { + display: none; + position: absolute; + top: 100%; + left: 0; + background: #fff; + border: 1px solid var(--border); + border-radius: var(--radius); + min-width: 160px; + box-shadow: 0 4px 12px rgba(0,0,0,.1); + padding: .4rem 0; + padding-left: 0; + margin: 0; + margin-bottom: 0; + list-style: none; + height: auto; +} + +.site-nav .dropdown:hover .dropdown-menu { display: block; } + +.site-nav .dropdown-menu li { margin: 0; padding: 0; } + +.site-nav .dropdown-menu a { + display: block; + padding: .5rem 1rem; + color: var(--text); + font-size: .9rem; + white-space: nowrap; +} + +.site-nav .dropdown-menu a:hover { color: var(--red); background: var(--surface); } + +/* ── Page banner ── */ +.page-banner { + background: var(--red); + padding: 1.5rem 2rem; +} + +.page-banner-inner { + max-width: 1100px; + margin: 0 auto; +} + +.page-banner h1 { + margin: 0; + font-size: 1.8rem; + letter-spacing: -.02em; + color: #fff; +} + +/* ── Breadcrumb ── */ +.breadcrumb { + font-size: .85rem; + color: var(--muted); + margin-bottom: 2rem; +} + +.breadcrumb a { color: var(--muted); } +.breadcrumb a:hover { color: var(--red); } + +/* ── News list ── */ +.news-item { + border-bottom: 1px solid var(--border); + padding-bottom: 1.75rem; + margin-bottom: 1.75rem; +} + +.news-item h2 { margin-top: 0; font-size: 1.4rem; } +.news-item h2 a { color: var(--text); } +.news-item h2 a:hover { color: var(--red); text-decoration: none; } + +.news-date { display: block; color: var(--red); font-size: .9rem; margin-bottom: .6rem; } + +.news-read-more { font-size: .9rem; color: var(--red); font-weight: 500; } +.news-read-more:hover { text-decoration: underline; } + +/* ── News single ── */ +.news-single { max-width: 720px; } +/* -- Download page -- */ +.dl-table { + width: 100%; + border-collapse: collapse; + font-size: .9rem; + margin-bottom: 1.5rem; +} + +.dl-table th, .dl-table td { + padding: .6rem .9rem; + text-align: left; + border: 1px solid var(--border); +} + +.dl-table thead th { background: var(--surface); font-weight: 600; } + +.dl-table .row-stable { background: #f0faf0; } + +/* All markdown-rendered tables on the download page */ +.component-body table, main table { + border-collapse: collapse; + font-size: .875rem; + margin-bottom: 1.5rem; + min-width: 100%; +} + +main table th, main table td { + padding: .5rem .75rem; + border: 1px solid var(--border); + white-space: nowrap; +} + +main table thead th { background: var(--surface); font-weight: 600; } + +/* Wrap wide tables */ +main .table-wrap, main > div[style*="overflow"] { + overflow-x: auto; + margin-bottom: 1.5rem; +} + +/* Make the schedule table scrollable by wrapping all tables in main */ +main table { display: block; overflow-x: auto; white-space: nowrap; } + +.dl-release { + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1.5rem; + margin-bottom: 1.5rem; + background: var(--surface); +} + +.dl-release h3 { margin-top: 0; font-size: 1.1rem; } + +.dl-date { font-weight: 400; color: var(--muted); font-size: .9rem; } + +.dl-meta { font-size: .875rem; color: var(--muted); margin-bottom: 1rem; } + +.status-dl dt { font-weight: 600; margin-top: .75rem; } +.status-dl dd { margin: .2rem 0 0 0; color: var(--muted); font-size: .9rem; } + +.site-footer { + border-top: 1px solid var(--border); + text-align: center; + padding: 2rem 1.5rem; + font-size: .85rem; + color: var(--muted); +} + +.site-footer a { color: var(--muted); text-decoration: underline; } diff --git a/hugo/content/_index.md b/hugo/content/_index.md new file mode 100644 index 0000000000..58b89d0175 --- /dev/null +++ b/hugo/content/_index.md @@ -0,0 +1,5 @@ +--- +title: "Apache ActiveMQ" +--- + +Apache ActiveMQ® is the most popular open source, multi-protocol, Java-based message broker. diff --git a/hugo/content/community/contact.md b/hugo/content/community/contact.md new file mode 100644 index 0000000000..7445dd415a --- /dev/null +++ b/hugo/content/community/contact.md @@ -0,0 +1,41 @@ +--- +url: /contact/ +title: "Contact Us" +--- +url: /contact/ + +Whether you have a simple question about configuration, a use-case you're confused about, a new feature you want to discuss, etc. the community is here to help. + +If you're fairly certain you're hitting a bug [please report it](../issues) via one of our issue trackers. + +#### Mailing Lists + +The **best** way to contact folks in the community is by using one of the mailing lists. + - **Users**: for users configuring & managing an ActiveMQ broker as well as messaging application developers + - **Dev**: for developers working _directly_ on one of the ActiveMQ code-bases + +To subscribe to or unsubscribe from a list simply: + 1. Send a blank email to the appropriate address (see below). + 1. The automated mailing list manager will send an reply (either a confirmation request or an error message, e.g. if you are not subscribed). + 1. Reply to the confirmation message. + + + +|List|Subscribe|Unsubscribe|Web Interface|Archives| +|---|---|---|---|---| +|Users|[users-subscribe@activemq.apache.org](mailto:users-subscribe@activemq.apache.org)|[users-unsubscribe@activemq.apache.org](mailto:users-unsubscribe@activemq.apache.org)|[Apache](https://lists.apache.org/list.html?users@activemq.apache.org)|[Apache](http://mail-archives.apache.org/mod_mbox/activemq-users/), [Markmail](http://activemq.markmail.org/search/list:org.apache.activemq.users)| +|Dev|[dev-subscribe@activemq.apache.org](mailto:dev-subscribe@activemq.apache.org)|[dev-unsubscribe@activemq.apache.org](mailto:dev-unsubscribe@activemq.apache.org)|[Apache](https://lists.apache.org/list.html?dev@activemq.apache.org)|[Apache](http://mail-archives.apache.org/mod_mbox/activemq-dev/), [Markmail](http://activemq.markmail.org/search/list:org.apache.activemq.dev)| + +Mailing list participants are expected to abide by the well-established rules of "netiquette," as well as the ASF's published [Code of Conduct](https://www.apache.org/foundation/policies/conduct.html). + +**Please read these [tips for email contributors](https://apache.org/dev/contrib-email-tips.html)**, especially if you're not getting the support you expect. + +If you're curious you can [read more](https://apache.org/foundation/mailinglists.html) about how these lists work at Apache. + +#### Chat + +If for some reason a mailing list doesn't work for you then you can potentially chat with other community members in real-time using **[Slack](https://slack.com/)**. Access to the [ASF Slack](https://the-asf.slack.com) requires an invitation. If you want an invitation to the ActiveMQ Slack channel simply send a request to the [users mailing list](#mailing). + +#### Artemis + +For Artemis, consult the [Apache Artemis](https://artemis.apache.org) website. diff --git a/hugo/content/community/contributing.md b/hugo/content/community/contributing.md new file mode 100644 index 0000000000..a4ca1ac94e --- /dev/null +++ b/hugo/content/community/contributing.md @@ -0,0 +1,49 @@ +--- +url: /contributing/ +title: "Contributing" +--- +url: /contributing/ + +There are many ways you can help make ActiveMQ a better piece of software - please dive in and help! + + - If you have a problem with the software or the documentation the first thing you might consider is [asking a question](contact#mailing). + - If you think you've hit a bug or want to request a new feature feel free to open [an issue](issues) in one of our trackers. + - If you're already familiar with an ActiveMQ component then join a [mailing list](contact#mailing) and help answers questions from the community. + +#### Documentation + +If anything in any component's documentation is confusing or not clear please [let us know](contact). + +#### Code + +If you want to get your hands on the code here are the repos for all our components. It's typically best to use the GitHub mirror as that will allow you to easily send pull requests which can be reviewed by project committers and merged. The Gitbox links redirect to GitHub for browsing. + +|Component|Apache Git Repository|GitHub Mirror| +|---|---|---| +|ActiveMQ|[activemq](https://gitbox.apache.org/repos/asf/activemq.git)|[activemq](https://github.com/apache/activemq)| +|NMS API|[activemq-nms-api](https://gitbox.apache.org/repos/asf/activemq-nms-api.git)|[activemq-nms-api](https://github.com/apache/activemq-nms-api)| +|NMS AMQP|[activemq-nms-amqp](https://gitbox.apache.org/repos/asf/activemq-nms-amqp.git)|[activemq-nms-amqp](https://github.com/apache/activemq-nms-amqp)| +|NMS EMS|[activemq-nms-ems](https://gitbox.apache.org/repos/asf/activemq-nms-ems.git)|[activemq-nms-ems](https://github.com/apache/activemq-nms-ems)| +|NMS OpenWire|[activemq-nms-openwire](https://gitbox.apache.org/repos/asf/activemq-nms-openwire.git)|[activemq-nms-openwire](https://github.com/apache/activemq-nms-openwire)| +|NMS MSMQ|[activemq-nms-msmq](https://gitbox.apache.org/repos/asf/activemq-nms-msmq.git)|[activemq-nms-msmq](https://github.com/apache/activemq-nms-msmq)| +|NMS STOMP|[activemq-nms-stomp](https://gitbox.apache.org/repos/asf/activemq-nms-stomp.git)|[activemq-nms-stomp](https://github.com/apache/activemq-nms-stomp)| +|NMS XMS|[activemq-nms-xms](https://gitbox.apache.org/repos/asf/activemq-nms-xms.git)|[activemq-nms-xms](https://github.com/apache/activemq-nms-xms)| +|NMS ZMQ|[activemq-nms-zmq](https://gitbox.apache.org/repos/asf/activemq-nms-zmq.git)|[activemq-nms-zmq](https://github.com/apache/activemq-nms-zmq)| +|CLI Tools|[activemq-cli-tools](https://gitbox.apache.org/repos/asf/activemq-cli-tools.git)|[activemq-cli-tools](https://github.com/apache/activemq-cli-tools)| +|CPP|[activemq-cpp](https://gitbox.apache.org/repos/asf/activemq-cpp.git)|[activemq-cpp](https://github.com/apache/activemq-cpp)| +|Website|[activemq-website](https://gitbox.apache.org/repos/asf/activemq-website.git)|[activemq-website](https://github.com/apache/activemq-website)| + +#### Becoming a committer + +If you're interested in becoming a "committer" please check out [this guide from Apache](https://infra.apache.org/new-committers-guide.html). + +#### Mailing Lists for Development Updates + +|List|Subscribe|Unsubscribe|Archives|Summary| +|---|---|---|---|---| +|Commits|[commits-subscribe@activemq.apache.org](mailto:commits-subscribe@activemq.apache.org)|[commits-unsubscribe@activemq.apache.org](mailto:commits-unsubscribe@activemq.apache.org)|[Apache](https://lists.apache.org/list.html?commits@activemq.apache.org), [Apache 2](http://mail-archives.apache.org/mod_mbox/activemq-commits/), [Markmail](http://activemq.markmail.org/search/list:org.apache.activemq.commits)|notifications when the project source code gets updated| +|Gitbox|[gitbox-subscribe@activemq.apache.org](mailto:gitbox-subscribe@activemq.apache.org)|[gitbox-unsubscribe@activemq.apache.org](mailto:gitbox-unsubscribe@activemq.apache.org)|[Apache](https://lists.apache.org/list.html?gitbox@activemq.apache.org), [Apache 2](http://mail-archives.apache.org/mod_mbox/activemq-gitbox/), [Markmail](http://activemq.markmail.org/search/list:org.apache.activemq.gitbox)|comments and other events for pull-requests| + +#### Artemis + +For Artemis, consult the [Apache Artemis](https://artemis.apache.org) website. diff --git a/hugo/content/community/issues.md b/hugo/content/community/issues.md new file mode 100644 index 0000000000..daa07af09c --- /dev/null +++ b/hugo/content/community/issues.md @@ -0,0 +1,53 @@ +--- +url: /issues/ +title: "Reporting Issues" +--- +url: /issues/ + +If you find a bug please raise a new issue in the appropriate tracker. If you're not quite sure you're hitting a bug consider [contacting us](contact) to get some clarity. + +Whenever you are reporting a problem please be sure to include as much information as possible; the more we know the more chance of a quicker resolution. Here's a few items to consider: + +* Which version of the component are you using on which Java platform? +* Any particular application/web server or container being used? If so what version? +* Stack traces generally really help! If in doubt include the whole thing. Often exceptions get wrapped in other exceptions and the exception right near the bottom explains the actual error, not the first few lines at the top. +* Log output can be useful too. Sometimes enabling `DEBUG` logging can help. +* Your code & configuration files are often useful. + +We can help you much quicker if you try the following: + +* Provide us with a JUnit test case that demonstrates your issue. For example, if you think you've found a bug can you create a test case to demonstrate the bug? +* [Send a PR](contributing) to fix the bug! +* For memory leaks or performance related issues, if you can run a profiler on your test case and attach the output as a file (or zipped file if it's huge) to the issue we can normally fix things much faster. e.g. you could run [jmap](https://docs.oracle.com/javase/7/docs/technotes/tools/share/jmap.html)/[jhat](https://docs.oracle.com/javase/7/docs/technotes/tools/share/jhat.html), JProfiler or YourKit on your code and send us the output. To find memory leaks it's quicker to resolve if you can tell us what classes are taking up all of the RAM; we can normally figure out what's wrong from that. + +|Component|Issue Tracker| +|---|---| +|ActiveMQ|[https://issues.apache.org/jira/projects/AMQ](https://issues.apache.org/jira/projects/AMQ)| +|NMS|[https://issues.apache.org/jira/projects/AMQNET](https://issues.apache.org/jira/projects/AMQNET)| +|CMS|[https://issues.apache.org/jira/projects/AMQCPP](https://issues.apache.org/jira/projects/AMQCPP)| + +#### Using the issue tracker + +Before you can create an issue in the issue tracker you need to [request an account](https://selfserve.apache.org/jira-account.html). When requesting the account please **be specific** about the reason you need it. Please give a brief synopsis of the bug you're encountering or feature you need. If you're not quite sure you're hitting an actual bug or you're not sure if the feature you need is valid, etc. please [contact us on the users mailing list](contact) to get some clarity. Account requests with vague reasons **will be rejected**. + +If you want to be the "assignee" of an issue you need to be in the list of `activemq-developers` on the issue tracker. To join the group please mail the [dev mailing list](mailto:dev@activemq.apache.org) with the email address you used to register with the issue tracker and we'll add you to the group. + +#### Contributing Your Own Fixes + +Want to do some hacking on ActiveMQ? Try surfing to our issue trackers for open issues or features that need to be implemented. Take ownership of an issue and try fix it. See the article on [contributing](contributing) for more details on how to get the code. + +If you can create a JUnit test case then your issue is more likely to be resolved quicker. Then we can add your issue to the test suite and then we'll know when its really fixed and we can ensure that the problem **stays fixed** in future releases. + +#### ActiveMQ Issues Mailing List + +This mailing list is automatically notified when JIRA issues are created and updated. + +Subscribe|[issues-subscribe@activemq.apache.org](mailto:issues-subscribe@activemq.apache.org) +Unsubscribe|[issues-unsubscribe@activemq.apache.org](mailto:issues-unsubscribe@activemq.apache.org) +Web Interface|[https://lists.apache.org/list.html?issues@activemq.apache.org](https://lists.apache.org/list.html?issues@activemq.apache.org) +Apache Archive|[http://mail-archives.apache.org/mod_mbox/activemq-issues/](http://mail-archives.apache.org/mod_mbox/activemq-issues/) +Mark Mail Archive|[http://activemq.markmail.org/search/list:org.apache.activemq.issues](http://activemq.markmail.org/search/list:org.apache.activemq.issues) + +#### Artemis + +For Artemis, consult the [Apache Artemis](https://artemis.apache.org) website. diff --git a/hugo/content/community/support.md b/hugo/content/community/support.md new file mode 100644 index 0000000000..c79a11da15 --- /dev/null +++ b/hugo/content/community/support.md @@ -0,0 +1,28 @@ +--- +url: /support/ +title: "Support" +--- +url: /support/ + +Support is divided into two main categories - **community** and **commercial**. + +#### Community Support + +This is an open source project so the amount of time community members have available to help resolve your issue is often limited as help is provided on a volunteer basis from [individuals](https://www.apache.org/foundation/how-it-works/#hats). However, it is *free* and you are often able to discuss issues with the developers who actually wrote the code you are running. + +If you want community support then please [contact us](contact). If you're fairly certain you're hitting a bug [please report it](issues) via one of our issue trackers. Be sure to review these pages carefully as they contain tips and tricks about working with Apache communities in general and ActiveMQ in particular. + +#### Commercial Support {#commercial-support} + +If you want to get priority help, need to get up to speed quickly, require some training or mentoring, or need full 24 x 7 production support you should contact a commercial company specializing in ActiveMQ support such as... + +* [apifocal](https://apifocal.com) is a Professional Services company. Headquartered near Washington, DC, USA, APIfocal provides consulting and training for leveraging the Apache Integration stack and commercial ESBs at large scale, adding automation and devops capabilities. +* [Amazon Web Services](https://aws.amazon.com/) provides [Amazon MQ](https://aws.amazon.com/amazon-mq/), a managed message broker service for Apache ActiveMQ "Classic" in the cloud. Amazon MQ manages the work involved in setting up an ActiveMQ message broker, from provisioning the infrastructure capacity you request–including server instances and storage–to installing the broker software itself. Once your broker is up and running, Amazon MQ automates common administrative tasks such as patching the operating system and ActiveMQ software. +* [HYTE](https://hyte.io/activemq-support/) Under the Apache License, HYTE offers HYTE MQ, an Open Source package of Apache ActiveMQ which provides enterprises a single distribution to support all DevOps pipelines and allows deployment in any environment: containers, cloud and on-premise. HYTE MQ is pre-configured with deployment and consulting best practices to ensure stability and ease of maintenance. HYTE's commercial offerings include: HYTE Console which provides a self-service, multi-tenant management capability across ActiveMQ and IBM MQ deployments, numerous production support packages, multi-platform message bridging, and consulting services. +* [meshIQ](https://www.meshiq.com/) provides expert support for Apache ActiveMQ and Apache Artemis, ensuring optimal performance and reliability. Their services include proactive monitoring, troubleshooting, and rapid issue resolution. With an integration ActiveMQ/Artemis console, meshIQ offers enhanced visibility into your ActiveMQ and Artemis brokers, simplifying management and reducing downtime. Learn more about [meshIQ's comprehensive Apache ActiveMQ and Apache Artemis support here](https://www.meshiq.com/meshiq-activemq-console). +* [OpenLogic](http://www.openlogic.com/) by Perforce has a team of ActiveMQ experts ready to help you, providing 24/7 support for troubleshooting issues and outages, consulting on architecture and design, instructor-led hands-on training. In addition to supporting many Apache packages OpenLogic's enterprise architects have expertise in over 400 open source packages. +* [Red Hat](https://developers.redhat.com/products/amq/overview) offers AMQ Broker, a supported distribution of Apache ActiveMQ that includes enterprise developer and production support as well as training and consultancy for enterprise deployments. +* [Savoir Technologies, Inc](http://www.savoirtech.com) provides enterprise consulting, training and support for ActiveMQ "Classic", ActiveMQ Artemis, and a host of other Apache service containers. Savoir can provide best practice mentoring for developing with ActiveMQ and ActiveMQ Artemis, as well as architectural/design reviews, troubleshooting and SOA infrastructure implementations. Savoir's staff includes some of the contributors of ActiveMQ and ActiveMQ Artemis who are on the ground consulting and are familiar with real world implementations and issues. +* [Total Transaction Management (TTM)](http://www.ttmsolutions.com/) provides ActiveMQ consulting and support, as well as security and [monitoring](http://www.ttmsolutions.com/Transactional_Software_Solutions/Active_Monitor_AMon.php/) add-on products and [reference guide](http://www.ttmsolutions.com/Apache_Software/ActiveMQ_Reference_Guide.php) for ActiveMQ. +* [Tomitribe](http://tomitribe.com) are experts in Tomcat and ActiveMQ integration, champions of Open Source and Java EE. Tomitribe offers consulting, training and support for TomEE, Tomcat, ActiveMQ, CXF and more. +* [Yupiik](https://www.yupiik.com) contributes and commits to the Apache ActiveMQ project. Provides consulting, training and support for Apache ActiveMQ and related projects like Apache Karaf, Apache Camel, Apache Kafka, Apache Unomi. diff --git a/hugo/content/components/_index.md b/hugo/content/components/_index.md new file mode 100644 index 0000000000..e55014ff45 --- /dev/null +++ b/hugo/content/components/_index.md @@ -0,0 +1,4 @@ +--- +title: Components +layout: redirect +--- diff --git a/hugo/content/components/classic/_index.md b/hugo/content/components/classic/_index.md new file mode 100644 index 0000000000..a48f0527a8 --- /dev/null +++ b/hugo/content/components/classic/_index.md @@ -0,0 +1,54 @@ +--- +title: "ActiveMQ" +subtitle: "The Tried and Trusted Open Source Message Broker" +--- + +Apache ActiveMQ® is a popular and powerful open source messaging and [Integration Patterns](documentation/enterprise-integration-patterns) server. Released under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0). + +Grab yourself a [download](/download/), review the [Getting Started Guide](documentation/getting-started), surf the [FAQ](documentation/faq), or start [contributing](/contributing/). + +--- + +
    + +
    +

    Multi-Protocol

    +

    Supports OpenWire, STOMP, AMQP 1.0, and MQTT 3.1 — connect from Java, C, C++, Python, Ruby, .NET and more.

    +
    + +
    +

    Enterprise Integration

    +

    Full support for Enterprise Integration Patterns in both the JMS client and the broker.

    +
    + +
    +

    JMS & Jakarta Messaging

    +

    Full JMS 1.1 and J2EE 1.4+ support, with partial Jakarta Messaging 3.1 & JMS 2.0 support including transient, persistent, transactional and XA messaging.

    +
    + +
    +

    High Availability

    +

    Designed for clustering, client-server and peer communication. Fast persistence via JDBC and a high-performance journal.

    +
    + +
    +

    Spring & J2EE Ready

    +

    Spring integration out of the box. Tested with TomEE, Geronimo, JBoss, GlassFish and WebLogic. Includes JCA 1.5 resource adaptors.

    +
    + +
    +

    Flexible Transport

    +

    Pluggable transport protocols: TCP, SSL, NIO, UDP, multicast, JGroups, JXTA and in-VM.

    +
    + +
    +

    Web & REST

    +

    REST API for language-neutral messaging. Ajax support for web streaming via pure DHTML.

    +
    + + + +
    diff --git a/hugo/content/components/classic/documentation/_index.md b/hugo/content/components/classic/documentation/_index.md new file mode 100644 index 0000000000..e1ec8ceae3 --- /dev/null +++ b/hugo/content/components/classic/documentation/_index.md @@ -0,0 +1,29 @@ +--- +title: ActiveMQ Documentation +layout: docs +--- + +- [Overview](overview) + - [New Features](new-features) + - [Getting Started](getting-started) + - [FAQ](faq) + - [Articles](articles) + - [Books](books) + - [License](http://www.apache.org/licenses/) + - [Latest Javadoc](maven/apidocs/) +- [Features](features) +- [Connectivity](connectivity) +- [Using ActiveMQ Classic](using-activemq-classic-5) +- [Tools](tools) +- [Developers](developers) +- Tests + - [Maven2 Performance Plugin](activemq-classic-performance-module-users-manual) + - [Benchmark Tests](benchmark-tests) + - [JMeter System Tests](jmeter-system-tests) + - [JMeter Performance Tests](jmeter-performance-tests) + - [Integration Tests](integration-tests) +- Project Reports + - [JUnit Reports](junit-reports) + - [Source XRef](source-xref) + - [Test Source XRef](test-source-xref) + - [Xml Reference](xml-reference) diff --git a/hugo/content/components/classic/documentation/activemq-classic-command-line-tools-reference.md b/hugo/content/components/classic/documentation/activemq-classic-command-line-tools-reference.md new file mode 100644 index 0000000000..6b3a51d377 --- /dev/null +++ b/hugo/content/components/classic/documentation/activemq-classic-command-line-tools-reference.md @@ -0,0 +1,258 @@ +--- +title: ActiveMQ Classic Command Line Tools Reference +layout: classic-doc +--- + + + +Command Line Tools +================== + +The current script contains the entire functionality to manage activemq. + +* [activemq](activemq-classic-command-line-tools-reference) - runs an activemq broker (see [Unix Shell Script](unix-shell-script)) + +In versions prior 5.4.1 some management functionalities beyond controlling the service itself where part of the "activemq-admin" script. +This script is currently still part of the distribution to provide access to this for Windows users- + +* [activemq-admin](activemq-classic-command-line-tools-reference) - manages a broker instance + +In versions prior to 5.0 the functionality of activemq-admin script was scattered over multiple scripts, such as: + +* [shutdown](activemq-classic-command-line-tools-reference) - shutdowns an activemq broker +* [list](activemq-classic-command-line-tools-reference) - lists all running brokers in the specified JMX context +* [query](activemq-classic-command-line-tools-reference) - queries the JMX context for broker statistics and information +* [bstat](activemq-classic-command-line-tools-reference) - predefined query that displays useful broker statistics +* [browse](activemq-classic-command-line-tools-reference) - browse the messages of a specific queue +* [purge](activemq-classic-command-line-tools-reference) - delete selected destination's messages that matches the message selector + +activemq script +--------------------- + +> **Description of this script is valid for Windows platform.** For Unix platform it is valid for broker versions prior to 5.4.0. With version 5.4.0 and later, ActiveMQ Classic comes with enhanced [Unix Shell Script](unix-shell-script) + +Script Name|activemq.bat, activemq +Task Usage|_activemq [options] [config]_ or _java -jar run.jar start [options] [config]_ +Description|Script to run an activemq broker either by specifying a broker configuration file or through a broker URI configuration. + +**Options:** + +Option Name|Syntax|Example|Description +---|---|---|--- +System Define Option|-D=|-Dactivemq.home=c:/ActiveMQ|Sets a systems property. i.e Systems.getProperty("activemq.home"); will return c:/ActiveMQ +Help Option|-h or -? or --help|activemq --help|Display the help messages for the activemq script. +Version Option|--version|activemq --version|Display the activemq version information. + +**Examples:** + +Example|Description +---|--- +activemq|Runs a broker using the default 'xbean:activemq.xml' as the broker configuration file. +activemq xbean:myconfig.xml|Runs a broker using the file myconfig.xml as the broker configuration file that is located in the classpath. +activemq xbean:file:./conf/broker1.xml|Runs a broker using the file broker1.xml as the broker configuration file that is located in the relative file path ./conf/broker1.xml +activemq xbean:file:C:/ActiveMQ/conf/broker2.xml|Runs a broker using the file broker2.xml as the broker configuration file that is located in the absolute file path C:/ActiveMQ/conf/broker2.xml +activemq broker:(tcp://localhost:61616, tcp://localhost:5000)?useJmx=true|Runs a broker with two transport connectors and JMX enabled.¹ +activemq broker:(tcp://localhost:61616, network:tcp://localhost:5000)?persistent=false|Runs a broker with 1 transport connector and 1 network connector with persistence disabled.¹ + +For details on how to configure using broker URI refer to: [Broker Configuration URI](broker-configuration-uri) + +activemq-admin +-------------- + +As of ActiveMQ Classic 5.x, the above standalone utilities have been incorporated into the activemq-admin command (with the exception of the activemq script), as follows: + +* [activemq-admin stop](activemq-classic-command-line-tools-reference) +* [activemq-admin list](activemq-classic-command-line-tools-reference) +* [activemq-admin query](activemq-classic-command-line-tools-reference) +* [activemq-admin bstat](activemq-classic-command-line-tools-reference) +* [activemq-admin browse](activemq-classic-command-line-tools-reference) + +The syntax of each task remains as described below. Note also that the activemq command is still supported. + +### stop task + +Task Name|stop +Task Usage|_activemq-admin stop [options] [broker names]_ +Description|Script to stop a running activemq broker. This task requires that JMX is enabled. + +**Options:** + +Option Name|Syntax|Example|Description +---|---|---|--- +Stop All Option|--all|stop --all|Stops all registered brokers in the specified JMX context +JMX URL Option|--jmxurl |--jmxurl service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi|Change the JMX service url to connect to. By default it connects to: service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi +JMX Authentication Option|--jmxuser user --jmxpassword password|--jmxuser smx --jmxpassword smx|For cases where username/password based authentication of the JMX client is required. Not set by default. +System Define Option|-D=|-Dactivemq.home=c:/ActiveMQ|Sets a systems property. i.e Systems.getProperty("activemq.home"); will return c:/ActiveMQ +Help Option|-h or -? or --help|--help|Display the help messages for the stop script. +Version Option|--version|activemq --version|Display the activemq version information. + +**Examples:** + +Example|Description +---|--- +activemq-admin stop|Stops the only running broker in the default JMX context. It assumes that there is only one running broker. +activemq-admin stop --jmxurl service:jmx:rmi:///jndi/rmi://remotehost:1099/jmxrmi --all|Stops all the running broker in the specified JMX context. +activemq-admin stop localhost|Stops the broker named 'localhost' in the default JMX context. +activemq-admin stop localhost remotehost|Stops the brokers 'localhost' and 'remotehost' in the default JMX context. + +### list task + +Task Name|list +Task Usage|_activemq-admin list [options]_ +Description|Script to list the names of all running brokers in the specified JMX context. This task requires that JMX is enabled. + +**Options:** + +Option Name|Syntax|Example|Description +---|---|---|--- +JMX URL Option|--jmxurl |--jmxurl service:jmx:rmi:///jndi/rmi://remotehost:1099/jmxrmi|Change the JMX service url to connect to. By default it connects to: service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi +JMX Authentication Option|--jmxuser user --jmxpassword password|--jmxuser smx --jmxpassword smx|For cases where username/password based authentication of the JMX client is required. Not set by default. +System Define Option|-D=|-Dactivemq.home=c:/ActiveMQ|Sets a systems property. i.e Systems.getProperty("activemq.home"); will return c:/ActiveMQ +Help Option|-h or -? or --help|--help|Display the help messages for the list script. +Version Option|--version|activemq --version|Display the activemq version information. + +**Examples:** + +Example|Description +---|--- +activemq-admin list|Lists the names of all running brokers in the default JMX context. +activemq-admin list --jmxurl service:jmx:rmi:///jndi/rmi://remotehost:1099/jmxrmi|List the names of all running brokers in the specified JMX context. + +### query task + +Task Name|query +Task Usage|_activemq-admin query [options]_ +Description|Script to query the specified JMX context for mbean attributes and information. This script requires that JMX is enabled. + +**Options:** + +Option Name|Syntax|Example|Description +---|---|---|--- +Predefined Query Option|-Q<type>=<name>|-QTopic=TEST.FOO, -QBroker=*host|Predefined object name query option that queries a specific type of mbean object based on its type and selected identifier. Refer to the mbean reference table below for details. +|-xQ<type>=<name>|-xQTopic=ActiveMQ.Advisory.*, -xQNetworkConnector=*|Predefined object name query option that removes all mbeans that matches the query from the search result. Refer to the mbean reference table below for details. +Object Name Query Option|--objname <object name query>|--objname Type=**Connect**,BrokerName=local*|Query option loosely based on the JMX object name format, which lets you filter mbeans based on their object name information. Refer to the mbean reference table below for details. +|--xobjname <object name query>|--xobjname Type=Topic,Destination=ActiveMQ.Advisory.*|Object name query that removes all mbeans that matches the query from the search result. Refer to the mbean reference table below for details. +View Option|--view <view list>|--view Type,BrokerName,Destination,EnqueueCount,DequeueCount|Lets you specify the attributes and object name information to view. If the view is omitted, all attributes and information will be displayed. +JMX URL Option|--jmxurl <url>|--jmxurl service:jmx:rmi:///jndi/rmi://remotehost:1099/jmxrmi|Change the JMX service url to connect to. By default it connects to: service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi +JMX Authentication Option|--jmxuser user --jmxpassword password|--jmxuser smx --jmxpassword smx|For cases where username/password based authentication of the JMX client is required. Not set by default. +System Define Option|-D<key>=<value>|-Dactivemq.home=c:/ActiveMQ|Sets a systems property. i.e Systems.getProperty("activemq.home"); will return c:/ActiveMQ +Help Option|-h or -? or --help|--help|Display the help messages for the query script. +Version Option|--version|activemq --version|Display the activemq version information. + +**Examples:** + +Example|Description +---|--- +activemq-admin query|Display all attributes and object name information of all registered mbeans in the default JMX context. +activemq-admin query -QTopic=TEST.FOO|Display all the attributes and object name information of the destination topic 'TEST.FOO' +activemq-admin query -QQueue=*|Display all the attributes and object name information of all registered queues. +activemq-admin query -QTopic=*.FOO -xQTopic=ActiveMQ.Advisory.*|Display all the attributes and object name information of all topics that ends with '.FOO' except those that also begins with 'ActiveMQ.Advisory.'. +activemq-admin query -QBroker=local???? --view Type,BrokerName,EnqueueCount,DequeueCount|Display the object type, broker name, enqueue count, and dequeue count information for all 9-letter brokers that begins with 'local'. +activemq-admin query --objname Type=**Connect**,BrokerName=localhost -xQNetworkConnector=*|Display all the attributes and object name information for all connections and connectors for broker 'localhost' except its network connectors. +activemq-admin query --objname Type=Connection --xobjname Type=Connection,BrokerName=localhost|Display all the attributes and object name information for all registered connections except those belonging to broker 'localhost'. +activemq-admin query -QQueue=???? --objname Type=Connection --xobjname BrokerName=remote*|Display all the attributes and object name information for all 4-letter queues and connections except those belonging to a broker that begins with 'remote'. + +**ActiveMQ Classic MBean Reference:** + +Mbean Type|Properties / ObjectName |Attributes|Operations +---|---|---|--- +Broker|**type=Broker**, **brokerName=<broker-identifier>**|BrokerId, TotalEnqueueCount, TotalDequeueCount, TotalConsumerCount, TotalMessageCount, TotalConnectionsCount, TotalConsumerCount, TotalProducerCount, MemoryLimit, MemoryPercentUsage, StoreLimit, StorePercentUsage|start, stop, terminateJVM, resetStatistics, gc +Destination|**type=Broker**, **brokerName=<name-of-broker>**, **destinationType=Queue\|Topic**, **destinationName=<name>**|Average, EnqueueTime, ConsumerCount, DequeueCount, EnqueueCount, ExpiredCount, InFlightCount, MemoryLimit, MemoryPercentUsage, Name, QueueSize (queues only)|browseMessages, gc, purge, resetStatistics +NetworkConnector|**type=Broker**, **brokerName==<name-of-broker>**, **connector=networkConnectors**, **networkConnectorName==<connector-identifier>**|Name, Duplex, DynamicOnly, BridgeTempDestinations, ConduitSubscriptions, DecreaseNetworkConsumerPriority, DispatchAsync, DynamicOnly, NetworkTTL, Password, PrefetchSize|start, stop +Connector|**type=Broker**, **brokerName=<name-of-broker>**, **connector=clientConnectors**, **ConnectorName==<connector-identifier>**|StatisticsEnabled|start, stop, resetStatistics, enableStatistics, disableStatistics, connectionCount +Connection|**type=Broker**, **brokerName=<name-of-broker>**, **connectionViewType=clientId**, **connectionName==<connection-identifier>**|DispatchQueueSize, Active, Blocked, Connected, Slow, Consumers, Producers, RemoteAddress, UserName, ClientId|start, stop, resetStatistics +PersistenceAdapter|**type=Broker**, **brokerName=<name-of-broker>**, **Service=PersistenceAdapter**, **InstanceName==<adapter-identifier>**|Name, Size, Data, Transactions| +Health|**type=Broker**, **brokerName=<name-of-broker>**, **Service=Health**|CurrentStatus|health + + + +### bstat task + +Task Name|bstat +Task Usage|_activemq-admin bstat_ [broker name] +Description|Predefined query script that displays useful statistics regarding a broker and its components. + +**Examples:** + +Example|Description +---|--- +activemq-admin bstat|Display useful statistics for all registered brokers in the default JMX context. +activemq-admin bstat localhost|Display useful statistics for the registered broker 'localhost'. + +### browse task + +Task Name|browse +Task Usage|_activemq-admin browse --amqurl <broker url> [options] <destinations>_ or _java -jar run.jar browse --amqurl <broker url> [options] <destinations>_ +Description|Script to browse selected destinations' messages.  The browse operation may not return all messages due to limitations of broker configuration and system resources. + +**Options:** + +Option Name|Syntax|Example|Description +---|---|---|--- +Broker URL Option|--amqurl <url>|--amqurl tcp://localhost:61616|Specify the broker URL to connect to. +Message Selector Option|--msgsel "<msgsel1,msgsel2,...>"|--msgsel "JMSMessageID='*:10',JMSPriority>5"|Allows you to filter the specific messages to view. Place the entire selector criteria in double quotes " ". You can use wildcard queries by enclosing the string message property in ' '. Other than using wildcard queries to filter string properties, other queries follows the message selector format. +Group View Option|-V[header \| custom \| body]|-Vheader, -Vcustom, -Vbody|Let's you specify a specific group of message attributes to view. The header view shows all the standard JMS message headers. The custom view shows all the custom fields added to each JMS message. The body view shows the message body of the JMS message. +Specific View Option|--view <attr1>,[header:\|custom:]<attr2>,...|--view JMSMessageID='*:10',custom:MyCustomField|Let's you specifically select a specific message attribute. It allows you to select specific attributes from the JMS and custom headers. You could add the tags header: and custom: to explicitly specify where the attribute belongs to. Refer to the message header table below for details. +System Define Option|-D<key>=<value>|-Dactivemq.home=c:/ActiveMQ|Sets a systems property. i.e Systems.getProperty("activemq.home"); will return c:/ActiveMQ +Help Option|-h or -? or --help|--help|Display the help messages for the browse script. +Version Option|--version|activemq --version|Display the activemq version information. + +**Examples:** + +Example|Description +---|--- +activemq-admin browse --amqurl tcp://localhost:61616 TEST.FOO|Prints the JMS message header, custom message header, and message body of the messages in the queue 'TEST.FOO' +activemq-admin browse --amqurl tcp://localhost:61616 -Vheader,body TEST.FOO|Prints the JMS message header and message body of the messages in the queue 'TEST.FOO' +activemq-admin browse --amqurl tcp://localhost:61616 -Vheader --view custom:MyCustomField TEST.FOO TEST.BAR|Prints all the JMS message header and the custom field 'MyCustomField' of the messages in the queue 'TEST.FOO' and 'TEST.BAR'. +activemq-admin browse --amqurl tcp://localhost:61616 --msgsel "JMSMessageID='*:10',JMSPriority>5" TEST.FOO|Prints all the attributes of the messages in the queue 'TEST.FOO' that has a JMSMessageID that matches the wildcard query *:10 and has a JMSPriority greater than 5. + +**JMS Message Header Reference:** + +Header Name|Header Type +---|--- +JMSCorrelation ID|String +JMSDelivery Mode|int (1-Non-Persistent, 2-Persistent) +JMSDestination|javax.jms.Destination +JMSExpiration|long +JMSMessageID|String +JMSPriority|int +JMSRedelivered|boolean +JMSReplyTo|javax.jms.Destination +JMSTimestamp|long +JMSType|String + +### purge task + +Task Name|purge +Task Usage|_activemq-admin purge_ [purge-options] +Description|Delete selected destination's messages that matches the message selector. + +**Options:** + +Option Name|Syntax|Example|Description +---|---|---|--- +JMX URL Option|--jmxurl <url>|--jmxurl service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi|Change the JMX service url to connect to. By default it connects to: service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi +JMX Authentication Option|--jmxuser user --jmxpassword password|--jmxuser smx --jmxpassword smx|For cases where username/password based authentication of the JMX client is required. Not set by default. +Message Selector Option|--msgsel "<msgsel1,msgsel2,...>"|--msgsel "JMSMessageID='*:10',JMSPriority>5"|Allows you to filter the specific messages to view. Place the entire selector criteria in double quotes " ". You can use wildcard queries by enclosing the string message property in ' '. Other than using wildcard queries to filter string properties, other queries follows the message selector format. +System Define Option|-D<key>=<value>|-Dactivemq.home=c:/ActiveMQ|Sets a systems property. i.e Systems.getProperty("activemq.home"); will return c:/ActiveMQ +Help Option|-h or -? or --help|--help|Display the help messages for the browse script. +Version Option|--version|activemq --version|Display the activemq version information. + +**Examples:** + +Example|Description| +activemq-admin purge FOO.BAR|Delete all the messages in queue FOO.BAR +activemq-admin purge --msgsel "JMSMessageID='*:10',JMSPriority>5" FOO.*|Delete all the messages in the destinations that matches FOO.* and has a JMSMessageID in", the header field that matches the wildcard *:10, and has a JMSPriority field > 5 in the", queue FOO.BAR. To use wildcard queries, the field must be a string and the query enclosed in '' + +### dstat task + +Task Name|dstat +Task Usage|_activemq-admin dstat_ [destination type] +Description|Predefined query script that displays useful statistics regarding destinations on a broker. + +**Examples:** + +Example|Description +---|--- +activemq-admin dstat|Display useful statistics for all destinations on the broker in the default JMX context. +activemq-admin dstat topics|Display useful statistics for the Topics that currently exist on the Broker. \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/activemq-classic-performance-module-users-manual.md b/hugo/content/components/classic/documentation/activemq-classic-performance-module-users-manual.md new file mode 100644 index 0000000000..7be78428b8 --- /dev/null +++ b/hugo/content/components/classic/documentation/activemq-classic-performance-module-users-manual.md @@ -0,0 +1,101 @@ +--- +title: ActiveMQ Classic Performance Module Users Manual +layout: classic-doc +--- + +## Running Maven 2 Performance Test + +This [Maven 2](http://maven.apache.org) plugin allows you to run performance tests easily using the Maven command line or run tests automatically in [Continuum](http://maven.apache.org/continuum/). + +### Prerequisites + +Starting with ActiveMQ Classic 5.5 and above the plugin can be obtained from maven or if you download the src from GIT you can build it yourself. Start with a complete build of Apache ActiveMQ Classic and then do: +``` +cd activemq-tooling +mvn clean install +``` +To run the following Maven goals make sure you are inside a Maven2 project directory where its POM is enabled with the Maven2 plugin. + +### Getting Started + +To get started, switch to the [activemq-perftest directory from the sandbox repo](http://svn.apache.org/repos/asf/activemq/sandbox/activemq-perftest/), or to a directory containing your own Maven POM with the following plugin defined: +```xml + + org.apache.activemq.tooling + activemq-perf-maven-plugin + ${activemq-version} + +``` +In ActiveMQ Classic versions prior to 5.8, the artifactId was `maven-activemq-perf-plugin`. + +Type the following commands into separate shells (the broker line here is optional if you have a preconfigured one running): +``` +mvn activemq-perf:broker -Durl=broker:tcp://localhost:61616 +mvn activemq-perf:consumer +mvn activemq-perf:producer +``` +If you run the broker on a different machine then change the producer and consumer commands to: +``` +mvn activemq-perf:consumer -Dfactory.brokerURL=tcp://host:port +mvn activemq-perf:producer -Dfactory.brokerURL=tcp://host:port +``` + +When you run the producer & consumer, it generates an XML performance report in the current directory. + +### Maven Goals + +| Goal | Description | +|------|-------------| +| `activemq-perf:broker` | Starts broker using the activemq configuration file located in `src/main/resources/broker-conf`. Parameters: `-DconfigType` specifies the config type; `-DconfigFile` path to an alternate config file. | +| `activemq-perf:consumer` | Starts the consumer's performance testing. Report saved to `sysTest.reportDir`. | +| `activemq-perf:producer` | Starts the producer's performance testing. Report saved to `sysTest.reportDir`. | + +### Configuration for Running a System of JMS Clients + +| Configuration Key | Default Value | Description | +|---|---|---| +| `sysTest.propsConfigFile` | null | Use properties specified externally in a key=value properties file | +| `sysTest.clientPrefix` | JmsConsumer or JmsProducer | Client name prefix | +| `sysTest.numClients` | 1 | Number of JMS Clients to start | +| `sysTest.totalDests` | 1 | Total number of destinations | +| `sysTest.destDistro` | all | How to distribute destinations: `all`, `equal`, or `divide` | +| `sysTest.reportDir` | ./ | Directory where the sampler report will be saved | +| `sysTest.reportType` | xml | Report format: `xml` or `verbose` | +| `sysTest.samplers` | tp,cpu | Samplers to start: `tp` (throughput) and/or `cpu` | + +### Configuration for Running a JMS Producer + +| Configuration Key | Default Value | Description | +|---|---|---| +| `producer.sessTransacted` | false | Whether the session is transacted | +| `producer.sessAckMode` | autoAck | Acknowledge mode: `autoAck`, `clientAck`, `dupsAck`, `transacted` | +| `producer.destName` | TEST.FOO | Destination name prefix (prefix with `queue://` or `topic://`) | +| `producer.deliveryMode` | nonpersistent | `nonpersistent` or `persistent` | +| `producer.messageSize` | 1024 bytes | Size of each text message | +| `producer.sendType` | time | `time` or `count` based sending | +| `producer.sendCount` | 1000000 | Messages to send if `sendType=count` | +| `producer.sendDuration` | 300000 ms | Duration to send if `sendType=time` | + +### Configuration for Running a JMS Consumer + +| Configuration Key | Default Value | Description | +|---|---|---| +| `consumer.sessTransacted` | false | Whether the session is transacted | +| `consumer.sessAckMode` | autoAck | Acknowledge mode | +| `consumer.destName` | TEST.FOO | Destination name prefix | +| `consumer.durable` | false | If true, create a durable subscriber | +| `consumer.asyncRecv` | true | If true, receive messages asynchronously via `onMessage()` | +| `consumer.recvType` | time | `time` or `count` based receiving | +| `consumer.recvCount` | 1000000 | Messages to receive if `recvType=count` | +| `consumer.recvDuration` | 300000 ms | Duration to receive if `recvType=time` | + +### Sampler Configuration + +| Configuration Key | Default Value | Description | +|---|---|---| +| `.duration` | 300000 | Total duration (ms) the sampler will run | +| `.rampUpTime` | 30000 | Ramp up time (ms) before sampling starts | +| `.rampDownTime` | 30000 | Ramp down time (ms) | +| `.interval` | 1000 | Sampling interval (ms) | + +Sampler names: `tpSampler` (throughput) and `cpuSampler` (CPU usage). diff --git a/hugo/content/components/classic/documentation/advisory-message.md b/hugo/content/components/classic/documentation/advisory-message.md new file mode 100644 index 0000000000..a47c395598 --- /dev/null +++ b/hugo/content/components/classic/documentation/advisory-message.md @@ -0,0 +1,197 @@ +--- +title: Advisory Message +layout: classic-doc +--- + + + +ActiveMQ Classic supports advisory messages which allows you to watch the system using regular JMS messages. Currently we have advisory messages that support: + +* consumers, producers and connections starting and stopping +* temporary destinations being created and destroyed +* messages expiring on topics and queues +* brokers sending messages to destinations with no consumers. +* connections starting and stopping + +Advisory messages can be thought as some kind of administrative channel where you receive information regarding what is happening on your JMS provider along with what's happening with producers, consumers and destinations. When you look at a broker via [JMX](jmx) you will see the advisory topics prefixed with `ActiveMQ.Advisory.`. + +Every Advisory has the message **type** `Advisory` and some predefined message properties: + +Property|Type|Description|Version +---|---|---|--- +`originBrokerId`|`StringProperty`|The id of the broker where the advisory originated.|5.x +`originBrokerName`|`StringProperty`|The name of the broker where the advisory originated.|5.x +`originBrokerURL`|`StringProperty`|The first URL of the broker where the advisory originated.|5.2 + +In addition, some messages carry a `Command` object, which carries additional information about the nature of the advisory, e.g., a subscription to each of the destination returns an `ActiveMQMessage`. Specific `DataStructure` objects, e.g.,. `ConsumerInfo`, `ProducerInfo`, `ConnectionInfo` can be retrieved using `ActiveMQMessage.getDataStructure()`. + +For example: +``` +Destination advisoryDestination = AdvisorySupport.getProducerAdvisoryTopic(destination) +MessageConsumer consumer = session.createConsumer(advisoryDestination); +consumer.setMessageListener(this); + +public void onMessage(Message msg){ + if(msg instanceof ActiveMQMessage) { + try { + ActiveMQMessage aMsg = (ActiveMQMessage)msg; + ProducerInfo prod = (ProducerInfo) aMsg.getDataStructure(); + } + catch(JMSException e) { + log.error("Failed to process message: " + msg); + } + } +} +``` + +The following advisory topics are supported +------------------------------------------- + +### Client based advisories + +> **Tip** +> +> These are always generated. + +Advisory Topics|Description|Properties|Data Structure +---|---|---|--- +`ActiveMQ.Advisory.Connection`|Connection start & stop messages.| |`ConnectionInfo`, `RemoveInfo` +`ActiveMQ.Advisory.Producer.Queue`|Producer start & stop messages on a Queue.|`String='producerCount'` - the number of producers|`ProducerInfo` +`ActiveMQ.Advisory.Producer.Topic`|Producer start & stop messages on a Topic.|`String='producerCount'` - the number of producers|`ProducerInfo` +`ActiveMQ.Advisory.Consumer.Queue`|Consumer start & stop messages on a Queue.|`String='consumerCount'` - the number of Consumers|`ConnectionInfo`, `RemoveInfo` +`ActiveMQ.Advisory.Consumer.Topic`|Consumer start & stop messages on a Topic.|`String='consumerCount'` - the number of Consumers|`ConnectionInfo`, `RemoveInfo` + +Note that the consumer start/stop advisory messages also have a `consumerCount` header to indicate the number of active consumers on the destination when the advisory message was sent. This means you can use the following selector to be notified when there are no active consumers on a given destination: +``` +consumerCount = 0 +``` + +### Destination and Message based advisories + +Advisory Topics|Description|Properties|Data Structure|Default|PolicyEntry Property +---|---|---|---|---|--- +`ActiveMQ.Advisory.Queue`|Queue create & destroy.|`null`|`DestinationInfo`|`true`|`none` +`ActiveMQ.Advisory.Topic`|Topic create & destroy.|`null`|`DestinationInfo`|`true`|`none` +`ActiveMQ.Advisory.TempQueue`|Temporary Queue create & destroy.|`null`|`DestinationInfo`|`true`|`none` +`ActiveMQ.Advisory.TempTopic`|Temporary Topic create & destroy.|`null`|`DestinationInfo`|`true`|`none` +`ActiveMQ.Advisory.Expired.Queue`|Expired messages on a Queue.|`String='orignalMessageId'` - the expired id|`Message`|`true`|`none` +`ActiveMQ.Advisory.Expired.Topic`|Expired messages on a Topic.|`String='orignalMessageId'` - the expired id|`Message`|`true`|`none` +`ActiveMQ.Advisory.NoConsumer.Queue`|No consumer is available to process messages being sent on a Queue.|`null`|`Message`|`false`|`sendAdvisoryIfNoConsumers` +`ActiveMQ.Advisory.NoConsumer.Topic`|No consumer is available to process messages being sent on a Topic.|`null`|`Message`|`false`|`sendAdvisoryIfNoConsumers` + +> **Tip** +> +> `NoConsumer` topic advisories are sent only for non-persistent messages. + +### New advisories in version 5.2 + +Advisory Topics|Description|Properties|Data Structure|Default|PolicyEntry Property +---|---|---|---|---|--- +`ActiveMQ.Advisory.SlowConsumer.Queue`|Slow Queue Consumer.|`String='consumerId'` - the consumer id|`ConsumerInfo`|`false`|`advisoryForSlowConsumers` +`ActiveMQ.Advisory.SlowConsumer.Topic`|Slow Topic Consumer.|`String='consumerId'` - the consumer id|`ConsumerInfo`|`false`|`advisoryForSlowConsumers` +`ActiveMQ.Advisory.FastProducer.Queue`|Fast Queue producer.|`String='producerId'` - the producer id|`ProducerInfo`|`false`|`advisoryForFastProducers` +`ActiveMQ.Advisory.FastProducer.Topic`|Fast Topic producer.|`String='consumerId'`' - the producer id|`ProducerInfo`|`false`|`advisoryForFastProducers` +`ActiveMQ.Advisory.MessageDiscarded.Queue`|Message discarded.|`String='orignalMessageId'` - the discarded id|`Message`|`false`|`advisoryForDiscardingMessages` +`ActiveMQ.Advisory.MessageDiscarded.Topic`|Message discarded.|`String='orignalMessageId'` - the discarded id|`Message`|`false`|`advisoryForDiscardingMessages` +`ActiveMQ.Advisory.MessageDelivered.Queue`|Message delivered to the broker.|`String='orignalMessageId'` - the delivered id|`Message`|`false`|`advisoryForDelivery` +`ActiveMQ.Advisory.MessageDelivered.Topic`|Message delivered to the broker.|`String='orignalMessageId'` - the delivered id|`Message`|`false`|`advisoryForDelivery` +`ActiveMQ.Advisory.MessageConsumed.Queue`|Message consumed by a client.|`String='orignalMessageId'` - the delivered id|`Message`|`false`|`advisoryForConsumed` +`ActiveMQ.Advisory.MessageConsumed.Topic`|Message consumed by a client.|`String='orignalMessageId'` - the delivered id|`Message`|`false`|`advisoryForConsumed` +`ActiveMQ.Advisory.FULL`|A Usage resource is at its limit.|`String='usageName'` - the name of Usage resource|`null`|`false`|`advisoryWhenFull` +`ActiveMQ.Advisory.MasterBroker`|A broker is now the master in a master/slave configuration.|`null`|`null`|`true`|`none` + +### New Advisories in 5.4 + +Advisory Topics|Description|Properties|Data Structure|Default|PolicyEntry Property +---|---|---|---|---|--- +`ActiveMQ.Advisory.MessageDLQd.Queue`|Message sent to DLQ.|`String='orignalMessageId'` - the delivered id|`Message`|Always on|`advisoryForConsumed` +`ActiveMQ.Advisory.MessageDLQd.Topic`|Message sent to DLQ.|`String='orignalMessageId'` - the delivered id|`Message`|Always on|`advisoryForConsumed` + +### Network bridge advisories + +Starting with ActiveMQ Classic version 5.5 you can watch advisory topics for events related to the status of network bridges. You can get advisory messages when the network bridge is started or stopped. + +Advisory Topics|Description|Properties|Data Structure|Default +---|---|---|--- +`ActiveMQ.Advisory.NetworkBridge`|Network bridge being stopped or started.|`Boolean="started"` - `true` if bridge is started, `false` if it is stopped. `Boolean="createdByDuplex"` - `true` if the bridge is created by remote network connector.|`BrokerInfo` - provides data of the remote broker|Always on + +### Enabling Advisories Disabled by Default + +The advisories that are not turned on by default (see the last column) can be enabled on a `PolicyEntry` in the ActiveMQ Classic Broker Configuration, e.g., to enable a message consumed advisory you can configure the following: +``` + + + + + + + +``` + +> Hint +> +> The `>` character matches all topics - you can use wild-card matches for setting a destination policy - see [Wildcards](wildcards) + +### Disabling Advisory Messages + +The use of advisory messages incurs a small overhead in terms of memory and connection resources that is related to the number of destinations in your system. In some cases it can make sense to disable all advisories. + +Advisories need to be disabled both on the Broker, via XML Configuration +``` + +``` +or from java code: +``` +BrokerService broker = new BrokerService(); +broker.setAdvisorySupport(false); +// ... +broker.start(); +``` +_and_ on your `ActiveMQConnectionFactory` (because a subscription to an advisory topic will auto create it) via the `brokerUrl`: +``` +tcp://localhost:61616?jms.watchTopicAdvisories=false +``` +or via java code using the `watchTopicAdvisories` attribute on the `ActiveMQConnectionFactory`. +``` +ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(); +factory.setWatchTopicAdvisories(false); +``` + +> **Warning** +> +> Advisory messages are required for [dynamic network broker topologies](networks-of-brokers) as `NetworkConnectors` subscribe to advisory messages. In the absence of advisories, a network must be statically configured. + +### Using the Destinations + +All of the above destinations are really prefixes which are appended with important information (like the actual topic or queue, the client ID, producer ID, consumer ID etc). This allows you to reuse the power of publish/subscribe, [Wildcards](wildcards) and [Selectors](selectors) to filter the advisory messages as you see fit. + +For example if you want to subscribe to expired messages on a topic `FOO.BAR` you could subscribe to `ActiveMQ.Advisory.Expired.Topic.FOO.BAR`. To subscribe to all messages of a certain kind of advisory just append `.>` to the topic, e.g., to subscribe to all the consumers starting and stopping to topics and queues subscribe to `ActiveMQ.Advisory.Consumer..>`. + +### Helper Methods + +Methods to get the advisory destination objects are available in [AdvisorySupport](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/advisory/AdvisorySupport.html) through the following methods. + +* AdvisorySupport.getConsumerAdvisoryTopic() +* AdvisorySupport.getProducerAdvisoryTopic() +* AdvisorySupport.getExpiredTopicMessageAdvisoryTopic() +* AdvisorySupport.getExpiredQueueMessageAdvisoryTopic() +* AdvisorySupport.getNoTopicConsumersAdvisoryTopic() +* AdvisorySupport.getNoQueueConsumersAdvisoryTopic() +* AdvisorySupport.getDestinationAdvisoryTopic() +* AdvisorySupport.getExpiredQueueMessageAdvisoryTopic() +* AdvisorySupport.getExpiredTopicMessageAdvisoryTopic() +* AdvisorySupport.getNoQueueConsumersAdvisoryTopic() +* AdvisorySupport.getNoTopicConsumersAdvisoryTopic() + +// Version 5.2 on: + +* AdvisorySupport.getSlowConsumerAdvisoryTopic() +* AdvisorySupport.getFastProducerAdvisoryTopic() +* AdvisorySupport.getMessageDiscardedAdvisoryTopic() +* AdvisorySupport.getMessageDeliveredAdvisoryTopic() +* AdvisorySupport.getMessageConsumedAdvisoryTopic() +* AdvisorySupport.getMasterBrokerAdvisoryTopic() +* AdvisorySupport.getFullAdvisoryTopic() + +Some helper classes to deal with advisory messages are available in the [advisories](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/advisory/package-summary.html) package. + diff --git a/hugo/content/components/classic/documentation/ajax.md b/hugo/content/components/classic/documentation/ajax.md new file mode 100644 index 0000000000..012cf6feaf --- /dev/null +++ b/hugo/content/components/classic/documentation/ajax.md @@ -0,0 +1,165 @@ +--- +title: Ajax +layout: classic-doc +--- + + + +Introduction +============ + +ActiveMQ Classic supports [Ajax](http://en.wikipedia.org/wiki/Ajax_%28programming%29) which is an Asychronous Javascript And Xml mechanism for real time web applications. This means you can create highly real time web applications taking full advantage of the publish/subscribe nature of ActiveMQ Classic + +Ajax allows a regular DHTML client (with JavaScript and a modern version 5 or later web browser) to send and receive messages over the web. Ajax support in ActiveMQ Classic builds on the same basis as the [REST](rest) connector for ActiveMQ Classic which allows any web capable device to send or receive messages over JMS. + +To see Ajax in action, try [running the examples](web-samples) + +The Servlet +=========== + +The AMQ AjaxServlet needs to be installed in your webapplications to support JMS over Ajax: + +``` + + AjaxServlet + org.apache.activemq.web.AjaxServlet + +... + + AjaxServlet + /amq/* + +``` +The servlet both serves the required js files and handles the JMS requests and responses. + +Javascript API +============== + +The ajax featues of amq are provided on the client side by the [amq.js](https://github.com/apache/activemq/blob/main/activemq-web-demo/src/main/webapp/js/amq.js) script. Beginning with ActiveMQ Classic 5.4, this script utilizes one of three different adapters to support ajax communication with the server. Current [jQuery](http://jquery.org), [Prototype](http://prototypejs.org), and [Dojo](http://www.dojotoolkit.org) are supported, and recent versions of all three libraries are shipped with ActiveMQ Classic. +``` + + + + +``` +Including these scripts results in the creation of a javascript object called `amq`, which provides the API to send messages and to subscribe to channels and topics. + +Sending a message +----------------- + +All that is required to send a JMS message from the javascript client, is to call the method: +``` +amq.sendMessage(myDestination,myMessage); +``` +where `myDestination` is the URL string address of the destination (e.g. `topic://MY.NAME` or `channel://MY.NAME`) and `myMessage` is any well formed XML or plain text encoded as XML content. + +Receiving messages +------------------ + +To receive messages, the client must define a message handling function and register it with the [amq](https://github.com/apache/activemq/tree/main/activemq-web-demo/src/main/webapp/js/amq.js) object. For example: +``` +var myHandler = +{ + rcvMessage: function(message) + { + alert("received "+message); + } +}; + +amq.addListener(myId,myDestination,myHandler.rcvMessage); +``` +where `myId` is a string identifier that can be used for a later call to `amq.removeHandler(myId)` and `myDestination` is a URL string address of the destination (e.g. `topic://MY.NAME` or `channel://MY.NAME`). When a message is received, a call back to the `myHandler.rcvMessage` function passes the message to your handling code. +The "message" is actually a text of the Text message or a String representation (`toString()`) in case of Object messages. + +Be aware that, by default, messages published via [Stomp](stomp) which include a `content-length` header will be converted by ActiveMQ Classic to binary messages, and will not be visible to your web clients. Beginning with ActiveMQ Classic 5.4.0, you can resolve this problem by always setting the [`amq-msg-type` header](https://issues.apache.org/jira/browse/AMQ-2833) to `text` in messages which will may be consumed by web clients. + +### Selector support + +By default, an ajax client will receive all messages on a topic or queue it is subscribed to. In [ActiveMQ Classic 5.4.1](http://activemq.apache.orgOverview/Download/activemq-541-release) amq.js supports [JMS selectors](http://activemq.apache.orgFeatures/Consumer Features/selectors) since it is frequently useful to receive only a subset of these messages. Selectors are supplied to an `amq.addListener` call by way of an optional 4th parameter. +``` +amq.addListener( myId, myDestination, myHandler.rcvMessage, { selector:"identifier='TEST'" } ); +``` +When used in this way, the Javascript client will receive only messages containing an `identifier` header set to the value `TEST`. + +Using AMQ Ajax in Multiple Browser Windows +------------------------------------------ + +All windows or tabs in a single browser share the same `JSESSIONID` on the ActiveMQ Classic server. Unless the server can distinguish listeners from multiple windows, messages which were intended for 1 window will be delivered to another one instead. Effectively, this means that amq.js could be active in only a single browser window at any given time. Beginning in [ActiveMQ Classic 5.4.2](http://activemq.apache.orgOverview/DownloadOverview/Download/Overview/Download/activemq-542-release), this is resolved by allowing each call to `amq.init` to specify a unique `clientId`. When this is done, multiple windows in the same browser can happily co-exist. Each can have a separate set of message subscriptions on the broker with no interactions between them. + +In this example, we use the current time (at the time the web page is loaded) as a unique identifier. This is effective as long as two browser windows are not opened within the same millisecond, and is the approach used by the example [chat.md](https://github.com/apache/activemq/tree/main/activemq-web-demo/src/main/webappchat) included with ActiveMQ Classic. Other schemes to ensure the uniqueness of `clientId` can easily be devised. Note that this `clientId` need only be unique within a single session. (Browser windows opened in the same millisecond in separate browsers will not interact, since they are in different sessions.) +``` +org.activemq.Amq.init({ + uri: 'amq', + logging: true, + timeout: 45, + clientId:(new Date()).getTime().toString() +}); +``` +Note that this `clientId` is common to all message subscriptions in a single tab or window, and is entirely different from the `clientId` which is supplied as a first argument in `amq.addListener` calls. + +* In `amq.init`, `clientId` serves to distinguish different web clients sharing the same `JSESSIONID`. All windows in a single browser need a unique `clientId` when they call `amq.init`. +* In `amq.addListener`, `clientId` is used to associate a message subscription with the callback function which should be invoked when a message is received for that subscription. These `clientId` values are internal to each web page, and do not need to be unique across multiple windows or tabs. + +How it works +============ + +AjaxServlet and MessageListenerServlet +-------------------------------------- + +The ajax featues of amq are handled on the server side by the [AjaxServlet](https://github.com/apache/activemq/tree/main/activemq-web/src/main/java/org/apache/activemq/web/AjaxServlet.java) which extends the [MessageListenerServlet](https://github.com/apache/activemq/tree/main/activemq-web/src/main/java/org/apache/activemq/web/MessageListenerServlet.java). This servlet is responsible for tracking the existing clients (using a HttpSesssion) and lazily creating the AMQ and javax.jms objects required by the client to send and receive messages (eg. Destination, MessageConsumer, MessageAVailableListener). This servlet should be mapped to `/amq/*` in the web application context serving the Ajax client (this can be changed, but the client javascript `amq.uri` field needs to be updated to match.) + +Client Sending messages +----------------------- + +When a message is sent from the client it is encoded as the content of a POST request, using the API of one of the supported connection adapters (jQuery, Prototype, or Dojo) for [XmlHttpRequest](http://jibbering.com/2002/4/httprequest.html). The [amq](https://github.com/apache/activemq/tree/main/activemq-web-demo/src/main/webapp/js/amq.js) object may combine several sendMessage calls into a single POST if it can do so without adding additional delays (see polling below). + +When the MessageListenerServlet receives a POST, the messages are decoded as `application/x-www-form-urlencoded` parameters with their type (in this case `send` as opposed to `listen` or `unlisten` see below) and destination. If a destination channel or topic do not exist, it is created. The message is sent to the destination as a TextMessage. + +Listening for messages +---------------------- + +When a client registers a listener, a message subscription request is sent from the client to the server in a POST in the same way as a message, but with a type of `listen`. When the MessageListenerServlet receives a `listen` message, it lazily creates a MessageAvailableConsumer and registers a Listener on it. + +Waiting Poll for messages +------------------------- + +When a Listener created by the MessageListenerServlet is called to indicate that a message is available, due to the limitations of the HTTP client-server model, it is not possible to send that message directly to the ajax client. Instead the client must perform a special type of **Poll** for messages. Polling normally means periodically making a request to see if there are messages available and there is a trade off: either the poll frequency is high and excessive load is generated when the system is idle; or the frequency is low and the latency for detecting new messages is high. + +To avoid the load vs latency tradeoff, AMQ uses a waiting poll mechanism. As soon as the amq.js script is loaded, the client begins polling the server for available messages. A poll request can be sent as a GET request or as a POST if there are other messages ready to be delivered from the client to the server. When the MessageListenerServlet receives a poll it: + +1. if the poll request is a POST, all `send`, `listen` and `unlisten` messages are processed +2. if there are no messages available for the client on any of the subscribed channels or topic, the servlet suspends the request handling until: + * A MessageAvailableConsumer Listener is called to indicate that a message is now available; or + * A timeout expires (normally around 30 seconds, which is less than all common TCP/IP, proxy and browser timeouts). +3. A HTTP response is returned to the client containing all available messages encapsulated as `text/xml`. + +When the amq.js javascipt receives the response to the poll, it processes all the messages by passing them to the registered handler functions. Once it has processed all the messages, it immediately sends another poll to the server. + +Thus the idle state of the amq ajax feature is a poll request "parked" in the server, waiting for messages to be sent to the client. Periodically this "parked" request is refreshed by a timeout that prevents any TCP/IP, proxy or browser timeout closing the connection. The server is thus able to asynchronously send a message to the client by waking up the "parked" request and allowing the response to be sent. + +The client is able to asynchronously send a message to the server by creating (or using an existing) second connection to the server. However, during the processing of the poll response, normal client message sending is suspended, so that all messages to be sent are queued and sent as a single POST with the poll that will be sent (with no delay) at the end of the processing. This ensures that only two connections are required between client and server (the normal for most browsers). + +Threadless Waiting +------------------ + +The waiting poll described above is implemented using the [Jetty 6 Continuations](http://docs.codehaus.org/display/JETTY/Continuations) mechanism. This allows the thread associated with the request to be released during the wait, so that the container does not need to have a thread per client (which may be a large number). If another servlet container is used, the Continuation mechanism falls back to use a wait and the thread is not released. + +Comparison to Pushlets +====================== + +Firstly we could easily add support for pushlets to ActiveMQ Classic. However we prefer the Ajax approach for various reasons + +* using Ajax means that we use a distinct HTTP request for each send/receive which is much more friendly to web infrastructure (firewalls, proxies, caches and so forth) rather than having an infinitely-long GET. +* we can still take advantage of HTTP 1.1 keep-alive sockets and pipeline processing to gain the efficiency of a single socket used for communication between the client and server side; though in a way that works with any HTTP-capable infrastructure +* the server is pure REST and so will work with any client side (rather than being tied to custom JavaScript function calls used on the page which the Pushlet approach requires). So Pushlets tie the server to the web page; with Ajax we can have a generic service which works with any page. +* the client can be in control over frequency of polling & timeouts. e.g. it can avoid the memory issues of Pushlets in some browsers by using a 20-second timeout HTTP GET. Or using a zero timeout GET to poll queues. +* its easier to take full advantage of HTTP encoding of messages, rather than using JavaScript function calls as the transfer protocol. +* pushlets assume the server knows what functions are used on the client side as the server basically writes JavaScript function calls down the scoket - it's better for us to send generic XML packets (or strings or whatever the message format is) and let the JavaScript client side be totally decoupled from the server side +* Ajax supports clean XML support allowing full XML documents to be streamed to the client for rich messages which are easy to process via standard JavaScript DOM support diff --git a/hugo/content/components/classic/documentation/amq-message-store.md b/hugo/content/components/classic/documentation/amq-message-store.md new file mode 100644 index 0000000000..550cdb4b37 --- /dev/null +++ b/hugo/content/components/classic/documentation/amq-message-store.md @@ -0,0 +1,97 @@ +--- +title: AMQ Message Store +layout: classic-doc +--- + +[Features](features) > [Persistence](persistence) > [AMQ Message Store](amq-message-store) + + +The Basics +---------- + +This is the default storage for AcitveMQ 5 and above. The AMQ Message Store is an embeddable transactional message storage solution that is extremely fast and reliable. +message commands are written to a transactional journal - which consists of rolling data logs - which means writing is extremely fast and the state of the store is easily recoverable. + +Messages themselves are persisted in the data logs of the journal - with references to their location being held by a reference store (by default Kaha) for fast retrevial. + +![](assets/img/amqstore.png) + +References to messages are held in memory, and periodically inserted into the reference store to improve performance. + +The messages are stored in data logs, which are individual files, typically 32mb in size (though this is configurable, they can be larger if the size of a message is large than the file size). When all the messages in a data log have been successfully consumed, the data log file is marked as being ready to be deleted - or archived - which will happen at the next clean up period. + +Configuration +------------- + +By default ActiveMQ Classic will use the the AMQ Store - and its default settings. You can configure the properties of the AMQ Store however, by explictly defining its persistence adapter (amqPersistenceAdapter): +``` + + + + + + + + +``` +The above shows the configuration required to set the AMQ Store through its amqPersistenceAdapter - and explicity setting the directory and maxFileLength properties. + +### AMQ Store Properties + +property name|default value|Comments +---|---|--- +`directory`|activemq-data|the path to the directory to use to store the message store data and log files +`useNIO`|true|use NIO to write messages to the data logs +`syncOnWrite`|false|sync every write to disk +`maxFileLength`|32mb|a hint to set the maximum size of the message data logs +`persistentIndex`|true|use a persistent index for the message logs. If this is false, an in-memory structure is maintained +`maxCheckpointMessageAddSize`|4kb|the maximum number of messages to keep in a transaction before automatically committing +`cleanupInterval`|30000|time (ms) before checking for a discarding/moving message data logs that are no longer used +`indexBinSize`|1024|default number of bins used by the index. The bigger the bin size - the better the relative performance of the index +`indexKeySize`|96|the size of the index key - the key is the message id +`indexPageSize`|16kb|the size of the index page - the bigger the page - the better the write performance of the index +`directoryArchive`|archive|the path to the directory to use to store discarded data logs +`archiveDataLogs`|false|if true data logs are moved to the archive directory instead of being deleted + +Data Structure +-------------- + +In the data directory defined for the AMQ Store there is the following directory structure: + +![](assets/img/amqdir.png) + +### Top level + +the message broker's name is used to distinguish its directory of message data. By default, the broker name is local host. +Below this top level directory are the following sub directories: + +### archive + +message data logs are moved here when they are discarded. +n.b. this directory only exists when the property archiveDataLogs is enabled + +### journal + +Used to hold the message data logs + +### kr-store + +The directory structure of the Kaha reference store (if used) + +##### data + +The indexes used to reference the message data logs in the journal for fast retrieval + +##### state + +The state of the store - i.e. names of durable subscribers - the reason for this is described in [Recovery](#recovery) + +### tmp-storage + +use to hold data files for transient messages that may be stored on disk to alleviate memory consumption - e.g. non-persistent topic messages awaiting delivery to an active, but slow subscriber. + +Recovery +-------- + +If the message broker does not shutdown properly, then the reference store indexes are cleaned and the message data files (which contain messages/acknowledgements and transactional boundaries) are replayed to rebuild up the message store state. It is possbile to force automatic recovery if using the Kaha reference store (the default) by deleting the kr-store/state/ directory. + diff --git a/hugo/content/components/classic/documentation/amqp.md b/hugo/content/components/classic/documentation/amqp.md new file mode 100644 index 0000000000..78a96aa563 --- /dev/null +++ b/hugo/content/components/classic/documentation/amqp.md @@ -0,0 +1,160 @@ +--- +title: AMQP +layout: classic-doc +--- + +ActiveMQ Classic supports the [AMQP 1.0](https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=amqp) protocol which is an OASIS standard. + +> **Availability** +> +> Available from ActiveMQ Classic version [5.8](activemq-580-release) onward. + +### Enabling the ActiveMQ Classic Broker for AMQP + +To enable AMQP protocol support on the broker add the following transport connector configuration referencing the `amqp` scheme in its URI: +``` + + + +``` +It is enabled in the default ActiveMQ Classic server configuration. For more help see [Run Broker](run-broker). + +### Security + +The AMQP implementation fully supports an [ActiveMQ Classic security](security) mechanism. This allows the broker to accept plain SASL authentication. Authorization policies are applied to a destination when it's accessed (read/write). + +> **SSL** +> +> For additional security AMQP can be configured to run over SSL as described in the following section. + +### Enabling AMQP over NIO + +For better scalability (and performance) the AMQP protocol should be configured to use NIO, rather than the default of TCP. To use NIO use the transport scheme `amqp+nio` instead of `amqp`. + +Example: +``` + +``` +This transport uses the [NIO transport](configuring-transports#TheNIOTransport) underneath and will generally use much less threads than the standard connector. This connector can help if you want to use [large number of queues](how-do-i-configure-10s-of-1000s-of-queues-in-a-single-broker) + +### Enabling AMQP over SSL + +It's easy to configure ActiveMQ Classic to use AMQP over a SSL connection. To use SSL use the transport scheme `amqp+ssl` instead of `amqp`. + +Example: +``` + +``` +For more details on using SSL with ActiveMQ Classic, see the following article ([How do I use SSL](how-do-i-use-ssl)). + +### Working with Destinations with AMQP + +You should prefix destination address with `queue://` to use queue based destinations or `topic://` to use topic based destinations. The destination type defaults to queue when the destination prefix is omitted. + +### Prefetch Size and Credit + +When AMQP receiver connects to the broker it's mapped to the JMS consumer. This JMS consumer has to have appropriate [prefetch size](what-is-the-prefetch-limit-for) set. The broker will honor the credit set by the client or use the default value of `1000` if client doesn't set it. + +Example: tuning the default `prefetch` size: +``` + +``` +In this case, client preference will be ignored and the configured value will be used. + +You can also tune broker-side `amqp` receiver link that handles incoming messages. It will use credit of `1000` messages by default, but you can override this by using `producerCredit` property, like  +``` + +``` + +### Mapping to JMS + +There are three basic conversion strategies that can be used with AMQP and inter-operating with the JMS API. + +Strategy|Description +---|--- +`native`|(**Default**) Wraps the bytes of the AMQP message into a JMS `BytesMessage` and maps the headers of the AMQP message to headers on the JMS message. +`raw`|Wraps the bytes of the AMQP message into a JMS `BytesMessage`. +`jms`|Maps headers of the AMQP message to JMS message headers and the body of the AMQP message to the JMS body. + +Set the **transformer** transport option on the `transportConnector` to the desired mapping strategy. For example, to inter-operate with JMS at the payload level, set the `transformer` option to `jms`: +``` + +``` + +#### How AMQP Message Headers are Mapped to JMS Headers + +The following headers are mapped regardless of the transformer used: + +AMQP Message|JMS Message|Notes +---|---|--- +|`JMS_AMQP_NATIVE`|Will be set to `true` if the transformer is `native` or `raw`, `false` otherwise. +`message-format`|`JMS_AMQP_MESSAGE_FORMAT`| + +The following header mappings apply when the transformer is either `native` or `jms`: + +AMQP Message|JMS Message|Notes +---|---|--- +`application-properties.JMSXGroupID`|`JMSXGroupID`| +`application-properties.JMSXGroupSequence`|`JMSXGroupSequence`| +`application-properties.JMSXUserID`|`JMSXUserID`| +`application-properties.**name`|`name` +`delivery-annotations.**name`|`JMS_AMQP_DA_**name`| +`footer.**name`|`JMS_AMQP_FT_**name`| +`header.deliveryCount`|`JMSXDeliveryCount`| +`header.durable`|`JMSDeliveryMode`|`javax.jms.Message.DEFAULT_DELIVERY_MODE` if not set. +`header.first-acquirer`|`JMS_AMQP_FirstAcquirer`| +`header.priority`|`JMSPriority`|`javax.jms.Message.DEFAULT_PRIORITY` if not set. +`header.ttl`|`JMSExpiration`|`javax.jms.Message.DEFAULT_TIME_TO_LIVE` if not set. +`message-annotations.**name`|`JMS_AMQP_MA_**name`| +`message-annotations.x-opt-jms-type`|`JMSType`| +`message-annotations.x-opt-reply-type`|Type of the `JMSReplyTo`|Comma separated list of `queue`, `topic`, or `temporary`. Defaults to `queue` if not set. +`message-annotations.x-opt-to-type`|Type of the `JMSDestination`|Comma separated list of `queue`, `topic`, or `temporary`. Defaults to `queue` if not set. +`properties.content-encoding`|`JMS_AMQP_ContentEncoding`| +`properties.content-type`|`JMS_AMQP_ContentType`| +`properties.correlation-id`|`JMSCorrelationID`| +`properties.creation-time`|`JMSTimestamp`| +`properties.group-sequence`|`JMSXGroupSequence`| +`properties.message-id`|`JMSMessageID`|Auto generated if not set. +`properties.reply-to`|`JMSReplyTo`|The name of the `JMSReplyTo` +`properties.reply-to-group-id`|`JMS_AMQP_ReplyToGroupID`| +`properties.subject`|`JMS_AMQP_Subject`| +`properties.to`|`JMSDestination`|The name of the `JMSDestination` +`properties.user-id`|`JMSXUserID`|`properties.user-id` is decoded as a UTF-8 String. + +AMQP property value types are converted as follows: + +AMQP Type|Java Type|Notes +---|---|--- +`binary`|`String`|Hex encoding of the binary value +`bool`|`Boolean`| +`byte`|`Byte`| +`double`|`Double`| +`float`|`Float`| +`int`|`Integer`| +`long`|`Long`| +`short`|`Short`| +`symbol`|`String`| +`ubyte`|`Byte` or `Short`|`Short` is used if: `value >` `Byte.MAX_VALUE` +`uint`|`Integer` or `Long`|`Long` is used if: `value >` `Integer.MAX_VALUE` +`ulong`|`Long`| +`ushort`|`Short` or `Integer`|`Integer` is used if: `value >` `Short.MAX_VALUE` + +#### How a AMQP Messages Body is Mapped to a JMS Message + +If the transformer is set to `jms` then the JMS message type will depend on the body type of the AMQP message. + +Body Type|JMS Message Type +---|--- +`AmqpSequence`|`StreamMessage` +`AmqpValue`|`ObjectMessage` +`AmqpValue` holding a `null`|`Message` +`AmqpValue` holding a `String`|`TextMessage` +`AmqpValue` holding a `binary`|`BytesMessage` +`AmqpValue` holding a `list`|`StreamMessage` +`Data`|`BytesMessage` +`null`|`Message` + +### AMQP 1.0 client library + +You can use [Apache Qpid Proton](http://qpid.apache.org/proton/). + diff --git a/hugo/content/components/classic/documentation/are-destinations-case-sensitive.md b/hugo/content/components/classic/documentation/are-destinations-case-sensitive.md new file mode 100644 index 0000000000..51ba86b008 --- /dev/null +++ b/hugo/content/components/classic/documentation/are-destinations-case-sensitive.md @@ -0,0 +1,9 @@ +--- +title: Are destinations case sensitive +layout: classic-doc +--- + + + +There seems to be no consensus on whether JMS providers should use case insensitive destination names. Since most names in Java & J2EE are case sensitive (class names, JNDi names, file names (on many unix operating systems), URIs and URLs - we've followed suit and use case sensitive destination names. + diff --git a/hugo/content/components/classic/documentation/are-messages-read-directly-from-the-journal.md b/hugo/content/components/classic/documentation/are-messages-read-directly-from-the-journal.md new file mode 100644 index 0000000000..1cea591d53 --- /dev/null +++ b/hugo/content/components/classic/documentation/are-messages-read-directly-from-the-journal.md @@ -0,0 +1,11 @@ +--- +title: Are messages read directly from the journal +layout: classic-doc +--- + + + +Kind of. A message can be loaded directly from the journal if it was swapped out of memory. + +The journal cannot be used, however, to recover a durable subscription as it does not keep an ordered index of messages per durable sub. So when a durable sub is activated, the journal checkpoints to flush any messages in the journal to the long term store and then the long term store is used to recover the durable subscription. + diff --git a/hugo/content/components/classic/documentation/articles.md b/hugo/content/components/classic/documentation/articles.md new file mode 100644 index 0000000000..9366b1efc0 --- /dev/null +++ b/hugo/content/components/classic/documentation/articles.md @@ -0,0 +1,36 @@ +--- +title: Articles +layout: classic-doc +--- + +This page captures resources and articles about ActiveMQ Classic. + +### Interviews and Podcasts + +- [ActiveMQ FeatherCast 2021-09-07](https://feathercast.apache.org/2021/09/07/apache-activemq/) — Interview on "Flexible & Powerful Open Source Multi-Protocol Messaging" +- [ActiveMQ FeatherCast 2007-04-02](https://feathercast.apache.org/2007/04/02/episode-27-apache-activemq/) — James Strachan on the ActiveMQ project + +### General Articles + +- [Connecting to ActiveMQ with Payara Server](http://blog.payara.fish/connecting-to-activemq-with-payara-server) (December 2015) +- [ActiveMQ in Action: Common Problems and Solutions](http://de.slideshare.net/bruce.snyder/activemq-in-action) by Bruce Snyder (July 2011) +- [Understanding Memory Usage](https://blog.christianposta.com/activemq/activemq-understanding-memory-usage/) by Christian Posta + +### Spring + +- [Spring JMS Examples with ActiveMQ](https://github.com/bsnyder/spring-jms-examples) by Bruce Snyder (June 2011) +- [Tuning JMS Message Consumption In Spring](https://bsnyderblog.blogspot.com/2010/05/tuning-jms-message-consumption-in.html) (May 2010) +- [Using Spring to Receive JMS Messages](https://bsnyderblog.blogspot.com/2010/02/using-spring-to-receive-jms-messages.html) (February 2010) +- [Using Spring to Send JMS Messages](https://bsnyderblog.blogspot.com/2010/02/using-spring-jmstemplate-to-send-jms.html) (February 2010) + +### Maintenance and Monitoring + +- [Management and monitoring ActiveMQ using hawtio](http://sensatic.net/activemq/activemq-and-hawtio.html) by Dejan Bosanac (April 2014) + +### Books + +See the [Books](books) page for published books on ActiveMQ Classic. + +### Additional Resources + +Many [commercial providers](/support/#commercial-support) have additional examples, articles, tutorials, and documentation. diff --git a/hugo/content/components/classic/documentation/async-sends.md b/hugo/content/components/classic/documentation/async-sends.md new file mode 100644 index 0000000000..0d485de29b --- /dev/null +++ b/hugo/content/components/classic/documentation/async-sends.md @@ -0,0 +1,47 @@ +--- +title: Async Sends +layout: classic-doc +--- + + + +Background +---------- + +ActiveMQ Classic supports sending messages to a broker in sync or async mode. The mode used has a huge impact in the latency of the send call. Since latency is typically a huge factor in the throughput that can achieved by producer, using async sends can increase the performance of your system dramatically. + +The good news is that ActiveMQ Classic sends message in async mode by default in several cases. It is only in cases where the JMS specification required the use of sync sending that we default to sync sending. The cases that we are forced to send in sync mode are when persistent messages are being sent outside of a transaction. + +If you are not using transactions and are sending persistent messages, then each send is synch and blocks until the broker has sent back an acknowledgement to the producer that the message has been safely persisted to disk. This ack provides that guarantee that the message will not be lost but it also costs a huge latency penalty since the client is blocked. + +Many high performance applications are designed to tolerate a small amount of message loss in failure scenarios. If your application has been designed in this fashion, you can enable the use of async sends to increase throughput even when using persistent messages. + +### Configuring Async Send using a Connection URI + +You can use the [Connection Configuration URI](connection-configuration-uri) to configure async sends as follows +``` +cf = new ActiveMQConnectionFactory("tcp://locahost:61616?jms.useAsyncSend=true"); +``` + +### Configuring Async Send at the ConnectionFactory Level + +You can enable this feature on the [ActiveMQConnectionFactory](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/ActiveMQConnectionFactory.html) object using the property. +``` +((ActiveMQConnectionFactory)connectionFactory).setUseAsyncSend(true); +``` + +### Configuring Async Send at the Connection Level + +Configuring the dispatchAsync setting at this level overrides the settings at the connection factory level. + +You can enable this feature on the [ActiveMQConnection](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/ActiveMQConnection.html) object using the property. +``` +((ActiveMQConnection)connection).setUseAsyncSend(true); +``` + +### Also see + +* [Connection Configuration URI](connection-configuration-uri) +* [Should I use transactions](should-i-use-transactions) +* [Consumer Dispatch Async](consumer-dispatch-async) + diff --git a/hugo/content/components/classic/documentation/audit-logging.md b/hugo/content/components/classic/documentation/audit-logging.md new file mode 100644 index 0000000000..e1c02b1a9e --- /dev/null +++ b/hugo/content/components/classic/documentation/audit-logging.md @@ -0,0 +1,33 @@ +--- +title: Audit Logging +layout: classic-doc +--- + + + +For many secured environments there's a requirement to log every user management action. For that ActiveMQ Classic implements _audit logging_, which means that every management action made through JMX or Web Console management interface will be logged and available for later inspection. + +Audit logging comes pre-configured with the distribution, so it's very easy to turn it on or off. All you have to do is to set `org.apache.activemq.audit` system property.  From 5.16.0 the value can be one of "true|entry|exit|all". When the value is all or exit, the audit captures the time the JMX operation completed. You can do that by uncommenting the following line in the startup script: +``` +ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS -Dorg.apache.activemq.audit=true" +``` +The actual logs are by default stored in `${ACTIVEMQ_HOME}/data/audit.log` and for secured broker you may expect entries similar to the following: +``` +2010-12-22 12:12:07,225 | INFO | admin requested /admin/createDestination.action [JMSDestination='test' JMSDestinationType='queue' secret='4eb0bc3e-9d7a-4256-844c-24f40fda98f1' ] from 127.0.0.1 | qtp12205619-39 +2010-12-22 12:12:14,512 | INFO | admin requested /admin/purgeDestination.action [JMSDestination='test' JMSDestinationType='queue' secret='eff6a932-1b58-45da-a64a-1b30b246cfc9' ] from 127.0.0.1 | qtp12205619-36 +2010-12-22 12:12:17,802 | INFO | admin requested /admin/sendMessage.action [JMSTimeToLive='' JMSXGroupSeq='' AMQ_SCHEDULED_DELAY='' JMSType='' JMSMessageCountHeader='JMSXMessageCounter' JMSXGroupID='' JMSReplyTo='' JMSDestination='test' AMQ_SCHEDULED_PERIOD='' JMSText='Enter some text +here for the message body...' JMSDestinationType='queue' AMQ_SCHEDULED_CRON='' JMSCorrelationID='' AMQ_SCHEDULED_REPEAT='' JMSMessageCount='1' secret='a0e1df62-14d6-4425-82a2-17aa01a16e7d' JMSPriority='' ] from 127.0.0.1 | qtp12205619-37 +... +2010-12-22 12:12:57,553 | INFO | admin called org.apache.activemq.broker.jmx.QueueView.purge[] | RMI TCP Connection(8)-192.168.1.107 +2010-12-22 12:13:21,976 | INFO | admin called org.apache.activemq.broker.jmx.QueueView.resetStatistics[] | RMI TCP Connection(8)-192.168.1.107 +2010-12-22 12:13:32,457 | INFO | admin called org.apache.activemq.broker.jmx.QueueView.sendTextMessage[message] | RMI TCP Connection(6)-192.168.1.107 +``` +In this example you can see sample entries for actions taken both in Web Console or via JMX. Log entries contain info like: + +* username (if available), or "anonymous" otherwise +* Operation performed, which in JMX case is the method name and request URL if the operation is performed over web +* Parameters used for the operation and +* IP address from which call has been made + +A default location of the audit log can be configured in `${ACTIVEMQ_HOME}/conf/log4j.properties` + diff --git a/hugo/content/components/classic/documentation/auto.md b/hugo/content/components/classic/documentation/auto.md new file mode 100644 index 0000000000..dac46367ad --- /dev/null +++ b/hugo/content/components/classic/documentation/auto.md @@ -0,0 +1,86 @@ +--- +title: AUTO +layout: classic-doc +--- + +[Connectivity](connectivity) > [Protocols](protocols) > [AUTO](auto) + +Starting with version 5.13.0, ActiveMQ Classic supports wire format protocol detection.   OpenWire, STOMP, AMQP, and MQTT can be automatically detected.  This allows one transport to be shared for all 4 types of clients. + +### Enabling AUTO over TCP + +To configure ActiveMQ Classic auto wire format detection over a TCP connection use the `auto` transport prefix. For example, add the following transport configuration in your XML file: +``` + +``` +### Enabling AUTO over SSL + +To configure ActiveMQ Classic auto wire format detection over an SSL connection use the `auto+ssl` transport prefix. For example, add the following transport configuration in your XML file: +``` + +``` +* For more details on using SSL with ActiveMQ Classic, see the following article ([How do I use SSL](how-do-i-use-ssl)). + +### Enabling AUTO over NIO + +To configure ActiveMQ Classic auto wire format detection over an NIO TCP connection use the `auto+nio` transport prefix. For example, add the following transport configuration in your XML file: +``` + +``` +### Enabling AUTO over NIO SSL + +To configure ActiveMQ Classic auto wire format detection over an NIO SSL connection use the `auto+nio+ssl` transport prefix. For example, add the following transport configuration in your XML file: +``` + +``` + +### Configuring AUTO Transport Options + +There are some configuration options that can be set. + +Parameter Name|Default Value|Description +---|---|--- +protocolDetectionTimeOut|30000|The time before a connection times out in milliseconds. This is similar to maxInactivityDuration. If a client makes a connection to but doesn't send data or enough data for the protocol to be detected then the thread will sit and wait for more data to come in over the socket. This will let the broker kill the connections if they do not complete the protocol initialization after a certain period of time. The default is 30 seconds. Set a default to <= 0 to disable this. +maxConnectionThreadPoolSize|MAX_INT|This option allows the configuration of the maximum size of the thread pool that handles connection attempts. Lowering this number can help prevent the broker from running out of threads if there are many different clients attempting to connect at the same time. By default it is turned off by setting to MAX_INT + +An example that configures the transport with a maximum protocol detection time of 5 seconds: +``` + +``` + +### Configuring Wire Formats + +OpenWire is the default Wire Format that ActiveMQ Classic uses.  It provides a highly efficent binary format for high speed messaging.  OpenWire options can be configured on a JMS client's connection URI string or on a Brokers transport bind URI. + +Parameter Prefix|Description +---|--- +wireFormat.|Applies the option to all wire formats. +wireFormat.default.|Applies the option to the default format which is OpenWire +wireFormat.stomp.|Applies the option to the STOMP wire format +wireFormat.amqp.|Applies the option to the AMQP wire format +wireFormat.mqtt.|Applies the option to the MQTT wire format + +An example of a property that applies to all formats: +``` + +``` +An example of a property only applied to OpenWire would be: +``` + +``` + +### Configuring Enabled Wire Protocols + +By default all wire protocols are available.  This can be configured to only enable certain formats by setting the property  auto`.protocols.`  + +Value|Description +---|--- +default|Enables OpenWire +amqp|Enables AMQP format +stomp|Enables STOMP format +mqtt|Enables MQTT format + +An example showing only OpenWire and STOMP enabled: +``` + +``` diff --git a/hugo/content/components/classic/documentation/benchmark-tests.md b/hugo/content/components/classic/documentation/benchmark-tests.md new file mode 100644 index 0000000000..2871bc28d9 --- /dev/null +++ b/hugo/content/components/classic/documentation/benchmark-tests.md @@ -0,0 +1,15 @@ +--- +title: Benchmark Tests +layout: classic-doc +--- + +## ActiveMQ Classic Maven Performance Test Plugin + +Starting with ActiveMQ Classic 5.5 and above the plugin can be obtained from Maven or if you download the src from GIT you can build it yourself. To run the following Maven goals make sure you are inside a Maven2 project directory where its POM is enabled with the Maven2 plugin. The plugin is further documented in the [ActiveMQ Classic Performance Module Users Manual](activemq-classic-performance-module-users-manual). + +## Third-Party JMS Performance Tests + +There are a number of third-party JMS performance test tools that can be used to measure the performance of various features of brokers and compare them. + +- [Apache JMeter](http://jmeter.apache.org/) +- [jms-benchmark](https://github.com/chirino/jms-benchmark) diff --git a/hugo/content/components/classic/documentation/blob-messages.md b/hugo/content/components/classic/documentation/blob-messages.md new file mode 100644 index 0000000000..df4bfc0275 --- /dev/null +++ b/hugo/content/components/classic/documentation/blob-messages.md @@ -0,0 +1,61 @@ +--- +title: Blob Messages +layout: classic-doc +--- + + + +Blob Messages +------------- + +A common requirement these days is to send around massive files for processing by consumers. Folks want to take advantage of the message broker's features such as reliable, transactional load balancing of queues with smart routing but still manage to deal with huge logical files. + +So we are introducing a BlobMessage API which allows massive BLOBs (Binary Large OBjects) to be sent around in some out-of-band transport mechanism. Possible out-of-band mechanisms could be HTTP or FTP or SCP or some other point-to-point protocol. + +There are now new createBlobMessage() methods on the ActiveMQSession that you can use for sending BLOBs. + +### Sending BlobMessages + +You can send a URL around the JMS network, such as a file or URL which exists on some shared file system or web server using the following code +``` +BlobMessage message = session.createBlobMessage(new URL("http://some.shared.site.com"); +producer.send(message); +``` +Or if you are creating files or streams dynamically on the client you may want to upload the file to the broker or some server (Jetty, FTP, WebDav or whatever). In which case you'd use one of the following methods +``` +// lets use a local file +BlobMessage message = session.createBlobMessage(new File("/foo/bar"); +producer.send(message); + +// lets use a stream +InputStream in = ...; +BlobMessage message = session.createBlobMessage(in); +producer.send(message); +``` + +### Receiving BlobMessages + +A [BlobMessage](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/BlobMessage.html) is a regular JMS message so it can be received just like any other message... +``` +public class MyListener implements MessageListener { + public void onMessage(Message message) { + if (message instanceof BlobMessage) { + BlobMessage blobMessage = (BlobMessage) message; + InputStream in = blobMessage.getInputStream(); + + // process the stream... + } + } +} +``` + +### Configuring the BLOB Transfer Policy + +You can explicitly configure the BlobTransferPolicy on an ActiveMQConnectionFactory, ActiveMQConnection or ActiveMQSession. Typically its done on the factory either via Java code or Spring. + +You can use the [Connection Configuration URI](connection-configuration-uri) to configure these things via a URI. + +For example you can connect to a broker also specifying the uploadUrl to use via +``` +tcp://localhost:61616?jms.blobTransferPolicy.uploadUrl=http://foo.com +``` diff --git a/hugo/content/components/classic/documentation/books.md b/hugo/content/components/classic/documentation/books.md new file mode 100644 index 0000000000..bda0e0fea4 --- /dev/null +++ b/hugo/content/components/classic/documentation/books.md @@ -0,0 +1,11 @@ +--- +title: Books +layout: classic-doc +--- + +Books about Apache ActiveMQ Classic. If you know of a book not listed here, please [contact us](/contact/). + +- [ActiveMQ in Action](https://www.manning.com/books/activemq-in-action) by Bruce Snyder, Dejan Bosanac and Rob Davies (Manning) +- [Instant Apache ActiveMQ Messaging Application Development](https://subscription.packtpub.com/book/application-development/9781782169413) by Timothy Bish (Packt) +- [Mobile and Web Messaging](http://shop.oreilly.com/product/0636920032366.do) by Jeff Mesnil (O'Reilly) +- [Apache ActiveMQ Reference Guide](http://www.ttmsolutions.com/Apache_Software/ActiveMQ_Reference_Guide.php) by TTM Solutions diff --git a/hugo/content/components/classic/documentation/building.md b/hugo/content/components/classic/documentation/building.md new file mode 100644 index 0000000000..0db8d5c17c --- /dev/null +++ b/hugo/content/components/classic/documentation/building.md @@ -0,0 +1,77 @@ +--- +title: Building +layout: classic-doc +--- + + + +Building ActiveMQ Classic from Source +----------------------------- + +ActiveMQ Classic uses [Maven](http://maven.apache.org/) as its build and management tool. If you don't fancy using Maven you can use your IDE directly or [Download](download) a distribution or JAR. + +### Prequisites + +**Required:** + +* Download and [install Maven](http://maven.apache.org/download). +* Get the latest [Source](source) +* JDK (11 for version 5.17.0+, 1.8 for version <= 5.17.0, 1.6 for version <= 5.10, 1.7 for version > 5.10) + +Using Maven 3 +------------------------------------- + +ActiveMQ Classic uses Maven 3 to Build. We recommend you download and install [Maven](http://maven.apache.org/download). + +> You should set the MAVEN_OPTS environment variable to at least -Xmx800m. There are portions of the ActiveMQ Classic build that are very memory intensive. Increase the maven memory limit so that the build does not fail for you. + +### Doing a Quick Build +``` +mvn -DskipTests -DfailIfNoTests=false clean install +``` +### Using an IDE + +If you prefer to use an IDE then you can auto-generate the IDE's project files using maven plugins. e.g. +``` +mvn eclipse:eclipse +``` +or +``` +mvn idea:idea +``` + +> **Importing into Eclipse** +> +> If you have not already done so, you will need to make Eclipse aware of the Maven repository so that it can build everything. In the preferences, go to Java->Build Path->Classpath and define a new Classpath Variable named M2_REPO that points to your local Maven repository (i.e., `~/.m2/repository` on Unix and `c:\Documents and Settings\\.m2\repository` on Windows). + +### Other Maven 2 Goals + +For more details try the [Examples](examples) or [Benchmark Tests](benchmark-tests) +Please refer to the [plugin reference](http://maven.apache.org/plugins/index.html) for more details on using them. + +Using Maven 1 (ActiveMQ Classic 4.0.x and Down) +--------------------------------------- + +ActiveMQ Classic 4.0.x and down use Maven 1 to Build. We recommend you download and install [Maven 1.0.2](http://maven.apache.org/maven-1.x/startOverviewOverview/Overview/download). + +### Doing a Quick Build +``` +maven -Dmaven.test.skip.exec=true +``` +### Using an IDE + +If you prefer to use an IDE then you can autogenerate the IDE's project files using maven plugins. e.g. +``` +maven eclipse +``` +or +``` +maven idea +``` +etc. + +### Other Maven 1 Goals + +For more details try the [Examples](examples) or [Benchmark Tests](benchmark-tests) +Please refer to the [plugin reference](http://maven.apache.org/maven-1.x/plugins/bundled/) for more details on using them. + diff --git a/hugo/content/components/classic/documentation/c-integration.md b/hugo/content/components/classic/documentation/c-integration.md new file mode 100644 index 0000000000..5c54b0fc20 --- /dev/null +++ b/hugo/content/components/classic/documentation/c-integration.md @@ -0,0 +1,24 @@ +--- +title: C Integration +layout: classic-doc +--- + + + +It is very common for an organisation to have lots of legacy C code which needs integration into the message bus. The current available solutions are + +* [CMS](#) is an easy-to-use JMS 1.1-like API for C++. Our implementation of CMS is called ActiveMQ-CPP, the architecture for which supports pluggable transport protocols, very much like the ActiveMQ Classic broker itself. +* use the [OpenWire C Client](openwire-c-client) which is only available in ActiveMQ Classic 4.x or later. +* we are working on the [OpenWire CPP Client](openwire-cpp-client) + +* use the [Stomp C Client](http://stomp.codehaus.org/C) for any version of ActiveMQ Classic from 3.1 onwards. You can also use [Stomp](http://stomp.codehaus.org/) from many other languages like .Net, Python, Ruby, Perl etc. + +Other alternative mechanisms to communicate using. + +* use the [REST](rest) API +* use [WS-Notification](http://servicemix.org/WS+Notification) and generate C bindings to WS-Notification using a SOAP stack +* use [.Net or Mono](how-do-i-access-activemq-classic-from-csharp-or-dotnet) to use ActiveMQ Classic insided .Net +* [Compile ActiveMQ Classic with GCJ](compile-activemq-with-gcj) to get a native C/C++ library +* link to the ActiveMQ Classic Java client using JNI +* Use a Jabber client to talk to the ActiveMQ Classic broker via the [XMPP](xmpp) protocol + diff --git a/hugo/content/components/classic/documentation/cached-ldap-authorization-module.md b/hugo/content/components/classic/documentation/cached-ldap-authorization-module.md new file mode 100644 index 0000000000..cd24b3f5aa --- /dev/null +++ b/hugo/content/components/classic/documentation/cached-ldap-authorization-module.md @@ -0,0 +1,86 @@ +--- +title: Cached LDAP Authorization Module +layout: classic-doc +--- + + + +> **Available since 5.6** +> +> Cached LDAP authorization module is an implementation of an default authorization module that initializes and updates data from LDAP. It supports all standard features like defining wildcard policy entries and entry for temporary destinations. + +Initializing +------------ + +We provide two ldif files for easy starting. The first one is for [Apache Directory Server](http://directory.apache.org/) ([ldif](https://github.com/apache/activemq/tree/main/activemq-unit-tests/src/test/resources/org/apache/activemq/security/activemq-apacheds.ldif)), which we use in embedded mode for testing. For an example on how to initialize the embedded ApacheDS with this ldif file take a look at [CachedLDAPSecurityTest](https://github.com/apache/activemq/tree/main/activemq-unit-tests/src/test/java/org/apache/activemq/security/CachedLDAPSecurityTest.java) + +The other one is for [OpenLDAP](http://www.openldap.org/) ([ldif](https://github.com/apache/activemq/tree/main/activemq-unit-tests/src/test/resources/org/apache/activemq/security/activemq-openldap.ldif)) + +The provided ldif and examples assume `dc=activemq,dc=apache,dc=org` suffix to be used for entries, so the configuration similar to the one shown in the following snippet +``` +suffix "dc=activemq,dc=apache,dc=org" +rootdn "cn=admin,dc=activemq,dc=apache,dc=org" +# Cleartext passwords, especially for the rootdn, should +# be avoid. See slappasswd(8) and slapd.conf(5) for details. +# Use of strong authentication encouraged. +rootpw {SSHA}lfAYn54xCFghgQv5B2Kqn3d3eLojqxtS +``` +should be put into your `slapd.conf` + +To initialize your (properly configured) OpenLDAP do something like +``` +ldapadd -x -D "cn=admin,dc=activemq,dc=apache,dc=org" -w sunflower -f activemq-openldap.ldif +``` + +Configuring +----------- + +Once entries are in LDAP, you can configure the module to load entries from there. A default values are adapted for embedded Apache DS server, so all you have to do in that case is add your plugin to the broker xml conf +``` + + + + + +``` +For the OpenLDAP case, you should define more parameters +``` + + + + + +``` +Full examples of configurations for [Apache DS](https://github.com/apache/activemq/tree/main/activemq-unit-tests/src/test/resources/org/apache/activemq/security/activemq-apacheds.xml) and [OpenLDAP](https://github.com/apache/activemq/tree/main/activemq-unit-tests/src/test/resources/org/apache/activemq/security/activemq-openldap.xml) + +The list of all properties for `cachedLDAPAuthorizationMap` + +property|default value|description|version +---|---|--- +connectionURL|ldap://localhost:1024|LDAP Server connection address. This can either be a single URL or a space-separated list of URLs.| +connectionUsername|uid=admin,ou=system|Dn to be used for connecting to the server| +connectionPassword|secret|Password to be used for connecting to the server| +connectionProtocol|s|Connection protocol to be used for connecting to the server| +authentication|simple|Authentication method to be used when connecting to the server| +queueSearchBase|ou=Queue,ou=Destination,ou=ActiveMQ,ou=system|Base dn of queue related entries|5.7 and later +topicSearchBase|ou=Topic,ou=Destination,ou=ActiveMQ,ou=system|Base dn of topic related entries|5.7 and later +tempSearchBase|ou=Temp,ou=Destination,ou=ActiveMQ,ou=system|Base dn of temporary destinations related entries|5.7 and later +refreshInterval|-1|Interval (in milliseconds) of pulling changes from the server, -1 means pulling is off, see #Updates for more info| +legacyGroupMapping|true|Should permission group members be configured as CN and not a full DN|5.7 and later + +Updates +------- + +Many LDAP servers supports so called "persistent search" feature which allows applications to receive changes in LDAP in a "push" manner. By default this plugin assumes that LDAP server supports this feature and will "register" to get live updates. + +For servers that doesn't support this yet (like OpenLDAP), we provide "pull" updates. In this case you need to set `refreshInterval` property, which will define the update period for the plugin (so in this case, updates will not be immediately applied) + diff --git a/hugo/content/components/classic/documentation/can-i-modify-messages-on-a-queue.md b/hugo/content/components/classic/documentation/can-i-modify-messages-on-a-queue.md new file mode 100644 index 0000000000..5109733950 --- /dev/null +++ b/hugo/content/components/classic/documentation/can-i-modify-messages-on-a-queue.md @@ -0,0 +1,12 @@ +--- +title: Can I modify messages on a queue +layout: classic-doc +--- + + + +Can I modify messages on a queue? +--------------------------------- + +The short answer is no. In JMS messages are immutable once they have been sent. If you find you need to modify messages its recommended that you create a consumer with some selector which matches the messages you wish to update, consume them and send new modified messages, either to another queue or if you are careful, back to the original queue. (If you are using the same queue, be careful not to get into a loop where your selector matches messages you are sending yourself - you may wish to use some JMS header to avoid this loop). + diff --git a/hugo/content/components/classic/documentation/can-i-send-and-receive-messages-concurrently-on-one-jms-connection.md b/hugo/content/components/classic/documentation/can-i-send-and-receive-messages-concurrently-on-one-jms-connection.md new file mode 100644 index 0000000000..9e0d39ed39 --- /dev/null +++ b/hugo/content/components/classic/documentation/can-i-send-and-receive-messages-concurrently-on-one-jms-connection.md @@ -0,0 +1,15 @@ +--- +title: Can I send and receive messages concurrently on one JMS Connection +layout: classic-doc +--- + + + +Absolutely! + +Strictly speaking each producer being used concurrently should be using a separate session (though in ActiveMQ Classic it'll probably work fine if you just use one session for all publishers). + +For concurrent consumption create a session per consumer - as all messages are dispatched to a session in a single thread - but you can have as many sessions as you like per connection. + +To further help with concurrent consuming of JMS you can use [Message Driven POJOs](http://jencks.codehaus.org/Message+Driven+POJOs) + diff --git a/hugo/content/components/classic/documentation/can-i-send-really-large-files-over-activemq-classic.md b/hugo/content/components/classic/documentation/can-i-send-really-large-files-over-activemq-classic.md new file mode 100644 index 0000000000..6e4a2e4d6a --- /dev/null +++ b/hugo/content/components/classic/documentation/can-i-send-really-large-files-over-activemq-classic.md @@ -0,0 +1,17 @@ +--- +title: Can I send really large files over ActiveMQ Classic? +layout: classic-doc +--- + + + +Can I send really large files over ActiveMQ Classic? +---------------------------------------------------- +If you are using ActiveMQ Classic 4.2 or later we highly recommend you use [Blob Messages](blob-messages) which implements an out-of-band transport of the messages. It allows the files to be hosted on external http/ftp sites if required and can support either direct publisher <-> subscriber communication or publisher -> broker/file server -> consumer messaging. + +For 4.1 or ealier large file transfer is achieved using [JMS Streams](jms-streams). + +Normally the JMS API expects the entire JMS messsage to reside in the client side memory; however using [Blob Messages](blob-messages) or [JMS Streams](jms-streams) allows you to send and receive arbitrarily large files with very low RAM overhead. + +If you want the broker itself to be able to handle large messages (i.e. without needing to use an out-of-band transport mechanism like HTTP or FTP) then use [ActiveMQ Artemis](../../artemis/documentation/latest/large-messages.html). + diff --git a/hugo/content/components/classic/documentation/can-i-use-activemq-classic-5x-or-later-on-java-14.md b/hugo/content/components/classic/documentation/can-i-use-activemq-classic-5x-or-later-on-java-14.md new file mode 100644 index 0000000000..050ae711dd --- /dev/null +++ b/hugo/content/components/classic/documentation/can-i-use-activemq-classic-5x-or-later-on-java-14.md @@ -0,0 +1,21 @@ +--- +title: Can I use ActiveMQ Classic 5.x or later on Java 1.4 +layout: classic-doc +--- + + + +Can I use ActiveMQ Classic 5.0 or later on Java 1.4? +-------------------------------------------- + +Apache ActiveMQ Classic 5.x or later is developed to run on Java 5 or later to take advantage of the new language features together with the major fact that on Java 5 the new concurrency code is faster & less buggy and requires less dependencies. + +We may get around to creating a sepate distro of retrotranslated jars for 1.4 [particularly if someone helps](contributing). + +Until then you can just [install the retrotranslator JIT in your JVM](http://retrotranslator.sourceforge.net/#jit) which will auto-swizzle all Java 5 bytecode to be complaint Java 1.4 bytecode using backport-util-concurrent instead of Java 5 concurrency code. + +See Also +-------- + +* [What platforms does ActiveMQ Classic support](what-platforms-does-activemq-classic-support) + diff --git a/hugo/content/components/classic/documentation/can-two-brokers-share-the-same-database.md b/hugo/content/components/classic/documentation/can-two-brokers-share-the-same-database.md new file mode 100644 index 0000000000..8c4599e2e1 --- /dev/null +++ b/hugo/content/components/classic/documentation/can-two-brokers-share-the-same-database.md @@ -0,0 +1,16 @@ +--- +title: Can two brokers share the same database +layout: classic-doc +--- + + + +Can two brokers share the same database +--------------------------------------- + +The short answer is no; 2 brokers cannot operate on the same sets of database tables concurrently. ActiveMQ Classic is designed for high performance so we want to minimise the amount of pessimistic locking; each broker is designed to work with its own persistent database. + +If you want to share the same physical database server across two brokers to simplify your installation & backup procedures then just create 2 different logins for each broker so that they get their own sets of database tables within the same physical database. (i.e. each broker gets its own logical database within the same physical database server). + +Also if you want to only have one database but many possible brokers (for HA) then just use [JDBC Master Slave](jdbc-master-slave) + diff --git a/hugo/content/components/classic/documentation/can-you-browse-a-topic.md b/hugo/content/components/classic/documentation/can-you-browse-a-topic.md new file mode 100644 index 0000000000..e1de06e36a --- /dev/null +++ b/hugo/content/components/classic/documentation/can-you-browse-a-topic.md @@ -0,0 +1,15 @@ +--- +title: Can you browse a topic +layout: classic-doc +--- + + + +You can browse queues, can you browse a topic? + +No. But then consuming messages on a topic does not affect any other consumers, so you don't need to 'browse' per se, just subscribe. + +i.e. browsing is necessary on queues as you wanna see what messages there are without removing them. For topics, everyone who's interested gets a copy of the message so just do a regular subscribe. + +One nice to have feature would be to expose durable subscriptions as a logical queue, so you could browse outstanding messages on a durable subscription as if it were a queue (see [AMQ-25](https://issues.apache.org/activemq/browse/AMQ-25) to track this feature request)but its not in any way standard JMS. + diff --git a/hugo/content/components/classic/documentation/certificateunknown.md b/hugo/content/components/classic/documentation/certificateunknown.md new file mode 100644 index 0000000000..b0c2adeea1 --- /dev/null +++ b/hugo/content/components/classic/documentation/certificateunknown.md @@ -0,0 +1,31 @@ +--- +title: certificate_unknown +layout: classic-doc +--- + + + +If you get an error something like this... +``` +javax.jms.JMSException: start failed: Received fatal alert: certificate_unknown + at org.activemq.transport.tcp.TcpTransportChannel.start(TcpTransportChannel.java:200) + at org.activemq.broker.impl.BrokerConnectorImpl.addClient(BrokerConnectorImpl.java:308) + at org.activemq.transport.TransportServerChannelSupport.addClient(TransportServerChannelSupp + at org.activemq.transport.tcp.TcpTransportServerChannel.run(TcpTransportServerChannel.java:1 + at java.lang.Thread.run(Unknown Source) +Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown + at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source) + at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source) + at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source) + at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source) + at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) + at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source) + at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source) + at java.io.BufferedInputStream.fill(Unknown Source) +``` +when you are trying to use SSL to connect to ActiveMQ Classic then the "certificate_unknown" error shows on the broker when the client doesn't trust the broker's certificate. On the client, I would see an error as well: "No trusted certificate found". + +### Fix + +Make sure that you exported the broker's certificate (step 2 in [How do I use SSL](how-do-i-use-ssl)) and imported it on the client into a truststore (step 4). If you did those, did you specify the javax.net.ssl.trustStore system property when you started your client VM? + diff --git a/hugo/content/components/classic/documentation/code-overview.md b/hugo/content/components/classic/documentation/code-overview.md new file mode 100644 index 0000000000..e99ef4ba19 --- /dev/null +++ b/hugo/content/components/classic/documentation/code-overview.md @@ -0,0 +1,123 @@ +--- +title: Code Overview +layout: classic-doc +--- + + + +Architecture +============ + +The following section walks through the main parts of Apache ActiveMQ Classic and links to the code to help you understand the layout + +![](../../../assets/img/BrokerDiagram.png) + +JMS Client +---------- + +The [org.apache.activemq](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/package-summary.html) package defines the core JMS client. + +Transport +--------- + +The JMS client and the message broker use the [Transport](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/transport/Transport.html) abstraction for sending around command objects (like a distributed _Command Pattern_). A TransportChannel typically deals with some kind of networking mechanism (TCP sockets using BIO, using NIO, UDP / multicast, SSL over sockets, JXTA, EmberIO etc). See the [org.apache.activemq.transport](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/transport/package-summary.html) package for more details + +So the TransportChannel is basically concerned with sending and receiving [Command](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/command/Command.html) objects (each instance represents some kind of _command_). Packet is defined in the [org.apache.activemq.command](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/command/package-summary.html) package which defines all the JMS Message implementations classes (which are Commands) along with a number of other kinds of packets, like subsciptions, message acknowledgements, transactions and so forth. + +WireFormat +---------- + +There are various possible ways of encoding messages onto a stream. We may wish to adapt to various different encoding mechanisms - such as to provide simpler wire formats for talking to C / JavaScript or to make a C# friendly encoding. + +So all the Transport  implementations take a pluggable WireFormat implementation class - which is a _Strategy Pattern_ for deciding how to write the Command to a DataIn / DataOut stream or Datagram. + +So if you wish to provide your own binary, _on the wire_ protocol then we just need a WireFormat implementation of your protocol, then we can use this with any transport (TCP BIO, NIO, JXTA etc). + +We use [OpenWireFormat](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/openwire/OpenWireFormat.html) by default which is the most efficient & easiest format to use from Java code - so if both ends of the wire are Java then its highly recommended. Though other WireFormats are most welcome. + +Default Wire Format +------------------- + +The default wire format writes a byte which indicates the kind of Command which is being sent (see the [CommandTypes](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/command/CommandTypes.html) interface which defines all the int constants for each type of command. + +The core JMS Message types each have a unique byte ID for + +* Message +* ObjectMessage +* TextMessage +* MapMessage +* BytesMessage +* StreamMessage + +Then in addition there are various other [types of command](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/command/package-summary.html) such as + +* [ConnectionInfo](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/command/ConnectionInfo.html) for when a new connection is established with a message broker +* [ConsumerInfo](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/command/ConsumerInfo.html) when a new consumer is created on a connection +* [MessageAck](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/command/MessageAck.html) to acknowledge a message ID +* [TransactionInfo](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/command/TransactionInfo.html) to denote a transaction + +There are a few others; the [org.apache.activemq.command](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/command/package-summary.html) package describes them in their gory detail. + +Basically the DefaultWireFormat has a default encoding of each of these commands. So after the first byte which indicates the type of packet is written, there is a specific wire format per packet type. + +For new wire formats it may be that you only need to support a small subset of these types. e.g. you might just have a simple publish message, consume message & message ack. + +Message Broker +============== + +The APIs for the message broker (server side of the JMS client) are defined in the [org.apache.activemq.broker](https://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/broker/package-summary.html). There are various other packages which define different parts, from the message stores to the message routing and so forth. + +To see an overview of these packages try the [JavaDocs](docs) + +* * * + +ActiveMQ Classic System Overview +======================== + +Introduction +------------ + +ActiveMQ Classic is the system responsible for creating and managing network connections used for communication between clients and the broker. This document hopes to outline the inner workings of this system with in order to make it easier to understand for future developers. It will give a high-level overview of the system and outline the major players. We will also cover a few other interesting classes that may be useful to others working on the system. Most of this document is written with the server side code in mind. This is because the client-side communication systems are architecturally simple and understanding the server will make understanding clients trivial by comparison. + +We assume the reader has basic understanding of JMS. Refer to the official Java docs for more information. + +Overview: The Big Players +------------------------- + +The core classes involved in the ActiveMQ Classic communication system are Transports. These include the `Transport`, `TransportServer`, and `TransportFactory` hierarchies. `Transport`s and `TransportServer`s are wrappers around sockets and server sockets respectively. `TransportFactory`s (as you may have guessed) are factories that create `Transport`s and `TransportServers`. `Transport`s are connected to `Broker`s and transmit `Command`s, which represent all major actions to be taken by ActiveMQ Classic (more on this later). The following example illustrates how these pieces fit together. + +The primary class needed to create a JMS "provider" application is the `Broker` class. The default ActiveMQ Classic binary will use a `BrokerService` class to wrap around `Broker`s. When the application is started, it instantiates a `BrokerService` and instructs it to bind to a specific (local) address, say "tcp://localhost:61616". The `Broker` will use the scheme in the given address and find the proper `TransportFactory`, `TcpTransportFactory` in this example. This factory will then be used to create a `TcpTransportServer` that will be bound to "localhost:61616". Once the `TransportServer` is started, it will continually pole its socket for incoming connections. Successfully connected incoming sockets will be wrapped in a `TcpTransport` instance and passed back (indirectly) to the `Broker`. The `Broker` will then start polling the new `Transport` for incoming `Command`s to process. + +The final pieces missing from the above example are the `TransportConnection` and `TransportConnector` classes. These classes are used to connect `Broker`s to `Transport`s and `TransportServer`s respectively. + +Class Details +------------- + +This section will explain some of the more interesting details of the mentioned classes separately. + +### Transports, TransportServers, and TransportFactories + +The basic principles of how these classes operate are very simple: `Transport`s and `TransportServer`s are wrappers around sockets and server sockets used to hide implementation, and `TransportFactory`s are factory classes for the mentioned classes. The only caveats are how `TransportFactory`s are chosen and configured based on URIs they are supplied. + +The `TransportFactory` class is abstract and incapable of creating `Transport` or `TransportServer` classes directly. It, nevertheless, is the class used to create `Transport`s and `TransportServer`s. `TransportFactory` delegates its responsibilities to its subclasses based on the choice of subclass provided by the `FactoryFinder` class, which uses the URI's scheme to find a matching factory classes based on text files stored under the META-INF directory. + +Configuration of the created `Transport`s is done entirely to reflection. `Transport`s are configured through calls to `compositeConfigure`, which are made by the factory at the time of the `Transport`'s creation. `compositeConfigure` uses the `IntrospectionSupport` class to call setters for parameters passed in through the URI. For example, creating a `Transport` using the URI "ssl://localhost:61616/?needClientAuth=true" would result in the creation of an `SslTransport` object whose `setNeedClientAuth` method (if it exists) is called with the value of `true` immediately after its creation. `TransportServer`s operate in a similar fashion. The only difference is that the call to `IntrospectionSupport` is made from the `doBind` method of the `TransportFactory`. + +### Commands + +`Command`s are the main means for communication within `Broker`s. Each `Command` represents an action to be taken. `Command` subclasses include `ConnectionInfo`, `KeepAliveInfo`, and `Message`, which result in processing of new connections, maintenance of old connections, and processing of user messages respectively. These classes are de-serialized from `Transport`s using Marshalers. Whenever new data is found in a socket, the first byte is read to determine what type of `Command` being received. The proper Marshaller is then selected to de-serialize the `Command` (e.g. to de-serialize a `ConnectionInfo`, the `ConnectionInfoMarshaller` is used). + +### TransportConnections and TransportConnectors + +Every `TransportServer` is connected to a `Broker` using a `TransportConnector`. The server's accept listener (which is called when a new `Transport` is constructed) is set to call the given `TransportConnector`'s `createConnection` method with the new `Transport`. When called, `createConnection` creates a new `TransportConnection` that links the given `Transport` and the supporting `Broker` together; the `Transport`'s transport listener is set to the `TransportConnection`'s `onCommand` method, which is then called whenever a new `Command` is received. + +`Command`s and `AbstractConnection` (the superclass of `TransportConnection`) form a visitor pattern. `onCommand` will call `AbstractConnection`'s service method which will make a series of calls in line with the visitor patter and eventually, the proper `Command` subclass to be passed to the corresponding method of the `Broker` for processing. + +### BrokerFilters and BrokerPlugins + +While not used directly by the communication system, `BrokerFilter`s and `BrokerPlugin`s provide an effective and easy to use way of modifying Broker behavior. `BrokerFilter`s allow for one to modify a few `Broker` methods without touching the rest (as the name suggests). The `BrokerFilter` passes on all of its responsibilities to a `Broker` it receives in its constructor. Subclassing `BrokerFilter` allows us to perform additional actions before passing the work down to the underlying `Broker`. + +The power of the `BrokerFilter` class comes from the fact that multiple filters can be cascaded to create different functional combinations. As an example, the `JaasAuthenticationBroker` is a subclass of `BrokerFilter` that modifies the methods used for adding and removing connections to allow for JAAS authentication. `AuthorizationBroker` is another subclass of `BrokerFilter`. This class modifies the destination regulation methods to enforce access levels. With this architecture, one can create a `JaasAuthenticationBroker` and have it use an `AuthorizationBroker` as its underlying broker (which would use another broker itself, etc.). + +`BrokerPlugin`s are simple classes that will wrap their corresponding `Brokers` around the one they are given. i.e. "installing" an `AuthorizationPlugin` on an existing `Broker` will create an `AuthorizationBroker` that uses the original `Broker` internally. The main reason for the existence of `BrokerPlugin`s is to allow for one to configure the `Broker` used by the `BrokerService` class (either through code or XML configuration and spring). + diff --git a/hugo/content/components/classic/documentation/community.md b/hugo/content/components/classic/documentation/community.md new file mode 100644 index 0000000000..7a9ed2f637 --- /dev/null +++ b/hugo/content/components/classic/documentation/community.md @@ -0,0 +1,11 @@ +--- +title: Community +layout: classic-doc +--- + +- [Articles](articles) +- [Books](books) +- [Contributing](/contributing/) +- [FAQ](faq) +- [Projects Using ActiveMQ Classic](projects-using-activemq-classic) +- [Privacy Policy](/privacy-policy/) diff --git a/hugo/content/components/classic/documentation/composite-destinations.md b/hugo/content/components/classic/documentation/composite-destinations.md new file mode 100644 index 0000000000..ecc1416009 --- /dev/null +++ b/hugo/content/components/classic/documentation/composite-destinations.md @@ -0,0 +1,27 @@ +--- +title: Composite Destinations +layout: classic-doc +--- + + +As of version 1.1, ActiveMQ Classic supports a technology we call _composite destinations_. This allows a single virtual JMS Destination to be used to represent a collection of JMS Destinations. + +For example you can use composite destinations to send a message to 12 physical queues in one operation. Or send a message to one topic and one queue in one operation. + +We do this using a simple separator of "," allowing a number of destinations to be specified when creating a destintation, or registering destinations in JNDI. e.g. the destination +``` +FOO.A,FOO.B,FOO.C +``` +Represents 3 different destinations. This could be used with a queue or topic to represent a set of 3 destinations. e.g. +``` +// send to 3 queues as one logical operation +Queue queue = new ActiveMQQueue("FOO.A,FOO.B,FOO.C"); +producer.send(queue, someMessage); +``` +If you wish to mix and match the types of destination, you can use a prefix of `queue://` or `topic://` to differentiate the type of destination. e.g. to publish on a queue but also make a notification on a topic as well you could use +``` +// send to queues and topic one logical operation +Queue queue = new ActiveMQQueue("FOO.A,topic://NOTIFY.FOO.A"); +producer.send(queue, someMessage); +``` +Composite destinations can also be configured on the [broker side](virtual-destinations), such that messages sent to a single destination by the client will be transparently copied to multiple physical destinations. diff --git a/hugo/content/components/classic/documentation/configure-version-5-brokers.md b/hugo/content/components/classic/documentation/configure-version-5-brokers.md new file mode 100644 index 0000000000..07f87b4dd3 --- /dev/null +++ b/hugo/content/components/classic/documentation/configure-version-5-brokers.md @@ -0,0 +1,127 @@ +--- +title: Configure version 5 Brokers +layout: classic-doc +--- + + + +### Overview + +There is an updates XML syntax for configuring message brokers - [see here](http://activemq.apache.org/schema/core/activemq-core-5.0-SNAPSHOT.xsd) + +So we decided that using XML would make this configuration much easier. we use [XBean](https://geronimo.apache.org/xbean/) to perform the XML configuration. + +For details of the XML see the [Xml Reference](xml-reference) + +Be careful with broker names and URIs + +Make sure you do not use any strange characters in the names of brokers as they are converted to URIs which [do not allow things like underscores](http://java.sun.com/j2se/1.4.2/docs/api/java/net/URI.html) in them etc. + +Examples +-------- + +The default ActiveMQ Classic configuration: [current default config](https://github.com/apache/activemq/blob/main/assembly/src/release/conf/activemq.xml). +``` + + + + + file:${activemq.conf}/credentials.properties + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +From the binary distributionthere is an `activemq` script allowing you to run a Message Broker as a stand alone process from the command line easily providing the `$ACTIVEMQ_HOME/bin` directory is on your PATH. + diff --git a/hugo/content/components/classic/documentation/configuring-version-5-transports.md b/hugo/content/components/classic/documentation/configuring-version-5-transports.md new file mode 100644 index 0000000000..667e6861a6 --- /dev/null +++ b/hugo/content/components/classic/documentation/configuring-version-5-transports.md @@ -0,0 +1,201 @@ +--- +title: Configuring Transports +layout: classic-doc +--- + + [Using ActiveMQ Classic]() > [Configuring Transports](configuring-version-5-transports) + +Transport configuration options +------------------------------- + +One of the first kinds of URI you are likely to use is a transport URI to connect to a broker using a kind of transport. Generally TCP or VM are the first transports you'll use. + +> **Be careful about whitespace** +> +> All of the following URI configurations are based on the java.net.URI class which does not allow whitespace to be used. So if you are using `failover:` or `static:` URIs, do not put any whitespace around the `','` symbol. + +### The AUTO Transport + +Starting with 5.13.0 ActiveMQ Classic has support for automatic wire protocol detection over TCP, SSL, NIO, and NIO SSL.  OpenWire, STOMP, AMQP, and MQTT are supported.  For details see the [AUTO](auto) Transport Reference. + +### The VM Transport + +The VM transport allows clients to connect to each other inside the VM without the overhead of the network communication. The connection used is not that of a socket connection but instead uses direct method invocations to enable a high performance embedded messaging system. + +The first client to use the VM connection will boot an embedded broker. Subsequent connections will attach that the same broker. Once all VM connections to the broker have been closed, the embedded broker will automatically shutdown. + +For more information see the [VM Transport Reference](vm-transport-reference) + +### The AMQP Transport + +As of 5.8.0 ActiveMQ Classic has support for AMQP. For details see the [AMQP](amqp) Transport Reference. + +### The MQTT Transport + +Starting with 5.6.0 ActiveMQ Classic also supports [MQTT](http://mqtt.org/). Its a light weight publish/subscribe messaging transport. See the [MQTT](mqtt) Transport Reference for details. + +### The TCP Transport + +The TCP transport allows clients to connect a remote ActiveMQ Classic using a a TCP socket. + +For more information see the [TCP Transport Reference](tcp-transport-reference) + +### The NIO Transport + +Same as the TCP transport, except that the [New I/O (NIO)](http://en.wikipedia.org/wiki/New_I/O) package is used, which may provide better performance. The Java NIO package should not be confused with IBM's [AIO4J](http://java.sys-con.com/read/46658.htm) package. + +To switch from TCP to NIO, simply change the scheme portion of the URI. Here's an example as defined within a broker's XML configuration file. +``` + + ... + + + + ... + +``` +Trying to use nio transport url on the client side will instantiate the regular TCP transport. For more information see the [NIO Transport Reference](nio-transport-reference) + +### The SSL Transport + +This allows you to talk over TCP using SSL. For more information see the [SSL Transport Reference](ssl-transport-reference) + +### The NIO SSL Transport + +> **Availability** +> +> Available since 5.6 + +Implementing SSL transport over NIO. This allows you to connect large number of SSL clients to a single broker instance. It's server side transport-option only +``` + + ... + + + + ... + +``` +Trying to use `nio+ssl` transport url on the client side will instantiate the regular SSL transport. + +### The Peer Transport + +The Peer transport provides a peer-to-peer network with ActiveMQ Classic. What actually happens is the peer transport uses the VM transport to create and connect to a local embedded broker but which configures the embedded broker to establish network connections to other peer embedded brokers. + +For more information see the [Peer Transport Reference](peer-transport-reference) + +### The UDP Transport + +This allows you to talk over UDP. + +For more information see the [UDP Transport Reference](udp-transport-reference) + +### The Multicast Transport + +This allows you to talk over Multicast. + +For more information see the [Multicast Transport Reference](multicast-transport-reference) + +### The HTTP and HTTPS Transport + +This allows the ActiveMQ Classic client and broker to tunnel over HTTP. If the client is not JMS you might want to look at [REST](rest) or [Ajax](ajax) support instead. + +For more information see the [HTTP and HTTPs Transports Reference](http-and-https-transports-reference) + +### The WebSockets Transport + +This transport uses the new HTML5 WebSockets to exchange messages with the broker. For more information see the [WebSockets](websockets) Transport Reference + +### The Stomp Transport + +A plain text transport that can be used with many languages. See [Stomp](stomp) for more details. + +General Purpose URIs +-------------------- + +You can configure other features via the URI syntax as follows... + +### Connection Configuration URI + +Any Apache ActiveMQ Classic JMS connection can be configured using the URL or explicitly setting properties on the [ActiveMQConnection](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/ActiveMQConnection.html) or [ActiveMQConnectionFactory](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/ActiveMQConnectionFactory.html) objects themselves. + +For more information see [Connection Configuration URI](connection-configuration-uri) + +### Destination Options + +You can configure various consumer related options using [Destination Options](destination-options) which allow you to configure destinations using URI syntax. + +### Broker Configuration URI + +You can use a [Broker Configuration URI](broker-configuration-uri) to configure an embedded broker, either using the BrokerFactory helper class from Java or using the activemq shell script. For more details see [How to Run a Broker](run-broker) + +### Configuring Wire Formats + +Any transport which involves marshalling messages onto some kind of network transport like TCP or UDP will typically use the [OpenWire](openwire) format. This is configurable to customize how things appear on the wire. + +For more information see [Configuring Wire Formats](configuring-wire-formats) + +High Level Protocol URIs +------------------------ + +The following higher level protocols can be configured via URI + +### The Failover Transport + +The Failover transport layers reconnect logic on top of any of the other transports. This is what used to be the Reliable transport in ActiveMQ Classic 3. Its configuration syntax allows you to specify any number of composite URIs. The Failover transport randomly chooses one of the composite URIs and attempts to establish a connection to it. If it does not succeed or if it subsequently fails, a new connection is established to one of the other URIs in the list. + +For more information see the [Failover Transport Reference](failover-transport-reference) + +### The Fanout Transport + +The Fanout transport layers reconnect and replicate logic on top of any of the other transports. It is used replicate commands to multiple brokers. + +For more information see the [Fanout Transport Reference](fanout-transport-reference) + +Using Discovery +--------------- + +Often when using transports like TCP you want to use [Discovery](discovery) to locate the available brokers. This is different from using, say, [Multicast](multicast-transport-reference) - as the actual main communication is over TCP but multicast is purely used to discover the location of brokers. + +### The Discovery Transport + +The Discovery transport works just like the reliable transport, except that it uses a discovery agent to locate the list of URIs to connect to. + +For more information see the [Discovery Transport Reference](discovery-transport-reference) + +### The ZeroConf Transport + +The ZeroConf transport provides [Discovery](discovery) and it works like the [Discovery Transport](discovery-transport-reference) but rather than using our own multicast based discovery mechanism (which allows you to configure the exact multicast address and port, etc.), the [ZeroConf](zeroconf) transport is used instead. + +For more information see the [ZeroConf Transport Reference](zeroconf-transport-reference) + +### Server side options + +There are a number of options that can be used for changing behavior on the server for the `TransportConnector` in the ActiveMQ Classic broker configuration. These are: + +property name|default|description +---|---|--- +`allowLinkStealing`|`false`|This is enabled for default for MQTT transport. Link Stealing is where the last of two or more connections with the same id (clientID for JMS) is deemed the valid connection and the older one is closed by the broker. +discoveryURI`|`null`|If set, the multicast discovery address for client connections to find the broker. +`enableStatusMonitor`|`false`|Will monitor connections to determine if they are blocked. +`name`|`null`|The name of the `TransportConnector` instance. +`rebalanceClusterClients`|`false`|Will automatically re-balance clients across the cluster on changes of topology. +`updateClusterClients`|`false`|If enabled, will update client connections (if they use the `failover://` transport) of changes to the broker cluster. +`updateClusterClientsOnRemove`|`false`|Will update clients if a broker is removed from the cluster. +`updateClusterFilter`|`null`|Comma separated list of regular expressions. Brokers with a name matching the pattern will be included for client updates. +`uri`|`null`|The bind address for the transport. + +`Note**: properties in red are version 5.10 (and higher) options only. + +Example configuration: +``` + +   + +   +     +   + +   + +``` \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/connectivity.md b/hugo/content/components/classic/documentation/connectivity.md new file mode 100644 index 0000000000..f05b653b46 --- /dev/null +++ b/hugo/content/components/classic/documentation/connectivity.md @@ -0,0 +1,39 @@ +--- +title: Connectivity +layout: classic-doc +--- + +Apache ActiveMQ Classic supports a large number of [Cross Language Clients](../cross-language-clients), a wide range of [Protocols](../protocols), and many [Containers](../containers). + +### Protocols + +- [AMQP](../amqp) +- [AUTO](../auto) +- [MQTT](../mqtt) +- [OpenWire](../openwire) +- [REST](../rest) +- [Stomp](../stomp) +- [WebSockets](../websockets) +- [XMPP](../xmpp) + +### Cross Language Clients + +- [C Integration](../c-integration) +- [Delphi and FreePascal](../delphi-and-freepascal) +- [ActiveMQ Classic C++ Clients](../activemq-c-clients) + +### Containers + +- [Spring Support](../spring-support) +- [OSGi Integration](../osgi-integration) +- [Tomcat](../tomcat) +- [JBoss Integration](../jboss-integration) +- [Geronimo](../geronimo) +- [J2EE](../j2ee) +- [Resource Adapter](../resource-adapter) +- [JNDI Support](../jndi-support) + +### Bridging + +- [JMS to JMS Bridge](../jms-to-jms-bridge) +- [Ajax](../ajax) diff --git a/hugo/content/components/classic/documentation/containers.md b/hugo/content/components/classic/documentation/containers.md new file mode 100644 index 0000000000..229b7c6b12 --- /dev/null +++ b/hugo/content/components/classic/documentation/containers.md @@ -0,0 +1,28 @@ +--- +title: Containers +layout: classic-doc +--- + + + +This page lists the various containers that Apache ActiveMQ Classic works inside + +* [Axis and CXF Support](axis-and-cxf-support) +* [BlazeDS](blazeds) +* [Geronimo](geronimo) +* [Integrating Apache ActiveMQ Classic with Glassfish](integrating-apache-activemq-classic-with-glassfish) +* [Integrating Apache ActiveMQ Classic with JBoss](integrating-apache-activemq-classic-with-jboss) +* [J2EE](j2ee) +* [JBoss Integration](jboss-integration) +* [JCA Container](jca-container) +* [JNDI Support](jndi-Community/support) +* [Old OSGi Integration](old-osgi-integration) +* [OSGi Integration](osgi-integration) +* [Resource Adapter](resource-adapter) +* [SJSAS with GenericJMSRA](sjsas-with-genericjmsra) +* [Spring Support](spring-support) +* [Sun JNDI](sun-jndi) +* [Tomcat](tomcat) +* [WebLogic Integration](weblogic-integration) +* [zOS](zos) + diff --git a/hugo/content/components/classic/documentation/could-not-find-packetreader-for-packet-type-unknown-packet-type.md b/hugo/content/components/classic/documentation/could-not-find-packetreader-for-packet-type-unknown-packet-type.md new file mode 100644 index 0000000000..ed4deceb0f --- /dev/null +++ b/hugo/content/components/classic/documentation/could-not-find-packetreader-for-packet-type-unknown-packet-type.md @@ -0,0 +1,18 @@ +--- +title: Could not find PacketReader for packet type - UNKNOWN PACKET TYPE +layout: classic-doc +--- + + + +### Error +``` +Could not find PacketReader for packet type: UNKNOWN PACKET TYPE: -102 +``` + +### Reason + +You are probably using different versions of ActiveMQ Classic jars on the client and the broker. Try using the same jars on each node and the problem should go away. + +Once 4.0 is GA we will be freezing the wire format version then increasing it for every future GA release - so the error message you get going forward should be more explicit + diff --git a/hugo/content/components/classic/documentation/cross-language-clients.md b/hugo/content/components/classic/documentation/cross-language-clients.md new file mode 100644 index 0000000000..c32ed9c48c --- /dev/null +++ b/hugo/content/components/classic/documentation/cross-language-clients.md @@ -0,0 +1,111 @@ +--- +title: Cross Language Clients +layout: classic-doc +--- + + + +Apache ActiveMQ Classic is a message broker written in Java with JMS, [REST](rest) and [WebSocket](websockets) interfaces, however it supports protocols like [AMQP](amqp), [MQTT](mqtt), [OpenWire](openwire) and [STOMP](stomp) that can be used by applications in different languages. + +Libraries +--------- + +* [.NET](http://activemq.apache.org/nms/) +* [C](http://docs.codehaus.org/display/STOMP/C) (defunct) +* [C++](http://activemq.apache.org/cms/) +* [Erlang](https://github.com/igb/Erlang-STOMP-Client) +* [Go](https://github.com/go-stomp/stomp) +* [Haskell](https://github.com/toschoo/mom) +* [Haxe](https://code.google.com/p/hxstomp) (defunct) +* [Jekejeke Prolog](https://github.com/fribeiro1/jekpro-activemq-library) +* [NetLogo](https://github.com/fribeiro1/ActiveMQ-Extension) +* [Node.js](https://github.com/gdaws/node-stomp) +* [Perl 5](http://search.cpan.org/%7Elcons/Net-STOMP-Client/) +* [Pike](https://github.com/hww3/pike_modules-public_protocols_stomp) +* [Python](https://github.com/jasonrbriggs/stomp.py) +* [Racket](https://github.com/tonyg/racket-stomp) +* [Ruby on Rails](https://github.com/kookster/activemessaging) +* [Tcl/Tk](https://github.com/siemens/tstomp) + +Code Samples +------------ + +Language|Variant|Interface|Protocol|Links +---|---|---|---|--- +Awk|Gawk|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/03/06/how-to-send-a-message-to-an-apache-activemq-queue-with-gawk/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/06/how-to-send-a-message-to-an-apache-activemq-topic-with-gawk/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/06/how-to-receive-a-message-from-an-apache-activemq-queue-with-gawk/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/06/how-to-receive-a-message-from-an-apache-activemq-topic-with-gawk/) +C/C++|None|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/02/23/how-to-send-a-message-to-an-apache-activemq-queue-with-cc/), [Send to Topic](https://simplesassim.wordpress.com/2014/02/23/how-to-send-a-message-to-an-apache-activemq-topic-with-cc/), [Receive from Queue](https://simplesassim.wordpress.com/2014/02/23/how-to-receive-a-message-from-an-apache-activemq-queue-with-cc/), [Receive from Topic](https://simplesassim.wordpress.com/2014/02/23/how-to-receive-a-message-from-an-apache-activemq-topic-with-cc/) +COBOL|GNU COBOL|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/04/15/how-to-send-a-message-to-an-apache-activemq-queue-with-gnu-cobol/), [Send to Topic](https://simplesassim.wordpress.com/2014/04/15/how-to-send-a-message-to-an-apache-activemq-topic-with-gnu-cobol/), [Receive from Queue](https://simplesassim.wordpress.com/2014/04/17/how-to-receive-a-message-from-an-apache-activemq-queue-with-gnu-cobol/), [Receive from Topic](https://simplesassim.wordpress.com/2014/04/17/how-to-receive-a-message-from-an-apache-activemq-topic-with-gnu-cobol/) +COBOL|Visual COBOL|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2013/11/12/how-to-send-a-message-to-an-apache-activemq-queue-with-visual-cobol/), [Send to Topic](https://simplesassim.wordpress.com/2013/11/12/how-to-send-a-message-to-an-apache-activemq-topic-with-visual-cobol/), [Receive from Queue](https://simplesassim.wordpress.com/2013/11/13/how-to-receive-a-message-from-an-apache-activemq-queue-with-visual-cobol/), [Receive from Topic](https://simplesassim.wordpress.com/2013/11/13/how-to-receive-a-message-from-an-apache-activemq-topic-with-visual-cobol/) +Ceylon|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2013/12/28/how-to-send-a-message-to-an-apache-activemq-queue-with-ceylon/), [Send to Topic](https://simplesassim.wordpress.com/2013/12/28/how-to-send-a-message-to-an-apache-activemq-topic-with-ceylon/), [Receive from Queue](https://simplesassim.wordpress.com/2013/12/28/how-to-receive-a-message-from-an-apache-activemq-queue-with-ceylon/), [Receive from Topic](https://simplesassim.wordpress.com/2013/12/28/how-to-receive-a-message-from-an-apache-activemq-topic-with-ceylon/) +Clojure|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2013/12/31/how-to-send-a-message-to-an-apache-activemq-queue-with-clojure/), [Send to Topic](https://simplesassim.wordpress.com/2013/12/31/how-to-send-a-message-to-an-apache-activemq-topic-with-clojure/), [Receive from Queue](https://simplesassim.wordpress.com/2013/12/31/how-to-receive-a-message-from-an-apache-activemq-queue-with-clojure/), [Receive from Topic](https://simplesassim.wordpress.com/2013/12/31/how-to-receive-a-message-from-an-apache-activemq-topic-with-clojure/) +D|None|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2015/12/02/how-to-send-a-message-to-an-apache-activemq-queue-with-d/), [Send to Topic](https://simplesassim.wordpress.com/2015/12/02/how-to-send-a-message-to-an-apache-activemq-topic-with-d/), [Receive from Queue](https://simplesassim.wordpress.com/2015/12/03/how-to-receive-a-message-from-an-apache-activemq-queue-with-d/), [Receive from Topic](https://simplesassim.wordpress.com/2015/12/03/how-to-receive-a-message-from-an-apache-activemq-topic-with-d/) +Dylan|Open Dylan|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2016/02/06/how-to-send-a-message-to-an-apache-activemq-queue-with-open-dylan/), [Send to Topic](https://simplesassim.wordpress.com/2016/02/06/how-to-send-a-message-to-an-apache-activemq-topic-with-open-dylan/), [Receive from Queue](https://simplesassim.wordpress.com/2016/02/06/how-to-receive-a-message-from-an-apache-activemq-queue-with-open-dylan/), [Receive from Topic](https://simplesassim.wordpress.com/2016/02/06/how-to-receive-a-message-from-an-apache-activemq-topic-with-open-dylan/) +Efene|None|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2016/01/11/how-to-send-a-message-to-an-apache-activemq-queue-with-efene/), [Send to Topic](https://simplesassim.wordpress.com/2016/01/11/how-to-send-a-message-to-an-apache-activemq-topic-with-efene/), [Receive from Queue](https://simplesassim.wordpress.com/2016/01/11/how-to-receive-a-message-from-an-apache-activemq-queue-with-efene/), [Receive from Topic](https://simplesassim.wordpress.com/2016/01/11/how-to-receive-a-message-from-an-apache-activemq-topic-with-efene/) +Eiffel|EiffelStudio|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2016/01/24/how-to-send-a-message-to-an-apache-activemq-queue-with-eiffelstudio/), [Send to Topic](https://simplesassim.wordpress.com/2016/01/24/how-to-send-a-message-to-an-apache-activemq-topic-with-eiffelstudio/), [Receive from Queue](https://simplesassim.wordpress.com/2016/01/24/how-to-receive-a-message-from-an-apache-activemq-queue-with-eiffelstudio/), [Receive from Topic](https://simplesassim.wordpress.com/2016/01/24/how-to-receive-a-message-from-an-apache-activemq-queue-with-eiffelstudio/) +Eiffel|GNU Eiffel|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2016/01/25/how-to-send-a-message-to-an-apache-activemq-queue-with-gnu-eiffel/), [Send to Topic](https://simplesassim.wordpress.com/2016/01/25/how-to-send-a-message-to-an-apache-activemq-topic-with-gnu-eiffel/), [Receive from Queue](https://simplesassim.wordpress.com/2016/01/25/how-to-receive-a-message-from-an-apache-activemq-queue-with-gnu-eiffel/), [Receive from Topic](https://simplesassim.wordpress.com/2016/01/25/how-to-receive-a-message-from-an-apache-activemq-topic-with-gnu-eiffel/) +Elixir|None|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/02/09/how-to-send-a-message-to-an-apache-activemq-queue-with-elixir/), [Send to Topic](https://simplesassim.wordpress.com/2014/02/09/how-to-send-a-message-to-an-apache-activemq-topic-with-elixir/), [Receive from Queue](https://simplesassim.wordpress.com/2014/02/09/how-to-receive-a-message-from-an-apache-activemq-queue-with-elixir/), [Receive from Topic](https://simplesassim.wordpress.com/2014/02/09/how-to-receive-a-message-from-an-apache-activemq-topic-with-elixir/) +Erlang|None|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/02/06/how-to-send-a-message-to-an-apache-activemq-queue-with-erlang/), [Send to Topic](https://simplesassim.wordpress.com/2014/02/06/how-to-send-a-message-to-an-apache-activemq-topic-with-erlang/), [Receive from Queue](https://simplesassim.wordpress.com/2014/02/07/how-to-receive-a-message-from-an-apache-activemq-queue-with-erlang/), [Receive from Topic](https://simplesassim.wordpress.com/2014/02/07/how-to-receive-a-message-from-an-apache-activemq-topic-with-erlang/) +Factor|None|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2015/12/13/how-to-send-a-message-to-an-apache-activemq-queue-with-factor/), [Send to Topic](https://simplesassim.wordpress.com/2015/12/13/how-to-send-a-message-to-an-apache-activemq-topic-with-factor/), [Receive from Queue](https://simplesassim.wordpress.com/2015/12/13/how-to-receive-a-message-from-an-apache-activemq-queue-with-factor/), [Receive from Topic](https://simplesassim.wordpress.com/2015/12/13/how-to-receive-a-message-from-an-apache-activemq-topic-with-factor/) +Fantom|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/01/11/how-to-send-a-message-to-an-apache-activemq-queue-with-fantom/), [Send to Topic](https://simplesassim.wordpress.com/2014/01/11/how-to-send-a-message-to-an-apache-activemq-topic-with-fantom/), [Receive from Queue](https://simplesassim.wordpress.com/2014/01/11/how-to-receive-a-message-from-an-apache-activemq-queue-with-fantom/), [Receive from Topic](https://simplesassim.wordpress.com/2014/01/11/how-to-receive-a-message-from-an-apache-activemq-topic-with-fantom/) +Frege|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2015/01/06/how-to-send-a-message-to-an-apache-activemq-queue-with-frege/), [Send to Topic](https://simplesassim.wordpress.com/2015/01/06/how-to-send-a-message-to-an-apache-activemq-topic-with-frege/), [Receive from Queue](https://simplesassim.wordpress.com/2015/01/06/how-to-receive-a-message-from-an-apache-activemq-queue-with-frege/), [Receive from Topic](https://simplesassim.wordpress.com/2015/01/06/how-to-receive-a-message-from-an-apache-activemq-topic-with-frege/) +Go|None|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/02/16/how-to-send-a-message-to-an-apache-activemq-queue-with-go/), [Send to Topic](https://simplesassim.wordpress.com/2014/02/16/how-to-send-a-message-to-an-apache-activemq-topic-with-go/), [Receive from Queue](https://simplesassim.wordpress.com/2014/02/16/how-to-receive-a-message-from-an-apache-activemq-queue-with-go/), [Receive from Topic](https://simplesassim.wordpress.com/2014/02/16/how-to-receive-a-message-from-an-apache-activemq-topic-with-go/) +Golo|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/01/10/how-to-send-a-message-to-an-apache-activemq-queue-with-golo/), [Send to Topic](https://simplesassim.wordpress.com/2014/01/10/how-to-send-a-message-to-an-apache-activemq-topic-with-golo/), [Receive from Queue](https://simplesassim.wordpress.com/2014/01/10/how-to-receive-a-message-from-an-apache-activemq-queue-with-golo/), [Receive from Topic](https://simplesassim.wordpress.com/2014/01/10/how-to-receive-a-message-from-an-apache-activemq-topic-with-golo/) +Gosu|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/12/31/how-to-send-a-message-to-an-apache-activemq-queue-with-gosu/), [Send to Topic](https://simplesassim.wordpress.com/2014/12/31/how-to-send-a-message-to-an-apache-activemq-topic-with-gosu/), [Receive from Queue](https://simplesassim.wordpress.com/2014/12/31/how-to-receive-a-message-from-an-apache-activemq-queue-with-gosu/), [Receive from Topic](https://simplesassim.wordpress.com/2014/12/31/how-to-receive-a-message-from-an-apache-activemq-topic-with-gosu/) +Groovy|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/01/01/how-to-send-a-message-to-an-apache-activemq-queue-with-groovy/), [Send to Topic](https://simplesassim.wordpress.com/2014/01/01/how-to-send-a-message-to-an-apache-activemq-topic-with-groovy/), [Receive from Queue](https://simplesassim.wordpress.com/2014/01/01/how-to-receive-a-message-from-an-apache-activemq-queue-with-groovy/), [Receive from Topic](https://simplesassim.wordpress.com/2014/01/01/how-to-receive-a-message-from-an-apache-activemq-topic-with-groovy/) +Haxe|None|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/03/12/how-to-send-a-message-to-an-apache-activemq-queue-with-haxe/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/12/how-to-send-a-message-to-an-apache-activemq-topic-with-haxe/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/12/how-to-receive-a-message-from-an-apache-activemq-queue-with-haxe/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/12/how-to-receive-a-message-from-an-apache-activemq-topic-with-haxe/) +Haskell|None|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/02/14/how-to-send-a-message-to-an-apache-activemq-queue-with-haskell/), [Send to Topic](https://simplesassim.wordpress.com/2014/02/14/how-to-send-a-message-to-an-apache-activemq-topic-with-haskell/), [Receive from Queue](https://simplesassim.wordpress.com/2014/02/14/how-to-receive-a-message-from-an-apache-activemq-queue-with-haskell/), [Receive from Topic](https://simplesassim.wordpress.com/2014/02/14/how-to-receive-a-message-from-an-apache-activemq-topic-with-haskell/) +Interfix|None|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2016/01/12/how-to-send-a-message-to-an-apache-activemq-queue-with-interfix/), [Send to Topic](https://simplesassim.wordpress.com/2016/01/12/how-to-send-a-message-to-an-apache-activemq-topic-with-interfix/), [Receive from Queue](https://simplesassim.wordpress.com/2016/01/12/how-to-receive-a-message-from-an-apache-activemq-queue-with-interfix/), [Receive from Topic](https://simplesassim.wordpress.com/2016/01/12/how-to-receive-a-message-from-an-apache-activemq-topic-with-interfix/) +Ioke|None|Library|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2015/12/10/how-to-send-a-message-to-an-apache-activemq-queue-with-ioke/), [Send to Topic](https://simplesassim.wordpress.com/2015/12/10/how-to-send-a-message-to-an-apache-activemq-topic-with-ioke/), [Receive from Queue](https://simplesassim.wordpress.com/2015/12/10/how-to-receive-a-message-from-an-apache-activemq-queue-with-ioke/), [Receive from Topic](https://simplesassim.wordpress.com/2015/12/10/how-to-receive-a-message-from-an-apache-activemq-topic-with-ioke/) +Java|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/02/19/how-to-send-a-message-to-an-apache-activemq-queue-with-java/), [Send to Topic](https://simplesassim.wordpress.com/2014/02/19/how-to-send-a-message-to-an-apache-activemq-topic-with-java/), [Receive from Queue](https://simplesassim.wordpress.com/2013/11/10/how-to-receive-a-message-from-an-apache-activemq-queue-with-java/), [Receive from Topic](https://simplesassim.wordpress.com/2013/11/10/how-to-receive-a-message-from-an-apache-activemq-topic-with-java/) +Java|Apache Camel|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/04/21/how-to-send-a-message-to-an-apache-activemq-queue-with-apache-camel/), [Send to Topic](https://simplesassim.wordpress.com/2014/04/21/how-to-send-a-message-to-an-apache-activemq-topic-with-apache-camel/), [Receive from Queue](https://simplesassim.wordpress.com/2014/04/21/how-to-receive-a-message-from-an-apache-activemq-queue-with-apache-camel/), [Receive from Topic](https://simplesassim.wordpress.com/2014/04/21/how-to-receive-a-message-from-an-apache-activemq-topic-with-apache-camel/) +Java|JAX-RS|REST|REST|[Send to Queue](https://simplesassim.wordpress.com/2013/11/07/how-to-send-a-message-to-an-apache-activemq-queue-with-jax-rs/), [Send to Topic](https://simplesassim.wordpress.com/2013/11/07/how-to-send-a-message-to-an-apache-activemq-topic-with-jax-rs/), [Receive from Queue](https://simplesassim.wordpress.com/2013/11/07/how-to-receive-a-message-from-an-apache-activemq-queue-with-jax-rs/), [Receive from Topic](https://simplesassim.wordpress.com/2013/11/07/how-to-receive-a-message-from-an-apache-activemq-topic-with-jax-rs/) +Java|Java API for WebSocket|WebSocket|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2016/01/23/how-to-send-a-message-to-an-apache-activemq-queue-with-the-java-api-for-websocket/), [Send to Topic](https://simplesassim.wordpress.com/2016/01/23/how-to-send-a-message-to-an-apache-activemq-topic-with-the-java-api-for-websocket/), [Receive from Queue](https://simplesassim.wordpress.com/2016/01/23/how-to-receive-a-message-from-an-apache-activemq-queue-with-the-java-api-for-websocket/), [Receive from Topic](https://simplesassim.wordpress.com/2016/01/23/how-to-receive-a-message-from-an-apache-activemq-topic-with-the-java-api-for-websocket/) +JavaScript|None|WebSocket|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2016/02/02/how-to-send-a-message-to-an-apache-activemq-queue-with-javascript/), [Send to Topic](https://simplesassim.wordpress.com/2016/02/02/how-to-send-a-message-to-an-apache-activemq-topic-with-javascript/), [Receive from Queue](https://simplesassim.wordpress.com/2016/02/02/how-to-receive-a-message-from-an-apache-activemq-queue-with-javascript/), [Receive from Topic](https://simplesassim.wordpress.com/2016/02/02/how-to-receive-a-message-from-an-apache-activemq-topic-with-javascript/) +JavaScript|DynJS|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/01/02/how-to-send-a-message-to-an-apache-activemq-queue-with-dynjs/), [Send to Topic](https://simplesassim.wordpress.com/2014/01/02/how-to-send-a-message-to-an-apache-activemq-topic-with-dynjs/), [Receive from Queue](https://simplesassim.wordpress.com/2014/01/02/how-to-receive-a-message-from-an-apache-activemq-queue-with-dynjs/), [Receive from Topic](https://simplesassim.wordpress.com/2014/01/02/how-to-receive-a-message-from-an-apache-activemq-topic-with-dynjs/) +JavaScript|Rhino|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2013/12/31/how-to-send-a-message-to-an-apache-activemq-queue-with-rhino/), [Send to Topic](https://simplesassim.wordpress.com/2013/12/31/how-to-send-a-message-to-an-apache-activemq-topic-with-rhino/), [Receive from Queue](https://simplesassim.wordpress.com/2013/12/31/how-to-receive-a-message-from-an-apache-activemq-queue-with-rhino/), [Receive from Topic](https://simplesassim.wordpress.com/2013/12/31/how-to-receive-a-message-from-an-apache-activemq-topic-with-rhino/) +JavaScript|Nashorn|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2013/12/31/how-to-send-a-message-to-an-apache-activemq-queue-with-nashorn/), [Send to Topic](https://simplesassim.wordpress.com/2013/12/31/how-to-send-a-message-to-an-apache-activemq-topic-with-nashorn/), [Receive from Queue](https://simplesassim.wordpress.com/2013/12/31/how-to-receive-a-message-from-an-apache-activemq-queue-with-nashorn/), [Receive from Topic](https://simplesassim.wordpress.com/2013/12/31/how-to-receive-a-message-from-an-apache-activemq-topic-with-nashorn/) +JavaScript|Node.js|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2016/03/13/how-to-send-a-message-to-an-apache-activemq-queue-with-node-js/), [Send to Topic](https://simplesassim.wordpress.com/2016/03/13/how-to-send-a-message-to-an-apache-activemq-topic-with-node-js/), [Receive from Queue](https://simplesassim.wordpress.com/2016/03/13/how-to-receive-a-message-from-an-apache-activemq-queue-with-node-js/), [Receive from Topic](https://simplesassim.wordpress.com/2016/03/13/how-to-receive-a-message-from-an-apache-activemq-topic-with-node-js/) +JudoScript|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2015/01/10/how-to-send-a-message-to-an-apache-activemq-queue-with-judoscript/), [Send to Topic](https://simplesassim.wordpress.com/2015/01/10/how-to-send-a-message-to-an-apache-activemq-topic-with-judoscript/), [Receive from Queue](https://simplesassim.wordpress.com/2015/01/10/how-to-receive-a-message-from-an-apache-activemq-queue-with-judoscript/), [Receive from Topic](https://simplesassim.wordpress.com/2015/01/10/how-to-receive-a-message-from-an-apache-activemq-topic-with-judoscript/) +Julia|None|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2016/01/02/how-to-send-a-message-to-an-apache-activemq-queue-with-julia/), [Send to Topic](https://simplesassim.wordpress.com/2016/01/02/how-to-send-a-message-to-an-apache-activemq-topic-with-julia/), [Receive from Queue](https://simplesassim.wordpress.com/2016/01/02/how-to-receive-a-message-from-an-apache-activemq-queue-with-julia/), [Receive from Topic](https://simplesassim.wordpress.com/2016/01/02/how-to-receive-a-message-from-an-apache-activemq-topic-with-julia/) +Kotlin|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/01/10/how-to-send-a-message-to-an-apache-activemq-queue-with-kotlin/), [Send to Topic](https://simplesassim.wordpress.com/2014/01/10/how-to-send-a-message-to-an-apache-activemq-topic-with-kotlin/), [Receive from Queue](https://simplesassim.wordpress.com/2014/01/10/how-to-receive-a-message-from-an-apache-activemq-queue-with-kotlin/), [Receive from Topic](https://simplesassim.wordpress.com/2014/01/10/how-to-receive-a-message-from-an-apache-activemq-topic-with-kotlin/) +Lisp/Scheme|ABCL|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/04/02/how-to-send-a-message-to-an-apache-activemq-queue-with-abcl/), [Send to Topic](https://simplesassim.wordpress.com/2014/04/02/how-to-send-a-message-to-an-apache-activemq-topic-with-abcl/), [Receive from Queue](https://simplesassim.wordpress.com/2014/04/02/how-to-receive-a-message-from-an-apache-activemq-queue-with-abcl/), [Receive from Topic](https://simplesassim.wordpress.com/2014/04/02/how-to-receive-a-message-from-an-apache-activemq-topic-with-abcl/) +Lisp/Scheme|Allegro CL|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/04/05/how-to-send-a-message-to-an-apache-activemq-queue-with-allegro-cl/), [Send to Topic](https://simplesassim.wordpress.com/2014/04/05/how-to-send-a-message-to-an-apache-activemq-topic-with-allegro-cl/), [Receive from Queue](https://simplesassim.wordpress.com/2014/04/05/how-to-receive-a-message-from-an-apache-activemq-queue-with-allegro-cl/), [Receive from Topic](https://simplesassim.wordpress.com/2014/04/05/how-to-receive-a-message-from-an-apache-activemq-topic-with-allegro-cl/) +Lisp/Scheme|Bigloo|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/04/02/how-to-send-a-message-to-an-apache-activemq-queue-with-bigloo/), [Send to Topic](https://simplesassim.wordpress.com/2014/04/02/how-to-send-a-message-to-an-apache-activemq-topic-with-bigloo/), [Receive from Queue](https://simplesassim.wordpress.com/2014/04/02/how-to-receive-a-message-from-an-apache-activemq-queue-with-bigloo/), [Receive from Topic](https://simplesassim.wordpress.com/2014/04/02/how-to-receive-a-message-from-an-apache-activemq-topic-with-bigloo/) +Lisp/Scheme|GNU CLISP|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/03/17/how-to-send-a-message-to-an-apache-activemq-queue-with-gnu-clisp/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/17/how-to-send-a-message-to-an-apache-activemq-topic-with-gnu-clisp/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/17/how-to-receive-a-message-from-an-apache-activemq-queue-with-gnu-clisp/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/17/how-to-receive-a-message-from-an-apache-activemq-topic-with-gnu-clisp/) +Lisp/Scheme|JScheme|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/03/30/how-to-send-a-message-to-an-apache-activemq-queue-with-jscheme/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/30/how-to-send-a-message-to-an-apache-activemq-topic-with-jscheme/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/30/how-to-receive-a-message-from-an-apache-activemq-queue-with-jscheme/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/30/how-to-receive-a-message-from-an-apache-activemq-topic-with-jscheme/) +Lisp/Scheme|Joxa|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/02/11/how-to-send-a-message-to-an-apache-activemq-queue-with-joxa/), [Send to Topic](https://simplesassim.wordpress.com/2014/02/11/how-to-send-a-message-to-an-apache-activemq-topic-with-joxa/), [Receive from Queue](https://simplesassim.wordpress.com/2014/02/11/how-to-receive-a-message-from-an-apache-activemq-queue-with-joxa/), [Receive from Topic](https://simplesassim.wordpress.com/2014/02/11/how-to-receive-a-message-from-an-apache-activemq-topic-with-joxa/) +Lisp/Scheme|Kawa|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/03/17/how-to-send-a-message-to-an-apache-activemq-queue-with-kawa/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/17/how-to-send-a-message-to-an-apache-activemq-topic-with-kawa/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/17/how-to-receive-a-message-from-an-apache-activemq-queue-with-kawa/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/17/how-to-receive-a-message-from-an-apache-activemq-topic-with-kawa/) +Lisp/Scheme|LFE|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/02/11/how-to-send-a-message-to-an-apache-activemq-queue-with-lfe/), [Send to Topic](https://simplesassim.wordpress.com/2014/02/11/how-to-send-a-message-to-an-apache-activemq-topic-with-lfe/), [Receive from Queue](https://simplesassim.wordpress.com/2014/02/11/how-to-receive-a-message-from-an-apache-activemq-queue-with-lfe/), [Receive from Topic](https://simplesassim.wordpress.com/2014/02/11/how-to-receive-a-message-from-an-apache-activemq-topic-with-lfe/) +Lisp/Scheme|MIT/GNU Scheme|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/03/24/how-to-send-a-message-to-an-apache-activemq-queue-with-mitgnu-scheme/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/24/how-to-send-a-message-to-an-apache-activemq-topic-with-mitgnu-scheme/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/25/how-to-receive-a-message-from-an-apache-activemq-queue-with-mitgnu-scheme/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/25/how-to-receive-a-message-from-an-apache-activemq-topic-with-mitgnu-scheme/) +Lisp/Scheme|Racket|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/03/29/how-to-send-a-message-to-an-apache-activemq-queue-with-racket/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/29/how-to-send-a-message-to-an-apache-activemq-topic-with-racket/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/29/how-to-receive-a-message-from-an-apache-activemq-queue-with-racket/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/29/how-to-receive-a-message-from-an-apache-activemq-topic-with-racket/) +Lisp/Scheme|SISC|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/04/06/how-to-send-a-message-to-an-apache-activemq-queue-with-sisc/), [Send to Topic](https://simplesassim.wordpress.com/2014/04/06/how-to-send-a-message-to-an-apache-activemq-topic-with-sisc/), [Receive from Queue](https://simplesassim.wordpress.com/2014/04/06/how-to-receive-a-message-from-an-apache-activemq-queue-with-sisc/), [Receive from Topic](https://simplesassim.wordpress.com/2014/04/06/how-to-receive-a-message-from-an-apache-activemq-topic-with-sisc/) +Logo|NetLogo|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2015/12/06/how-to-send-a-message-to-an-apache-activemq-queue-with-netlogo/), [Send to Topic](https://simplesassim.wordpress.com/2015/12/06/how-to-send-a-message-to-an-apache-activemq-topic-with-netlogo/), [Receive from Queue](https://simplesassim.wordpress.com/2015/12/06/how-to-receive-a-message-from-an-apache-activemq-queue-with-netlogo/), [Receive from Topic](https://simplesassim.wordpress.com/2015/12/06/how-to-receive-a-message-from-an-apache-activemq-topic-with-netlogo/) +Lua|Lua|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/03/13/how-to-send-a-message-to-an-apache-activemq-queue-with-lua/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/13/how-to-send-a-message-to-an-apache-activemq-topic-with-lua/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/13/how-to-receive-a-message-from-an-apache-activemq-queue-with-lua/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/13/how-to-receive-a-message-from-an-apache-activemq-topic-with-lua/) +Lua|Luaj|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2015/01/25/how-to-send-a-message-to-an-apache-activemq-queue-with-luaj/), [Send to Topic](https://simplesassim.wordpress.com/2015/01/25/how-to-send-a-message-to-an-apache-activemq-topic-with-luaj/), [Receive from Queue](https://simplesassim.wordpress.com/2015/01/25/how-to-receive-a-message-from-an-apache-activemq-queue-with-luaj/), [Receive from Topic](https://simplesassim.wordpress.com/2015/01/25/how-to-receive-a-message-from-an-apache-activemq-topic-with-luaj/) +ML|OCaml|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2015/02/21/how-to-send-a-message-to-an-apache-activemq-queue-with-ocaml/), [Send to Topic](https://simplesassim.wordpress.com/2015/02/22/how-to-send-a-message-to-an-apache-activemq-topic-with-ocaml/), [Receive from Queue](https://simplesassim.wordpress.com/2015/02/22/how-to-receive-a-message-from-an-apache-activemq-queue-with-ocaml/), [Receive from Topic](https://simplesassim.wordpress.com/2015/02/22/how-to-receive-a-message-from-an-apache-activemq-topic-with-ocaml/) +ML|OCaml-Java|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2015/02/15/how-to-send-a-message-to-an-apache-activemq-queue-with-ocaml-java/), [Send to Topic](https://simplesassim.wordpress.com/2015/02/15/how-to-send-a-message-to-an-apache-activemq-topic-with-ocaml-java/), [Receive from Queue](https://simplesassim.wordpress.com/2015/02/15/how-to-receive-a-message-from-an-apache-activemq-queue-with-ocaml-java/), [Receive from Topic](https://simplesassim.wordpress.com/2015/02/15/how-to-receive-a-message-from-an-apache-activemq-topic-with-ocaml-java/) +Mirah|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/12/30/how-to-send-a-message-to-an-apache-activemq-queue-with-mirah/), [Send to Topic](https://simplesassim.wordpress.com/2014/12/30/how-to-send-a-message-to-an-apache-activemq-topic-with-mirah/), [Receive from Queue](https://simplesassim.wordpress.com/2014/12/30/how-to-receive-a-message-from-an-apache-activemq-queue-with-mirah/), [Receive from Topic](https://simplesassim.wordpress.com/2014/12/30/how-to-receive-a-message-from-an-apache-activemq-topic-with-mirah/) +Perl|Perl 5|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/03/08/how-to-send-a-message-to-an-apache-activemq-queue-with-perl-5/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/08/how-to-send-a-message-to-an-apache-activemq-topic-with-perl-5/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/08/how-to-receive-a-message-from-an-apache-activemq-queue-with-perl-5/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/08/how-to-receive-a-message-from-an-apache-activemq-topic-with-perl-5/) +Pike|None|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/03/16/how-to-send-a-message-to-an-apache-activemq-queue-with-pike/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/16/how-to-send-a-message-to-an-apache-activemq-topic-with-pike/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/16/how-to-receive-a-message-from-an-apache-activemq-queue-with-pike/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/16/how-to-receive-a-message-from-an-apache-activemq-topic-with-pike/) +Prolog|JIProlog|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2015/01/14/how-to-send-a-message-to-an-apache-activemq-queue-with-jiprolog/), [Send to Topic](https://simplesassim.wordpress.com/2015/01/14/how-to-send-a-message-to-an-apache-activemq-topic-with-jiprolog/), [Receive from Queue](https://simplesassim.wordpress.com/2015/01/14/how-to-receive-a-message-from-an-apache-activemq-queue-with-jiprolog/), [Receive from Topic](https://simplesassim.wordpress.com/2015/01/14/how-to-receive-a-message-from-an-apache-activemq-topic-with-jiprolog/) +Prolog|Jekejeke Prolog|Library|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2015/01/26/how-to-send-a-message-to-an-apache-activemq-queue-with-jekejeke-prolog/), [Send to Topic](https://simplesassim.wordpress.com/2015/01/26/how-to-send-a-message-to-an-apache-activemq-topic-with-jekejeke-prolog/), [Receive from Queue](https://simplesassim.wordpress.com/2015/01/26/how-to-receive-a-message-from-an-apache-activemq-queue-with-jekejeke-prolog/), [Receive from Topic](https://simplesassim.wordpress.com/2015/01/26/how-to-receive-a-message-from-an-apache-activemq-topic-with-jekejeke-prolog/) +Prolog|tuProlog|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2015/01/21/how-to-send-a-message-to-an-apache-activemq-queue-with-tuprolog/), [Send to Topic](https://simplesassim.wordpress.com/2015/01/21/how-to-send-a-message-to-an-apache-activemq-topic-with-tuprolog/), [Receive from Queue](https://simplesassim.wordpress.com/2015/01/21/how-to-receive-a-message-from-an-apache-activemq-queue-with-tuprolog/), [Receive from Topic](https://simplesassim.wordpress.com/2015/01/21/how-to-receive-a-message-from-an-apache-activemq-topic-with-tuprolog/) +Python|None|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/03/14/how-to-send-a-message-to-an-apache-activemq-queue-with-python/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/14/how-to-send-a-message-to-an-apache-activemq-topic-with-python/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/14/how-to-receive-a-message-from-an-apache-activemq-queue-with-python/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/14/how-to-receive-a-message-from-an-apache-activemq-topic-with-python/) +Python|Jython|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2013/12/30/how-to-send-a-message-to-an-apache-activemq-queue-with-jython/), [Send to Topic](https://simplesassim.wordpress.com/2013/12/30/how-to-send-a-message-to-an-apache-activemq-topic-with-jython/), [Receive from Queue](https://simplesassim.wordpress.com/2013/12/30/how-to-receive-a-message-from-an-apache-activemq-queue-with-jython/), [Receive from Topic](https://simplesassim.wordpress.com/2013/12/30/how-to-receive-a-message-from-an-apache-activemq-topic-with-jython/) +R|GNU R|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/03/19/how-to-send-a-message-to-an-apache-activemq-queue-with-gnu-r/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/19/how-to-send-a-message-to-an-apache-activemq-topic-with-gnu-r/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/19/how-to-receive-a-message-from-an-apache-activemq-queue-with-gnu-r/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/19/how-to-receive-a-message-from-an-apache-activemq-topic-with-gnu-r/) +R|Renjin|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/12/31/how-to-send-a-message-to-an-apache-activemq-queue-with-renjin/), [Send to Topic](https://simplesassim.wordpress.com/2014/12/31/how-to-send-a-message-to-an-apache-activemq-topic-with-renjin/), [Receive from Queue](https://simplesassim.wordpress.com/2014/12/31/how-to-receive-a-message-from-an-apache-activemq-queue-with-renjin/), [Receive from Topic](https://simplesassim.wordpress.com/2014/12/31/how-to-receive-a-message-from-an-apache-activemq-topic-with-renjin/) +Rebol|None|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2015/11/28/how-to-send-a-message-to-an-apache-activemq-queue-with-rebol/), [Send to Topic](https://simplesassim.wordpress.com/2015/11/28/how-to-send-a-message-to-an-apache-activemq-topic-with-rebol/), [Receive from Queue](https://simplesassim.wordpress.com/2015/11/28/how-to-receive-a-message-from-an-apache-activemq-queue-with-rebol/), [Receive from Topic](https://simplesassim.wordpress.com/2015/11/28/how-to-receive-a-message-from-an-apache-activemq-topic-with-rebol/) +Rexx|BSF4ooRexx|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/08/21/how-to-send-a-message-to-an-apache-activemq-queue-with-bsf4oorexx/), [Send to Topic](https://simplesassim.wordpress.com/2014/08/21/how-to-send-a-message-to-an-apache-activemq-topic-with-bsf4oorexx/), [Receive from Queue](https://simplesassim.wordpress.com/2014/08/22/how-to-receive-a-message-from-an-apache-activemq-queue-with-bsf4oorexx/), [Receive from Topic](https://simplesassim.wordpress.com/2014/08/22/how-to-receive-a-message-from-an-apache-activemq-topic-with-bsf4oorexx/) +Rexx|NetRexx|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/08/17/how-to-send-a-message-to-an-apache-activemq-queue-with-netrexx/), [Send to Topic](https://simplesassim.wordpress.com/2014/08/17/how-to-send-a-message-to-an-apache-activemq-topic-with-netrexx/), [Receive from Queue](https://simplesassim.wordpress.com/2014/08/17/how-to-receive-a-message-from-an-apache-activemq-queue-with-netrexx/), [Receive from Topic](https://simplesassim.wordpress.com/2014/08/17/how-to-receive-a-message-from-an-apache-activemq-topic-with-netrexx/) +Rexx|ooRexx|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/08/21/how-to-send-a-message-to-an-apache-activemq-queue-with-oorexx/), [Send to Topic](https://simplesassim.wordpress.com/2014/08/21/how-to-send-a-message-to-an-apache-activemq-topic-with-oorexx/), [Receive from Queue](https://simplesassim.wordpress.com/2014/08/21/how-to-receive-a-message-from-an-apache-activemq-queue-with-oorexx/), [Receive from Topic](https://simplesassim.wordpress.com/2014/08/21/how-to-receive-a-message-from-an-apache-activemq-topic-with-oorexx/) +Ruby|None|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/02/02/how-to-send-a-message-to-an-apache-activemq-queue-with-ruby/), [Send to Topic](https://simplesassim.wordpress.com/2014/02/03/how-to-send-a-message-to-an-apache-activemq-topic-with-ruby/), [Receive from Queue](https://simplesassim.wordpress.com/2014/02/03/how-to-receive-a-message-from-an-apache-activemq-queue-with-ruby/), [Receive from Topic](https://simplesassim.wordpress.com/2014/02/03/how-to-receive-a-message-from-an-apache-activemq-topic-with-ruby/) +Ruby|Ruby on Rails|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/01/27/how-to-send-a-message-to-an-apache-activemq-queue-with-ruby-on-rails/), [Send to Topic](https://simplesassim.wordpress.com/2014/01/27/how-to-send-a-message-to-an-apache-activemq-topic-with-ruby-on-rails/), [Receive from Queue](https://simplesassim.wordpress.com/2014/01/27/how-to-receive-a-message-from-an-apache-activemq-queue-with-ruby-on-rails/), [Receive from Topic](https://simplesassim.wordpress.com/2014/01/27/how-to-receive-a-message-from-an-apache-activemq-topic-with-ruby-on-rails/) +Ruby|JRuby|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2013/12/30/how-to-send-a-message-to-an-apache-activemq-queue-with-jruby/), [Send to Topic](https://simplesassim.wordpress.com/2013/12/30/how-to-send-a-message-to-an-apache-activemq-topic-with-jruby/), [Receive from Queue](https://simplesassim.wordpress.com/2013/12/30/how-to-receive-a-message-from-an-apache-activemq-queue-with-jruby/), [Receive from Topic](https://simplesassim.wordpress.com/2013/12/30/how-to-receive-a-message-from-an-apache-activemq-topic-with-jruby/) +Rust|None|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2015/01/16/how-to-send-a-message-to-an-apache-activemq-queue-with-rust/), [Send to Topic](https://simplesassim.wordpress.com/2015/01/16/how-to-send-a-message-to-an-apache-activemq-topic-with-rust/), [Receive from Queue](https://simplesassim.wordpress.com/2015/01/16/how-to-receive-a-message-from-an-apache-activemq-queue-with-rust/), [Receive from Topic](https://simplesassim.wordpress.com/2015/01/16/how-to-receive-a-message-from-an-apache-activemq-topic-with-rust/) +Scala|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2013/12/31/how-to-send-a-message-to-an-apache-activemq-queue-with-scala/), [Send to Topic](https://simplesassim.wordpress.com/2013/12/31/how-to-send-a-message-to-an-apache-activemq-topic-with-scala/), [Receive from Queue](https://simplesassim.wordpress.com/2013/12/31/how-to-receive-a-message-from-an-apache-activemq-queue-with-scala/), [Receive from Topic](https://simplesassim.wordpress.com/2013/12/31/how-to-receive-a-message-from-an-apache-activemq-topic-with-scala/) +Smalltalk|GNU Smalltalk|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/03/28/how-to-send-a-message-to-an-apache-activemq-queue-with-gnu-smalltalk/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/28/how-to-send-a-message-to-an-apache-activemq-topic-with-gnu-smalltalk/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/28/how-to-receive-a-message-from-an-apache-activemq-queue-with-gnu-smalltalk/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/28/how-to-receive-a-message-from-an-apache-activemq-topic-with-gnu-smalltalk/) +Smalltalk|Squeak|Sockets|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/03/30/how-to-send-a-message-to-an-apache-activemq-queue-with-squeak/), [Send to Topic](https://simplesassim.wordpress.com/2014/03/30/how-to-send-a-message-to-an-apache-activemq-topic-with-squeak/), [Receive from Queue](https://simplesassim.wordpress.com/2014/03/30/how-to-receive-a-message-from-an-apache-activemq-queue-with-squeak/), [Receive from Topic](https://simplesassim.wordpress.com/2014/03/30/how-to-receive-a-message-from-an-apache-activemq-topic-with-squeak/) +Tcl|Tcl/Tk|Library|STOMP|[Send to Queue](https://simplesassim.wordpress.com/2014/02/27/how-to-send-a-message-to-an-apache-activemq-queue-with-tcltk/), [Send to Topic](https://simplesassim.wordpress.com/2014/02/27/how-to-send-a-message-to-an-apache-activemq-topic-with-tcltk/), [Receive from Queue](https://simplesassim.wordpress.com/2014/02/27/how-to-receive-a-message-from-an-apache-activemq-queue-with-tcltk/), [Receive from Topic](https://simplesassim.wordpress.com/2014/02/27/how-to-receive-a-message-from-an-apache-activemq-topic-with-tcltk/) +Tcl|Tcl/Java|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/08/24/how-to-send-a-message-to-an-apache-activemq-queue-with-tcljava/), [Send to Topic](https://simplesassim.wordpress.com/2014/08/24/how-to-send-a-message-to-an-apache-activemq-topic-with-tcljava/), [Receive from Queue](https://simplesassim.wordpress.com/2014/08/24/how-to-receive-a-message-from-an-apache-activemq-queue-with-tcljava/), [Receive from Topic](https://simplesassim.wordpress.com/2014/08/24/how-to-receive-a-message-from-an-apache-activemq-topic-with-tcljava/) +Xtend|None|JMS|OpenWire|[Send to Queue](https://simplesassim.wordpress.com/2014/01/01/how-to-send-a-message-to-an-apache-activemq-queue-with-xtend/), [Send to Topic](https://simplesassim.wordpress.com/2014/01/01/how-to-send-a-message-to-an-apache-activemq-topic-with-xtend/), [Receive from Queue](https://simplesassim.wordpress.com/2014/01/01/how-to-receive-a-message-from-an-apache-activemq-queue-with-xtend/), [Receive from Topic](https://simplesassim.wordpress.com/2014/01/01/how-to-receive-a-message-from-an-apache-activemq-topic-with-xtend/) + diff --git a/hugo/content/components/classic/documentation/delay-and-schedule-message-delivery.md b/hugo/content/components/classic/documentation/delay-and-schedule-message-delivery.md new file mode 100644 index 0000000000..da9c73223e --- /dev/null +++ b/hugo/content/components/classic/documentation/delay-and-schedule-message-delivery.md @@ -0,0 +1,58 @@ +--- +title: Delay and Schedule Message Delivery +layout: classic-doc +--- + +ActiveMQ Classic from version **5.4** has an optional persistent scheduler built into the ActiveMQ Classic message broker. It is enabled by setting the broker **schedulerSupport** attribute to true in the [Xml Configuration](xml-configuration). +An ActiveMQ Classic client can take advantage of a delayed delivery by using the following message properties: + +> **Check your Message Properties** +> +> The message property `scheduledJobId `is reserved for use by the Job Scheduler. If this property is set before sending, the message will be sent immediately and not scheduled. Also, after a scheduled message is received, the property `scheduledJobId` will be set on the received message so keep this in mind if using something like a Camel Route which might automatically copy properties over when re-sending a message. + +Property name|type|description +---|---|--- +AMQ_SCHEDULED_DELAY|long|The time in milliseconds that a message will wait before being scheduled to be delivered by the broker +AMQ_SCHEDULED_PERIOD|long|The time in milliseconds to wait after the start time to wait before scheduling the message again +AMQ_SCHEDULED_REPEAT|int|The number of times to repeat scheduling a message for delivery +AMQ_SCHEDULED_CRON|String|Use a Cron entry to set the schedule + +For the connivence of Java JMS clients - there's an interface with the property names used for scheduling at _**org.apache.activemq.ScheduledMessage**_. + +For example, to have a message scheduled for delivery in 60 seconds - you would need to set the _AMQ_SCHEDULED_DELAY_ property: +```java +MessageProducer producer = session.createProducer(destination); +TextMessage message = session.createTextMessage("test msg"); +long time = 60 * 1000; +message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time); +producer.send(message); +``` +You can set a message to wait with an initial delay, and the repeat delivery 10 times, waiting 10 seconds between each re-delivery: +```java +MessageProducer producer = session.createProducer(destination); +TextMessage message = session.createTextMessage("test msg"); +long delay = 30 * 1000; +long period = 10 * 1000; +int repeat = 9; +message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay); +message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period); +message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat); +producer.send(message); +``` +You can also use [CRON](http://en.wikipedia.org/wiki/Cron) to schedule a message, for example, if you want a message scheduled to be delivered every hour, you would need to set the CRON entry to be - `0 * * * *` - e.g. +```java +MessageProducer producer = session.createProducer(destination); +TextMessage message = session.createTextMessage("test msg"); +message.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON, "0 * * * *"); +producer.send(message); +``` +CRON scheduling takes priority over using message delay - however, if a repeat and period is set with a CRON entry, the ActiveMQ Classic scheduler will schedule delivery of the message for every time the CRON entry fires. Easier to explain with an example. Supposing that you want a message to be delivered 10 times, with a one second delay between each message - and you wanted this to happen every hour - you'd do this: +```java +MessageProducer producer = session.createProducer(destination); +TextMessage message = session.createTextMessage("test msg"); +message.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON, "0 * * * *"); +message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 1000); +message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, 1000); +message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, 9); +producer.send(message); +``` \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/delphi-and-freepascal.md b/hugo/content/components/classic/documentation/delphi-and-freepascal.md new file mode 100644 index 0000000000..8a82e691cd --- /dev/null +++ b/hugo/content/components/classic/documentation/delphi-and-freepascal.md @@ -0,0 +1,28 @@ +--- +title: Delphi and FreePascal +layout: classic-doc +--- + + + +Delphi and FreePascal Client +============================ + +Habari ActiveMQ Classic Client is a library for Delphi(tm) and Free Pascal. With Habari, applications can connect to Apache ActiveMQ Classic servers, subscribe to queues and topics, send and receive messages and objects, and work with transactions. + +### Supported Communication Libraries + +* Internet Direct (Indy) 10.2 +* Synapse +* OverByte ICS V6 (limited feature set) +* TClientSocket (limited feature set) + +### Project Status + +Habari ActiveMQ Classic Client 1.0 has been released on March 5, 2008. Demo applications, API documentation and source code examples are available for download. +The API documentation is available at [http://www.mikejustin.com/habaridocs.md/index.html](http://www.mikejustin.com/habaridocs.md/index.html) + +### Project Home Page + +[http://www.mikejustin.com/](http://www.mikejustin.com/) + diff --git a/hugo/content/components/classic/documentation/design-documents.md b/hugo/content/components/classic/documentation/design-documents.md new file mode 100644 index 0000000000..57e52395e6 --- /dev/null +++ b/hugo/content/components/classic/documentation/design-documents.md @@ -0,0 +1,15 @@ +--- +title: Design Documents +layout: classic-doc +--- + + + +* [Slow Consumers](slow-consumers) +* [Durable Queue Memory Management](durable-queue-memory-management) +* [Supporting IO Streams](supporting-io-streams) +* [Message Redelivery and DLQ Handling](message-redelivery-and-dlq-handling) +* [Multicast Transport](multicast-transport) +* [Proposed C Client Architecture](proposed-c-client-architecture) +* [REST protocols](rest-protocols) + diff --git a/hugo/content/components/classic/documentation/developer-guide.md b/hugo/content/components/classic/documentation/developer-guide.md new file mode 100644 index 0000000000..b7ed03f4d6 --- /dev/null +++ b/hugo/content/components/classic/documentation/developer-guide.md @@ -0,0 +1,22 @@ +--- +title: Developer Guide +layout: classic-doc +--- + + + +The following documents might be interesting + +* [Building](building) +* [Release Plans](release-plans) +* [Release Guide](release-guide) +* [Design Documents](design-documents) +* [Changes in 4.0](New Features/changes-in-40) +* [Maven SNAPSHOT Repository in your POM](maven-snapshot-repository-in-your-pom) + +### Code walkthrough + +* [Code Overview](code-overview) +* [Wire Protocol](wire-protocol) +* [Developing Plugins](developing-plugins) + diff --git a/hugo/content/components/classic/documentation/developers.md b/hugo/content/components/classic/documentation/developers.md new file mode 100644 index 0000000000..ecae7a995d --- /dev/null +++ b/hugo/content/components/classic/documentation/developers.md @@ -0,0 +1,23 @@ +--- +title: Developers +layout: classic-doc +--- + +- [Becoming a committer](https://infra.apache.org/new-committers-guide.html) +- [Building](../building) +- [Source](../source) +- [GIT](../git) +- [Code Overview](../code-overview) +- [Developer Guide](../developer-guide) + - [Design Documents](../design-documents) + - [Developing Plugins](../developing-plugins) + - [Release Plans](../release-plans) +- [Release Guide](../release-guide) +- [Integration Tests](../integration-tests) +- [JMeter Performance Tests](../jmeter-performance-tests) +- [JMeter System Tests](../jmeter-system-tests) +- [JUnit Reports](../junit-reports) +- [Source XRef](../source-xref) +- [Test Source XRef](../test-source-xref) +- [Wire Protocol](../wire-protocol) +- [Sandbox](../sandbox) diff --git a/hugo/content/components/classic/documentation/developing-plugins.md b/hugo/content/components/classic/documentation/developing-plugins.md new file mode 100644 index 0000000000..c516b8ec11 --- /dev/null +++ b/hugo/content/components/classic/documentation/developing-plugins.md @@ -0,0 +1,70 @@ +--- +title: Developing Plugins +layout: classic-doc +--- + + + +Apache ActiveMQ Classic is based on the model of POJOs and _Dependency Injection_. If you are developing [Interceptors](interceptors) or additional components or plugins for ActiveMQ Classic then the first thing you should do is develop the code as if you are writing any other Spring component, using dependency injection. + +### Dependency Injection + +Some folks favour using constructor based injection as it removes the need to have a separate lifecycle _start()_ method - others find using property based injection is a little more flexible and easier to map to XML configuration files. We'll leave that choice up to you. For complex to create objects you could consider writing a FactoryBean. For more details on writing POJOs with Spring see their [documentation](http://www.springframework.org/documentation). + +### Custom XML + +With ActiveMQ Classic you can use regular Spring.xml syntax to configure things. However to produce neater XML that is easier to read and edit we use [XBean](http://geronimo.apache.org/xbean/) to autogenerate support for [Custom XML](http://geronimo.apache.org/xbean/custom-xml.html). + +If you wish your POJO to have its own custom XML you may wish to follow the following source examples for working nicely with XBean. Basically you add an XBean annotation in the javadoc comments to tell XBean how to map the POJO to custom XML. This should look something like +``` +/** + * @org.apache.xbean.XBean element="foo" + */ +public class MyExtension { +... +} +``` +You can omit the element configuration. For more details on the available annotation options see [here](http://geronimo.apache.org/xbean/xbean-ant-task.html) + +If you are submitting your plugin to the ActiveMQ Classic project then it will end up being included in the maven build step to create the XBean artifacts as part of the jar (in the META-INF/services area). + +However if you are writing an external plugin to ActiveMQ Classic then you will need to add the maven-xbean-plugin to your Maven 2 build. Refer to the [activemq-spring/pom.xml](https://github.com/apache/activemq/tree/main/activemq-spring/pom.xml) as an example of using this plugin. + +### Configuring plugins without custom XML + +If you want to configure plugins that does not implement custom XML, you can define plugins as "regular" Spring beans and reference them in broker's `plugins` attribute. For example, +``` + + ... + + + +``` +Not that this mechanism will not work in case that you have some XBean plugins configured inside the `` tag. In that case you must define the plugin inside that tag as well (with the appropriate schema definition). For example, +``` + + + + + + + + + + +``` +### Examples + +The easiest way to get a feel for how to extend ActiveMQ Classic is maybe to look at some concrete examples of features and how those are implemented and configured. Here are some examples + +* [XBeanBrokerService](https://github.com/apache/activemq/tree/main/activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerService.java) deals with most of the core configuration of the tag in the XML +* [Security](security) has an [example](http://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/org/apache/activemq/security/jaas-broker.xml) XML configuration file using the [AuthorizationPlugin](http://svn.apache.org/repos/asf/activemq/trunk/activemq-broker/src/main/java/org/apache/activemq/security/AuthorizationPlugin.java) +* The [Discarding DLQ Plugin](Design Documents/message-redelivery-and-dlq-handling) is used to discard messages from the DLQ. + diff --git a/hugo/content/components/classic/documentation/discovery.md b/hugo/content/components/classic/documentation/discovery.md new file mode 100644 index 0000000000..db0a993ecc --- /dev/null +++ b/hugo/content/components/classic/documentation/discovery.md @@ -0,0 +1,68 @@ +--- +title: Discovery +layout: classic-doc +--- + + + +Discovery Agents +---------------- + +ActiveMQ Classic uses an abstraction called a [Discovery Agent](http://actievmq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/transport/discovery/DiscoveryAgent.html) to detect remote services such as remote brokers. We can use discovery for JMS clients to auto-detect a Message Broker to connect to, or to provide [Networks of Brokers](networks-of-brokers) + +There are currently two kinds of discovery agent. + +### Multicast + +The Discovery transport uses our own Multicast based discovery agent to locate the list of URIs to connect to. + +For more information see the [Discovery Transport Reference](discovery-transport-reference). + +### Zeroconf + +[ZeroConf](zeroconf) is a standard discovery specification that uses UDP / multicast to discovery devices. Its used by Apple's Rendezvous services. +We use the [jmDNS](http://jmdns.sf.net/) project to implement the Zeroconf specification to detect services. This means other Zeroconf +based tools can be used in conjunction with this discovery agent. + +To configure discovery in a Broker you should use the [Xml Configuration](xml-configuration). Here is an [example](http://svn.apache.org/viewvc/activemq/trunk/activemq-unit-tests/src/test/resources/org/apache/activemq/usecases/receiver-zeroconf.xml?view=co) of using discovery to create [Networks of Brokers](networks-of-brokers). + +If you have one or more brokers running with Zeroconf discovery enabled you can connect to a broker using the brokerURL +``` +zeroconf:_activemq_development. +``` +This will use Zeroconf to find an available broker and one will be randomly chosen & things will auto-failover on disconnect if there are several brokers running. + +### LDAP Discovery + +ActiveMQ Classic supports the use of LDAP for discovery of brokers. + +Please see [LDAP Broker Discovery Mechanism](ldap-broker-discovery-mechanism) for more details. + +Trying out discovery +-------------------- + +If you run the following commands in separate shells you'll have 2 brokers auto-discovering themselves and 2 clients using fixed-URLs +``` +maven -o server -Dconfig=src/test/org/activemq/usecases/receiver-zeroconf.xml +maven -o server -Dconfig=src/test/org/activemq/usecases/sender-zeroconf.xml +maven -o consumer -Durl=tcp://localhost:62002 +maven -o producer -Durl=tcp://localhost:62001 +``` +If you want the clients to use discovery to find brokers, run either of the two 'server' statements above (or both) then run the producer/consumer as follows +``` +maven -o consumer -Durl=zeroconf:_activemq.broker.development. +maven -o producer -Durl=zeroconf:_activemq.broker.development. +``` +The transport URL is of the format +``` +zeroconf: +``` +where`` is the Zeroconf service name; which seems to start with an underscore (_) and must end with a dot (.). So we can use this service name to distinguish development, UAT & production brokers - or group them into domains etc. + +Discovery and Security +---------------------- + +When using auto discovery of brokers an attacker may be able to present itself as a legitimate broker and by this way catch and / or manipulate all messages that run over it. + +Are there security settings in auto discovery to avoid this? + diff --git a/hugo/content/components/classic/documentation/dispatch-policies.md b/hugo/content/components/classic/documentation/dispatch-policies.md new file mode 100644 index 0000000000..76b76d8d2b --- /dev/null +++ b/hugo/content/components/classic/documentation/dispatch-policies.md @@ -0,0 +1,75 @@ +--- +title: Dispatch Policies +layout: classic-doc +--- + + [Features](features) > [Message Dispatching Features](message-dispatching-features) > [Dispatch Policies](dispatch-policies) + +Dispatch Policies +================= + +Dispatch policies for queues +---------------------------- + +Plug-able dispatch policies only apply to topics. For Queues, dispatch is more static, you can choose round robin (the default) or strict order. Before discussing dispatch policies its worth first understanding [the purpose of the prefetch value](what-is-the-prefetch-limit-for). + +The out of the box configuration of ActiveMQ Classic is designed for high performance and high throughput messaging where there are lots of messages that need to be dispatched to consumers as quickly as possible. So the default prefetch values are fairly large and the default dispatch policy will try and fill the prefetch buffers as quickly as possible. + +However with messaging there are many use cases and sometimes the default configuration is not ideal to your use case; when you send a small number of messages, they tend to all go to one consumer unless you've lots of messages. If you have a large number of consumers and a relatively high [prefetch value](what-is-the-prefetch-limit-for) and you have a small number of messages that each message takes quite a while to process then the default dispatch policy might result in increasing the amount of time it takes to process all the messages (since the load balancing is not fair for small numbers of messages). + +For queues, you can define whether the dispatch will occur in a round-robin fashion (default behaviour) or if one consumer's prefetch buffer will be exhausted before the dispatch process selects the next consumer along (strictOrderDispatch). + +The latter behaviour is enabled by setting the `strictOrderDispatch` attribute on the `` element. E.g.: +``` + +``` +Consumer priorities are observed, so if you have several consumers with different [priorities](consumer-priority), the one with the highest priority will be flooded first until it can take no more, then the next one along, etc. + +From version 5.14.0 - the strictOrderDispatch=true option will ensure strict order for redispatched messages when there is a single consumer.  + +Dispatch policies for Topics +---------------------------- + +There are more options for topics because the dispatch policy is plug-able. Any implementation of org.apache.activemq.broker.region.policy.DispatchPolicy will work. + +The default `org.apache.activemq.broker.region.policy.SimpleDispatchPolicy` does what one would expect and delivers messages to all subscribers. An example of a more advanced implementation is the `org.apache.activemq.broker.region.policy.PriorityNetworkDispatchPolicy` which will only dispatch to the highest priority network consumer. This is useful in a loop network topology where there is more than route to a consumer. + +Here is an [example of destination policy configuration](http://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/org/apache/activemq/xbean/activemq-policy.xml). + +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` diff --git a/hugo/content/components/classic/documentation/does-activemq-classic-support-clustering.md b/hugo/content/components/classic/documentation/does-activemq-classic-support-clustering.md new file mode 100644 index 0000000000..6bcf442b12 --- /dev/null +++ b/hugo/content/components/classic/documentation/does-activemq-classic-support-clustering.md @@ -0,0 +1,9 @@ +--- +title: Does ActiveMQ Classic support clustering +layout: classic-doc +--- + + + +Yes, though there are various kinds of clustering. See [this page on details](clustering) + diff --git a/hugo/content/components/classic/documentation/does-activemq-classic-support-my-sql-database.md b/hugo/content/components/classic/documentation/does-activemq-classic-support-my-sql-database.md new file mode 100644 index 0000000000..9b68393242 --- /dev/null +++ b/hugo/content/components/classic/documentation/does-activemq-classic-support-my-sql-database.md @@ -0,0 +1,9 @@ +--- +title: Does ActiveMQ Classic support my SQL database +layout: classic-doc +--- + + + +Quite possibly. See the [JDBC Support](jdbc-support) page for details of how to configure for your database or how to let us know of a database which does not work. Also see [Persistence](persistence) + diff --git a/hugo/content/components/classic/documentation/dr.md b/hugo/content/components/classic/documentation/dr.md new file mode 100644 index 0000000000..f173e63dd9 --- /dev/null +++ b/hugo/content/components/classic/documentation/dr.md @@ -0,0 +1,11 @@ +--- +title: DR +layout: classic-doc +--- + + + +Disaster Recovery. + +Typically this means having multiple data centres configured such that if there is a major catastrophy and an entire data centre is lost, messages are replicated to another location so the systems can continue running. + diff --git a/hugo/content/components/classic/documentation/encrypted-passwords.md b/hugo/content/components/classic/documentation/encrypted-passwords.md new file mode 100644 index 0000000000..fa25cf9f3b --- /dev/null +++ b/hugo/content/components/classic/documentation/encrypted-passwords.md @@ -0,0 +1,107 @@ +--- +title: Encrypted passwords +layout: classic-doc +--- + + + +As of ActiveMQ Classic 5.4.1 you can encrypt your passwords and safely store them in configuration files. To encrypt the password, you can use the newly added `encrypt` command like: +``` +$ bin/activemq encrypt --password activemq --input mypassword +... +Encrypted text: eeWjNyX6FY8Fjp3E+F6qTytV11bZItDp +``` +Where the password you want to encrypt is passed with the `input` argument, while the `password` argument is a secret used by the encryptor. In a similar fashion you can test-out your passwords like: +``` +$ bin/activemq decrypt --password activemq --input eeWjNyX6FY8Fjp3E+F6qTytV11bZItDp +... +Decrypted text: mypassword +``` +**Note:** It is recommended that you use only alphanumeric characters for the password. Special characters, such as `$/^&`, are not supported. + +As of the 5.16.0 release, support has been added to specify an algorithm +parameter to the "encrypt" and "decrypt" commands. By default, the algorithm +that is used is "PBEWithMD5AndDES". To use a more modern encryption algorithm +you can specify: +``` +$ bin/activemq encrypt --password activemq --input mypassword --algorithm PBEWITHHMACSHA256ANDAES_256 +... +Encrypted text: h/cWj/ZZelMt3Y7NSzUG2vHYSnfWK561qjNg9Ywyr9yT72ru7pR4IEUnHLIdLSOb +``` + +The next step is to add the password to the appropriate configuration file, `$ACTIVEMQ_HOME/conf/credentials-enc.properties` by default. +``` +activemq.username=system +activemq.password=ENC(mYRkg+4Q4hua1kvpCCI2hg==) +guest.password=ENC(Cf3Jf3tM+UrSOoaKU50od5CuBa8rxjoL) +... +jdbc.password=ENC(eeWjNyX6FY8Fjp3E+F6qTytV11bZItDp) +``` +Note that we used `ENC()` to wrap our encrypted passwords. You can mix plain and encrypted passwords in your properties files, so encrypted ones must be wrapped this way. + +Finally, you need to instruct your property loader to decrypt variables when it loads properties to the memory. Instead of standard property loader we'll use the special one (see `\$ACTIVEMQ_HOME/conf/activemq-security.xml`) to achieve this. +``` + + + + + + + + + + + + + +``` +With this configuration ActiveMQ Classic will try to load your encryptor password from the `ACTIVEMQ_ENCRYPTION_PASSWORD` environment variable and then use it to decrypt passwords from `credential-enc.properties` file. + +Alternative is to use a simple variant and store encryptor password in the xml file, like this +``` + + + + +``` +but with that you'll lose the secrecy of the encryptor's secret. You may also consult [http://www.jasypt.org/advancedCommunity/FAQ/configuration.md](http://www.jasypt.org/advancedCommunity/FAQ/configuration) for more ideas on how to configure Jasypt. + +Finally, we can use properties like we'd normally do +``` + + + + + + + +``` +or +``` + + + + + + + + +``` +If you want to run the broker with this configuration, you need to do the following: + +* Set environment variable: + ``` + $ export ACTIVEMQ\_ENCRYPTION\_PASSWORD=activemq + ``` +* Start the broker: + ``` + $ bin/activemq start xbean:conf/activemq-security.xml + ``` +* Unset the environment variable: + ``` + $ unset ACTIVEMQ\_ENCRYPTION\_PASSWORD + ``` + +In this way your encryptor secret is never saved on your system and your encrypted passwords are safely stored in the configuration files. diff --git a/hugo/content/components/classic/documentation/enterprise-integration-patterns.md b/hugo/content/components/classic/documentation/enterprise-integration-patterns.md new file mode 100644 index 0000000000..a2cb14205f --- /dev/null +++ b/hugo/content/components/classic/documentation/enterprise-integration-patterns.md @@ -0,0 +1,58 @@ +--- +title: Enterprise Integration Patterns +layout: classic-doc +--- + + + +Enterprise Integration Patterns +------------------------------- + +Version 5.0 onwards of Apache ActiveMQ Classic comes complete with full support for the [Enterprise Integration Patterns](http://www.enterpriseintegrationpatterns.com/toc.html) (from the excellent book by [Gregor Hohpe](http://www.amazon.com/exec/obidos/search-handle-url/105-9796798-8100401?%5Fencoding=UTF8&search-type=ss&index=books&field-author=Gregor%20Hohpe) and [Bobby Woolf](http://www.amazon.com/exec/obidos/search-handle-url/105-9796798-8100401?%5Fencoding=UTF8&search-type=ss&index=books&field-author=Bobby%20Woolf)) via the [Apache Camel library](http://activemq.apache.org/camel/). + +You can easily add any of the supported [Enterprise Integration Patterns](enterprise-integration-patterns) into ActiveMQ Classic (either on the JMS client or in the broker process) to support smart routing, transformation and a whole host of other powerful patterns. You can of course just embed [Camel library](http://activemq.apache.org/camel/) directly into your application, such as via [Spring](http://activemq.apache.org/camel/spring.html) as well.. + +This also means you can cleanly integrate all of the [Camel Components](http://activemq.apache.org/camel/components.html) into ActiveMQ Classic so you can easily integrate with [CXF](http://activemq.apache.org/camel/cxf.html), [Files](http://activemq.apache.org/camel/file.html), [JBI](http://activemq.apache.org/camel/jbi.html), [JPA](http://activemq.apache.org/camel/jpa.html), [Mail](http://activemq.apache.org/camel/mail.html), [MINA](http://activemq.apache.org/camel/mina.html), [Quartz](http://activemq.apache.org/camel/quartz.html), [XMPP](http://activemq.apache.org/camel/xmpp) and [many other protocols and transports!](http://activemq.apache.org/camel/components.html) + +### Using EIP in the ActiveMQ Classic Broker + +The broker's `activemq.xml` file comes already configured to support Camel; you just need to customize the routing rules. + +#### Writing EIP rules using Java code + +To use [Java code to write EIP routing rules](http://activemq.apache.org/camel/dsl.html), just put your classes on the classpath (such as in activemq/lib/myroutes/foo.jar). Then to get Camel to find your routes you need to edit the activemq.xml so that the **packages** attribute points to the package name (or a parent package name) to look for. + +For example if all your routes are in the package `org.acme.cheese` such as `org.acme.cheese.whatnot.MyRouter` then you could edit the XML to be... +``` + + org.acme.cheese + +``` + +#### Writing EIP rules using XML + +To use XML its even easier, as you can just embed whatever routing rules inside the `` element using Camel's [Spring XML format](http://activemq.apache.org/camel/xml-configuration). Note that the XML is way more verbose than the [Java DSL](http://activemq.apache.org/camel/dsl.html) but it is a bit simpler to deploy. e.g. for a trivial route... +``` + + + + + + +``` +### Using EIP in the JMS client + +You can use [Camel](http://activemq.apache.org/camel/) [Endpoints](http://activemq.apache.org/camel/endpoint.html) directly from your JMS client one of the following JMS destinations, depending on what JMS API you want it to use + +* [CamelDestination](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/camel/CamelDestination.html) +* [CamelQueue](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/camel/CamelQueue.html) +* [CamelTopic](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/camel/CamelTopic.html) + +You can then use this destination like any other JMS destination when sending or receiving messages! This means you can use any of the [large number of Camel components](http://activemq.apache.org/camel/components.html) from your JMS code, by just changing the Destination object! + +### See Also + +* [Enterprise Integration Patterns](http://activemq.apache.org/camel/enterprise-integration-patterns) +* [Camel Components](http://activemq.apache.org/camel/components.html) +* [Camel XML Reference](http://activemq.apache.org/camel/xml-reference) + diff --git a/hugo/content/components/classic/documentation/exclusive-consumer.md b/hugo/content/components/classic/documentation/exclusive-consumer.md new file mode 100644 index 0000000000..70e4c0c4b2 --- /dev/null +++ b/hugo/content/components/classic/documentation/exclusive-consumer.md @@ -0,0 +1,30 @@ +--- +title: Exclusive Consumer +layout: classic-doc +--- + + + +### Background + +We maintain the order of messages in queues and dispatch them to consumers in order. However if you have multiple JMS Sessions and MessageConsumer instances consuming from the same queue (whether in the same JVM or not), you will loose the guarantee of processing the messages in order; since the messages will be processed concurrently in different threads. + +Sometimes its important to guarantee the order in which messages are processed. e.g. you don't want to process the update to an order until an insert has been done; or to go backwards in time, overwriting an newer update of an order with an older one etc. + +So what folks have to do in J2EE clusters is often to _pin_ one particular JVM in the cluster to have _one_ consumer on the queue to avoid loosing ordering. The problem with this is that if the particular pinned JVM goes down, no one is processing the queue any more, which can be problem. + +### Exclusive Consumer + +We have a new feature in 4.x called Exclusive Consumer or Exclusive Queues which avoids the end user having to _pin_ anything. The broker will pick a single MessageConsumer to get all the messages for a queue to ensure ordering. If that consumer fails, the broker will auto failover and choose another consumer. + +So the effect is a heterogeneous J2EE cluster where each JVM has the same setup and configuration; the broker is choosing one consumer to be the _master_ and send all the messages to it in order until it dies; then you get immediate failover to another consumer. + +For those who've struggled with pinning JMS consumers in J2EE clusters you'll immediately realize how useful this is to making clustered, high available distributed services. + +### Example + +An Exclusive Consumer is created using [Destination Options](destination-options) as follows: +``` +queue = new ActiveMQQueue("TEST.QUEUE?consumer.exclusive=true"); +consumer = session.createConsumer(queue); +``` diff --git a/hugo/content/components/classic/documentation/faq.md b/hugo/content/components/classic/documentation/faq.md new file mode 100644 index 0000000000..6fb98404ae --- /dev/null +++ b/hugo/content/components/classic/documentation/faq.md @@ -0,0 +1,193 @@ +--- +title: FAQ +layout: classic-doc +--- + +Here are commonly asked questions and answers. If you have questions not listed here, please [contact us](/contact/). + +### General + +- [Can I get commercial support](/support/) +- [How can I get the source code from subversion](/contributing/) +- [How does ActiveMQ Classic compare to AMQP](../how-does-activemq-classic-compare-to-amqp) +- [How does Classic compare to Artemis](../how-does-classic-compare-to-artemis) +- [How does ActiveMQ Classic compare to Fuse Message Broker](../how-does-activemq-classic-compare-to-fuse-message-broker) +- [How does ActiveMQ Classic compare to JBossMQ](../how-does-activemq-classic-compare-to-jbossmq) +- [How does ActiveMQ Classic compare to Mantaray](../how-does-activemq-classic-compare-to-mantaray) +- [How does ActiveMQ Classic compare to Mule](../how-does-activemq-classic-compare-to-mule) +- [How does ActiveMQ Classic compare to Spread Toolkit](../how-does-activemq-classic-compare-to-spread-toolkit) +- [How does OpenWire compare to Stomp](../how-does-openwire-compare-to-stomp) +- [How do I avoid Maven downloading latest jars](../how-do-i-avoid-maven-downloading-latest-jars) +- [How do I build but disable the unit tests](../how-do-i-build-but-disable-the-unit-tests) +- [How do I compile from the source](../how-do-i-compile-from-the-source) +- [How fast is ActiveMQ Classic](../how-fast-is-activemq-classic) +- [Should I run ActiveMQ Classic on Windows in a directory with spaces](../should-i-run-activemq-classic-on-windows-in-a-directory-with-spaces) +- [What is ActiveMQ Classic](../what-is-activemq-classic) +- [What is the license](../what-is-the-license) +- [What jars do I need](../what-jars-do-i-need) +- [What open source integration solution works best with ActiveMQ Classic](../what-open-source-integration-solution-works-best-with-activemq-classic) +- [What platforms does ActiveMQ Classic support](../what-platforms-does-activemq-classic-support) +- [What version should I use](../what-version-should-i-use) + +### JMS + +- [Can I modify messages on a queue](../can-i-modify-messages-on-a-queue) +- [Can I send and receive messages concurrently on one JMS Connection](../can-i-send-and-receive-messages-concurrently-on-one-jms-connection) +- [Can you browse a topic](../can-you-browse-a-topic) +- [How do durable queues and topics work](../how-do-durable-queues-and-topics-work) +- [How does a Queue compare to a Topic](../how-does-a-queue-compare-to-a-topic) +- [How does ConnectionFactory relate to the Broker](../how-does-connectionfactory-relate-to-the-broker) +- [How does JMS compare with email](../how-does-jms-compare-with-email) +- [How do I consume a specific message](../how-do-i-consume-a-specific-message) +- [How do I get started with JMS](../how-do-i-get-started-with-jms) +- [How do I make messages durable](../how-do-i-make-messages-durable) +- [How do I send messages to different Destinations from a single MessageProducer](../how-do-i-send-messages-to-different-destinations-from-a-single-messageproducer) +- [How do I use JMS efficiently](../how-do-i-use-jms-efficiently) +- [How should I implement request response with JMS](../how-should-i-implement-request-response-with-jms) +- [How To Unit Test JMS Code](../how-to-unit-test-jms-code) +- [Multiple consumers on a queue](../multiple-consumers-on-a-queue) +- [Should I use transactions](../should-i-use-transactions) +- [Should I use XA](../should-i-use-xa) +- [What are administered objects](../what-are-administered-objects) + +### Using Apache ActiveMQ Classic + +- [ActiveMQ Classic Command Line Tools Reference](../activemq-classic-command-line-tools-reference) +- [Are destinations case sensitive](../are-destinations-case-sensitive) +- [Can I send really large files over ActiveMQ Classic](../can-i-send-really-large-files-over-activemq-classic) +- [Can I use ActiveMQ Classic 5.x or later on Java 1.4](../can-i-use-activemq-classic-5x-or-later-on-java-14) +- [Can two brokers share the same database](../can-two-brokers-share-the-same-database) +- [Does ActiveMQ Classic support clustering](../does-activemq-classic-support-clustering) +- [How can I avoid serialization of Objects in ObjectMessage](../how-can-i-avoid-serialization-of-objects-in-objectmessage) +- [How can I get a list of the topics and queues in a broker](../how-can-i-get-a-list-of-the-topics-and-queues-in-a-broker) +- [How can I make ActiveMQ Classic faster](../how-can-i-make-activemq-classic-faster) +- [How can I monitor ActiveMQ Classic](../how-can-i-monitor-activemq-classic) +- [How can I monitor the connection with the broker](../how-can-i-monitor-the-connection-with-the-broker) +- [How can I see what destinations are used](../how-can-i-see-what-destinations-are-used) +- [How can I support auto reconnection](../how-can-i-support-auto-reconnection) +- [How can I support priority queues](../how-can-i-support-priority-queues) +- [How can I use different network protocols](../how-can-i-use-different-network-protocols) +- [How do distributed queues work](../how-do-distributed-queues-work) +- [How do I access ActiveMQ Classic from C](../how-do-i-access-activemq-classic-from-c) +- [How do I access ActiveMQ Classic from CSharp or dotNet](../how-do-i-access-activemq-classic-from-csharp-or-dotnet) +- [How do I access ActiveMQ Classic from Ruby, Perl, Python, PHP](../how-do-i-access-activemq-classic-from-ruby-perl-python-php) +- [How do I bridge different JMS providers](../how-do-i-bridge-different-jms-providers) +- [How do I change dispatch policy](../how-do-i-change-dispatch-policy) +- [How do I change the logging](../how-do-i-change-the-logging) +- [How do I connect to one of a number of message brokers](../how-do-i-connect-to-one-of-a-number-of-message-brokers) +- [How do I create new destinations](../how-do-i-create-new-destinations) +- [How do I delete a destination](../how-do-i-delete-a-destination) +- [How do I disable logging](../how-do-i-disable-logging) +- [How do I embed a Broker inside a Connection](../how-do-i-embed-a-broker-inside-a-connection) +- [How do I enable asynchronous sending](../how-do-i-enable-asynchronous-sending) +- [How do I enable debug logging](../how-do-i-enable-debug-logging) +- [How do I find the Size of a Queue](../how-do-i-find-the-size-of-a-queue) +- [How do I preserve order of messages](../how-do-i-preserve-order-of-messages) +- [How do I purge a queue](../how-do-i-purge-a-queue) +- [How do I restart embedded broker](../how-do-i-restart-embedded-broker) +- [How do I restrict connections from creating new queues or topics](../how-do-i-restrict-connections-from-creating-new-queues-or-topics) +- [How do I run a broker](../how-do-i-run-a-broker) +- [How do I set the message expiration](../how-do-i-set-the-message-expiration) +- [How do I turn off creating an embedded ActiveMQ Classic broker when using the VM transport](../how-do-i-turn-off-creating-an-embedded-activemq-classic-broker-when-using-the-vm-transport) +- [How do I unack the message with Stomp](../how-do-i-unack-the-message-with-stomp) +- [How do I use ActiveMQ Classic using in JVM messaging](../how-do-i-use-activemq-classic-using-in-jvm-messaging) +- [How do I use durable subscribers in a network of brokers](../how-do-i-use-durable-subscribers-in-a-network-of-brokers) +- [How do I use Ivy with ActiveMQ Classic](../how-do-i-use-ivy-with-activemq-classic) +- [How do I use log4j JMS appender with ActiveMQ Classic](../how-do-i-use-log4j-jms-appender-with-activemq-classic) +- [How do I use SSL](../how-do-i-use-ssl) +- [How do Message Groups compare to Selectors](../how-do-message-groups-compare-to-selectors) +- [How do multiple transports work](../how-do-multiple-transports-work) +- [How Do Transactions Work](../how-do-transactions-work) +- [How lightweight is sending a message](../how-lightweight-is-sending-a-message) +- [How should I package applications using Camel and ActiveMQ Classic](../how-should-i-package-applications-using-camel-and-activemq-classic) +- [How should I use the VM transport](../how-should-i-use-the-vm-transport) +- [How to deal with large number of threads in clients](../how-to-deal-with-large-number-of-threads-in-clients) +- [How to disable auto destination creation](../how-to-disable-auto-destination-creation) +- [I see NC_ client-ids, what does that mean](../i-see-nc-client-ids-what-does-that-mean) +- [Should I deploy Enterprise Integration Patterns in the broker or another application](../should-i-deploy-enterprise-integration-patterns-in-the-broker-or-another-application) +- [Should I deploy the broker inside my JVM or AppServer](../should-i-deploy-the-broker-inside-my-jvm-or-appserver) +- [What are those topics ActiveMQ.Advisory](../what-are-those-topics-activemqadvisory) +- [What happens with a fast producer and slow consumer](../what-happens-with-a-fast-producer-and-slow-consumer) +- [What is the difference between a Virtual Topic and a Composite Destination](../what-is-the-difference-between-a-virtual-topic-and-a-composite-destination) +- [What is the difference between discovery, multicast and zeroconf](../what-is-the-difference-between-discovery-multicast-and-zeroconf) +- [What is the Prefetch Limit For?](../what-is-the-prefetch-limit-for) +- [While posting large binary file to activeMQ, is there a way to measure its progress](../while-posting-large-binary-file-to-activemq-is-there-a-way-to-measure-its-progress) + +### Configuration + +- [How can I enable detailed logging](../how-can-i-enable-detailed-logging) +- [How does XBean compare to Spring 2](../how-does-xbean-compare-to-spring-2) +- [How do I configure 10s of 1000s of Queues in a single broker](../how-do-i-configure-10s-of-1000s-of-queues-in-a-single-broker) +- [How do I configure ActiveMQ Classic to hold 100s of millions of Queue Messages](../how-do-i-configure-activemq-classic-to-hold-100s-of-millions-of-queue-messages) +- [How do I configure ActiveMQ Classic to use AIO server transport](../how-do-i-configure-activemq-classic-to-use-aio-server-transport) +- [How do I configure automatic reconnection](../how-do-i-configure-automatic-reconnection) +- [How do I configure distributed queues or topics](../how-do-i-configure-distributed-queues-or-topics) +- [How do I configure the queues I want](../how-do-i-configure-the-queues-i-want) +- [How do I define a local address and local port for TCP or SSL](../how-do-i-define-a-local-address-and-local-port-for-tcp-or-ssl) +- [How do I disable persistence](../how-do-i-disable-persistence) +- [How do I run ActiveMQ Classic under the Kaffe JVM](../how-do-i-run-activemq-classic-under-the-kaffe-jvm) +- [How to configure a new database](../how-to-configure-a-new-database) +- [How to deploy activemq-ra-version.rar to weblogic](../how-to-deploy-activemq-ra-versionrar-to-weblogic) +- [How to disable multicast discovery](../how-to-disable-multicast-discovery) + +### Persistence Questions + +- [Are messages read directly from the journal](../are-messages-read-directly-from-the-journal) +- [Does ActiveMQ Classic support my SQL database](../does-activemq-classic-support-my-sql-database) +- [How does journaling work with multiple brokers](../how-does-journaling-work-with-multiple-brokers) +- [How does the journal work](../how-does-the-journal-work) +- [How do I back-up KahaDB](../how-do-i-back-up-kahadb) +- [How do I change the message store directory for an embedded broker](../how-do-i-change-the-message-store-directory-for-an-embedded-broker) +- [Is there a specified size of the journal](../is-there-a-specified-size-of-the-journal) +- [What happens when the journal size is exceeded](../what-happens-when-the-journal-size-is-exceeded) +- [What is the difference between persistent and non-persistent delivery](../what-is-the-difference-between-persistent-and-non-persistent-delivery) + +### Errors + +- [Could not find PacketReader for packet type - UNKNOWN PACKET TYPE](../could-not-find-packetreader-for-packet-type-unknown-packet-type) +- Exceptions + - [certificate_unknown](../certificateunknown) + - [IOException - could not find class for resource](../ioexception-could-not-find-class-for-resource) + - [java.io.InterruptedIOException](../javaiointerruptedioexception) + - [java.io.IOException Failed to create database 'derbydb'](../javaioioexception-failed-to-create-database-derbydb-see-the-next-exception-for-details) + - [java.lang.NoSuchMethodError](../javalangnosuchmethoderror) + - [java.lang.NoSuchMethodException org.activemq.ra.ActiveMQResourceAdapter.setUseEmbeddedBroker](../javalangnosuchmethodexception-orgactivemqraactivemqresourceadaptersetuseembeddedbroker) + - [java.lang.OutOfMemory](../javalangoutofmemory) + - [javax.jms.JMSException - Wire format negociation timeout](../javaxjmsjmsexception-wire-format-negociation-timeout-peer-did-not-send-his-wire-format) + - [JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI needs 2.1 API](../jaxb-20-api-is-being-loaded-from-the-bootstrap-classloader-but-this-ri-needs-21-api) + - [Journal is already opened by this application](../journal-is-already-opened-by-this-application) + - [NoClassDefFoundError - org.springframework.core.io.Resource](../noclassdeffounderror-orgspringframeworkcoreioresource) + - [No suitable driver](../no-suitable-driver) +- [I am having problems with the Spring JmsTemplate](../i-am-having-problems-with-the-spring-jmstemplate) +- [I am not receiving any messages, what is wrong](../i-am-not-receiving-any-messages-what-is-wrong) +- [I cannot connect to ActiveMQ Classic from JConsole](../i-cannot-connect-to-activemq-classic-from-jconsole) +- [I do not receive messages in my second consumer](../i-do-not-receive-messages-in-my-second-consumer) +- [I get errors building the code whats wrong](../i-get-errors-building-the-code-whats-wrong) +- [log4j-WARN No appenders could be found for logger](../log4j-warn-no-appenders-could-be-found-for-logger) +- [Multicast - Watch out for IPV6 vs IPV4 support on your operating system or distribution or network](../multicast-watch-out-for-ipv6-vs-ipv4-support-on-your-operating-system-or-distribution-or-network) +- [My producer blocks](../my-producer-blocks) +- [onMessage method of MessageListener is never called](../onmessage-method-of-messagelistener-is-never-called) +- [Resource Adapter does not seem to pool connections](../resource-adapter-does-not-seem-to-pool-connections) +- [Slow networks drop large messages](../slow-networks-drop-large-messages) +- [The Broker will not start](../the-broker-will-not-start) +- [The vm transport starts a broker before my configured broker starts](../the-vm-transport-starts-a-broker-before-my-configured-broker-starts) +- [Why do I not get all of the messages I sent](../why-do-i-not-get-all-of-the-messages-i-sent) +- [Why do I not receive messages on my durable topic subscription](../why-do-i-not-receive-messages-on-my-durable-topic-subscription) +- [Why do KahaDB log files remain after cleanup](../why-do-kahadb-log-files-remain-after-cleanup) + +### Developing ActiveMQ Classic + +- [How can I add a new type of transport](../how-can-i-add-a-new-type-of-transport) +- [How can I contribute](/contributing/) +- [How do I add my own plugins](../how-do-i-add-my-own-plugins) +- [How do I debug ActiveMQ Classic from my IDE](../how-do-i-debug-activemq-classic-from-my-ide) + +### Terminology + +- [DR](../dr) — Disaster Recovery +- [HA](../ha) — High Availability +- [Latency](../latency) +- [MOM](../mom) — Message Oriented Middleware +- [QoS](../qos) +- [SEDA](../seda) — Staged Event-Driven Architecture +- [Throughput](../throughput) diff --git a/hugo/content/components/classic/documentation/features-overview.md b/hugo/content/components/classic/documentation/features-overview.md new file mode 100644 index 0000000000..bdadbe7d6b --- /dev/null +++ b/hugo/content/components/classic/documentation/features-overview.md @@ -0,0 +1,26 @@ +--- +title: Features Overview +layout: classic-doc +--- + + + +* Supports a variety of [Cross Language Clients and Protocols](cross-language-clients) from Java, C, C++, C#, Ruby, Perl, Python, PHP + * [OpenWire](openwire) for high performance clients in Java, C, C++, C# + * [Stomp](stomp) support so that clients can be written easily in C, Ruby, Perl, Python, PHP, ActionScript/Flash, Smalltalk to talk to ActiveMQ Classic as well as any other popular Message Broker + * [AMQP](amqp) v1.0 support + * [MQTT](mqtt) v3.1 support allowing for connections in an IoT environment. +* full support for the [Enterprise Integration Patterns](enterprise-integration-patterns) both in the JMS client and the Message Broker +* Supports many [advanced features](features) such as [Message Groups](message-groups), [Virtual Destinations](virtual-destinations), [Wildcards](wildcards) and [Composite Destinations](composite-destinations) +* Fully supports JMS 1.1 and J2EE 1.4 with support for transient, persistent, transactional and XA messaging +* [Spring Support](spring-Community/support) so that ActiveMQ Classic can be easily embedded into Spring applications and configured using Spring's XML configuration mechanism +* Tested inside popular J2EE servers such as [TomEE](http://tomee.apache.org/), [Geronimo](http://geronimo.apache.org/), JBoss, GlassFish and WebLogic + * Includes [JCA 1.5 resource adaptors](resource-adapter) for inbound & outbound messaging so that ActiveMQ Classic should auto-deploy in any J2EE 1.4 compliant server +* Supports pluggable [transport protocols](uri-Connectivity/protocols) such as [in-VM](how-do-i-use-activemq-classic-using-in-jvm-messaging), TCP, SSL, NIO, UDP, multicast, JGroups and JXTA transports +* Supports very fast [persistence](persistence) using JDBC along with a high performance journal +* Designed for high performance clustering, client-server, peer based communication +* [REST](rest) API to provide technology agnostic and language neutral web based API to messaging +* [Ajax](ajax) to support web streaming support to web browsers using pure DHTML, allowing web browsers to be part of the messaging fabric +* [CXF and Axis Support](axis-and-cxf-support) so that ActiveMQ Classic can be easily dropped into either of these web service stacks to provide reliable messaging +* Can be used as an in memory JMS provider, ideal for [unit testing JMS](how-to-unit-test-jms-code) + diff --git a/hugo/content/components/classic/documentation/features.md b/hugo/content/components/classic/documentation/features.md new file mode 100644 index 0000000000..4e1e8e462b --- /dev/null +++ b/hugo/content/components/classic/documentation/features.md @@ -0,0 +1,73 @@ +--- +title: Apache ActiveMQ Features +layout: classic-doc +--- + +Apache ActiveMQ is packed with features. See the [Features Overview](../features-overview) for a summary, or browse the full list below. + +### Clustering & High Availability + +- [MasterSlave](../masterslave) — [JDBC Master Slave](../jdbc-master-slave), [Shared File System Master Slave](../shared-file-system-master-slave), [Pure Master Slave](../pure-master-slave) +- [Networks of Brokers](../networks-of-brokers) +- [Replicated Message Store](../replicated-message-store) + +### Consumer Features + +- [Exclusive Consumer](../exclusive-consumer) +- [Message Groups](../message-groups) +- [Redelivery Policy](../redelivery-policy) +- [Retroactive Consumer](../retroactive-consumer) +- [Selectors](../selectors) +- [Slow Consumer Handling](../slow-consumer-handling) +- [Subscription Recovery Policy](../subscription-recovery-policy) + +### Destination Features + +- [Composite Destinations](../composite-destinations) +- [Virtual Destinations](../virtual-destinations) +- [Wildcards](../wildcards) +- [Mirrored Queues](../mirrored-queues) +- [Per Destination Policies](../per-destination-policies) + +### Message Features + +- [Advisory Message](../advisory-message) +- [Blob Messages](../blob-messages) +- [Delay and Schedule Message Delivery](../delay-and-schedule-message-delivery) +- [Message Transformation](../message-transformation) +- [ObjectMessage](../objectmessage) + +### Message Dispatching + +- [Async Sends](../async-sends) +- [Dispatch Policies](../dispatch-policies) +- [Message Cursors](../message-cursors) +- [Optimized Acknowledgement](../optimized-acknowledgement) +- [Producer Flow Control](../producer-flow-control) + +### Persistence + +- [KahaDB](../kahadb) +- [JDBC Support](../jdbc-support) +- [AMQ Message Store](../amq-message-store) +- [Pluggable storage lockers](../pluggable-storage-lockers) + +### Security + +- [Security](../security) +- [Audit Logging](../audit-logging) +- [Encrypted passwords](../encrypted-passwords) +- [Cached LDAP Authorization Module](../cached-ldap-authorization-module) + +### Performance + +- [ActiveMQ Classic Performance Module Users Manual](../activemq-classic-performance-module-users-manual) +- [Load Testing with Camel](../load-testing-with-camel) + +### Other + +- [JMX](../jmx) +- [MDC Logging](../mdc-logging) +- [Discovery](../discovery) +- [Enterprise Integration Patterns](../enterprise-integration-patterns) +- [New Features](../new-features) diff --git a/hugo/content/components/classic/documentation/geronimo.md b/hugo/content/components/classic/documentation/geronimo.md new file mode 100644 index 0000000000..2d51b963e4 --- /dev/null +++ b/hugo/content/components/classic/documentation/geronimo.md @@ -0,0 +1,206 @@ +--- +title: Geronimo +layout: classic-doc +--- + + + +ActiveMQ Classic is the default JMS provider in [Apache Geronimo](http://geronimo.apache.org). + +ActiveMQ Classic can be used both as JMS Client and a JMS Broker. This short +article explains how to use it on a standalone client to access the +topics/queues setup on a remote Geronimo/ActiveMQ Classic broker. + +1) Setup the queues and topics on the ActiveMQ Classic Broker +If you're using a standalone ActiveMQ Classic broker, then following the instructions on +ActiveMQ Classic's website should be enough to setup everything. +However, if your ActiveMQ Classic's instance is embedded inside the J2EE Geronimo +Application Server, creating Queues and Topics is about deploying Resource +Adapters to your Geronimo server. +The following deployment descriptor can be used to deploy two topics and a +ConnectionFactory: weatherTopic and weatherRequestsTopic + +``` + + + + + ActiveMQ Classic RA + tcp://localhost:61616 + geronimo + geronimo + + DefaultWorkManager + + + + + +javax.jms.ConnectionFactory + + ConnectionFactory + +javax.jms.QueueConnectionFactory + +javax.jms.TopicConnectionFactory + + + + + + 10 + +5000 + + + + ConnectionFactory + + + + + + + javax.jms.Topic + +org.codehaus.activemq.message.ActiveMQTopic + + weatherTopic + weatherTopic + + + + javax.jms.Topic + +org.codehaus.activemq.message.ActiveMQTopic + + +weatherRequestsTopic + weatherRequestsTopic + + + + +``` + +Then deploy it using Geronimo's deploy tool : + +``` +D:\\geronimo>java -jar bin\\deployer.jar deploy d:\\projects\\weather\\src\\resources\ +geronimo-activemq.xml repository\\activemq\\rars\\activemq-ra-3.1-SNAPSHOT.rar +Username: system +Password: manager +Deployed weather/Topics +``` + +The geronimo.log file should now refer to these newly deployed Topics. + +2) Now that the queues are available server-side, what we want is access them +thanks to a standalone Client. +Usually, the process is the following one : + +* Contact the J2EE naming server (port 1099, RMI) to get an JNDI InitialContext. +* The J2EE server automatically exposes the ConnectionFactory and the Topics + through JNDI, so the InitialContext allows you to retrieve both the + ConnectionFactory and the Topics +* Once you have your Topics, you just use them.. + +However, ActiveMQ Classic's JNDI Implementation does NOT talk to the naming server. It's +a stripped down version of a JNDI client that just allows to get Topics and +Queues directly from a JMS instance. +So, instead of supplying the naming server address, you have to supply the JMS +server address. +Most JNDI implementations use the java.naming.provider.url property to specify +the naming server's address. ActiveMQ Classic uses the brokerURL one. Using the +java.naming.provider.url one instead will result in ActiveMQ Classic trying to load the +whole Broker. + +3) So, now we have explained the process, let's detail the Spring way of doing +things : + +* Create a bootstrap.properties file that's available in your classpath + ``` + jms.connectionFactoryName=ConnectionFactory + jms.jndiProviderUrl=tcp://localhost:61616 + jms.jndiContextFactory=org.activemq.jndi.ActiveMQInitialContextFactory + + jms.weatherTopic=weatherTopic + jms.weatherRequestsTopic=weatherRequestsTopic + ``` +* Now, in your Spring description file, declare the bean that will read the properties from the bootstrap.properties file + + + classpath:/bootstrap.properties + + + +* Create a JNDI template (A Spring-specific wrapper around the JNDI InitialContext + ``` + + + + ${jms.jndiContextFactory} + + + + + ${jms.jndiProviderUrl} + + ${jms.weatherTopic} + ${jms.weatherRequestsTopic} + + + + ``` + +* Retrieve the ConnectionFactory from the JNDI context + + ``` + + + + + + ${jms.connectionFactoryName} + + + ``` +I'm not 100% sure, but I think that you can put any Factory Name, it will just +work. (In a scenario where the JNDI context actually contacts a naming server, +it should match the name of the deployed ConnectionFactory) + +* Get the Topics instances from the JNDI Context + ``` + + + + + + ${jms.weatherTopic} + + + + + + + + + ${jms.weatherRequestsTopic} + + + ``` +* Now, you can reuse these Topics beans the way you want. + diff --git a/hugo/content/components/classic/documentation/getting-started.md b/hugo/content/components/classic/documentation/getting-started.md new file mode 100644 index 0000000000..4fe45e44ab --- /dev/null +++ b/hugo/content/components/classic/documentation/getting-started.md @@ -0,0 +1,57 @@ +--- +title: Getting Started with ActiveMQ +layout: classic-doc +--- + +This document describes how to install and configure ActiveMQ Classic 5.x for both Unix and Windows platforms. + +### Pre-Installation Requirements + +**Hardware:** ~60 MB disk space for binary distribution; ~300 MB for source distribution. + +**Java:** JRE 1.8 or greater (1.7 for ≤5.15.0, 1.6 for ≤5.10.0). `JAVA_HOME` must be set. + +### Installation on Windows + +1. Download the latest release from the [Download](../../download/) page (`apache-activemq-x.x.x-bin.zip`). +2. Extract the ZIP to a directory of your choice. +3. Start the broker: + ``` + cd [activemq_install_dir] + bin\activemq start + ``` + +### Installation on Unix + +1. Download the tarball from the [Download](../../download/) page. +2. Extract: + ``` + tar zxvf apache-activemq-x.x.x-bin.tar.gz + ``` +3. Start the broker: + ``` + cd [activemq_install_dir]/bin + ./activemq start + ``` + +On macOS with Homebrew: +``` +brew install apache-activemq +``` + +### Testing the Installation + +- Open the admin console at [http://127.0.0.1:8161/admin/](http://127.0.0.1:8161/admin/) (login: admin/admin). +- Check the default port: `netstat -nl | grep 61616` + +### Stopping ActiveMQ Classic + +Press `CTRL-C` in the console, or on Unix: +``` +cd [activemq_install_dir]/bin +./activemq stop +``` + +### Configuring ActiveMQ Classic + +Configure the broker via an [XML Configuration](xml-configuration) file or the [Broker Configuration URI](broker-configuration-uri). See [Configuring Transports](configuring-transports) for connection options. diff --git a/hugo/content/components/classic/documentation/git.md b/hugo/content/components/classic/documentation/git.md new file mode 100644 index 0000000000..f2f0034fa4 --- /dev/null +++ b/hugo/content/components/classic/documentation/git.md @@ -0,0 +1,58 @@ +--- +title: GIT +layout: classic-doc +--- + + + +ActiveMQ Classic 5 +========== + +Web Browsing of the git Repo +---------------------------- + +To browse via the web: + +[https://git-wip-us.apache.org/repos/asf?p=activemq.git](https://git-wip-us.apache.org/repos/asf?p=activemq.git) + +Checking out from the git Repo +------------------------------ + +git clone [https://git-wip-us.apache.org/repos/asf/activemq.git](https://git-wip-us.apache.org/repos/asf/activemq.git) + +Only project developers can commit to the git repo via this method. SSH must be installed on your client machine. Enter your site password when prompted. + +Building the code +----------------- + +To then build the code, see [Building](building). + +ActiveMQ Artemis +================ + +Web Browsing of the ASF git Repo +-------------------------------- + +To browse via the web: + +[https://git-wip-us.apache.org/repos/asf?p=activemq-artemis.git](https://git-wip-us.apache.org/repos/asf?p=activemq-artemis.git) + +Browsing the Github Repo  +------------------------- + +[https://github.com/apache/activemq-artemis](https://github.com/apache/activemq-artemis) + +Checking out from the Github Repo +--------------------------------- + +git clone [https://github.com/apache/activemq-artemis](https://github.com/apache/activemq-artemis) + +`Committers:** Please follow the instructions for properly configuring the [Instructions for Core Contributors/Hacking Guide](https://github.com/apache/activemq-artemis/blob/master/docs/hacking-guide/enSUMMARY) + +`Contributors:** Please create a [pull request](https://github.com/apache/activemq-artemis) to contribute changes to the source code.  + +Building the code +----------------- + +To then build the code, take a look at [Building the distribution](https://github.com/apache/activemq-artemis/blob/master/docs/hacking-guide/enDevelopers/Developers/building) + diff --git a/hugo/content/components/classic/documentation/ha.md b/hugo/content/components/classic/documentation/ha.md new file mode 100644 index 0000000000..5ef7f6d4a2 --- /dev/null +++ b/hugo/content/components/classic/documentation/ha.md @@ -0,0 +1,11 @@ +--- +title: HA +layout: classic-doc +--- + + + +High Availability. + +This typically refers to having a number of available instances of a service (such as a Message Broker) such that if the instance you're connected to fails, you can failover quickly to another instance providing _high availabliity_ and resilience. + diff --git a/hugo/content/components/classic/documentation/how-can-i-add-a-new-type-of-transport.md b/hugo/content/components/classic/documentation/how-can-i-add-a-new-type-of-transport.md new file mode 100644 index 0000000000..123e42c815 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-can-i-add-a-new-type-of-transport.md @@ -0,0 +1,17 @@ +--- +title: How can I add a new type of transport +layout: classic-doc +--- + + + +ActiveMQ Classic is specifically designed to allow custom transports to be plugged in. You can programatically create TransportConnector instances and add them to the BrokerService in Java code using the [BrokerService.addConnector() method](http://activemq.codehaus.org/maven/apidocs/org/apache/activemq/broker/BrokerService.html#addConnector(org.apache.activemq.broker.TransportConnector)) + +or you can use the transport discovery mechanism, so that folks can just use your new transport using the neat URI syntax. + +The way it works is that the URI scheme (e.g. "vm") is used to find a text file on the classpath - [here are all the schemes provided](http://svn.apache.org/repos/asf/incubator/activemq/trunk/activemq-core/src/main/resources/META-INF/services/org/apache/activemq/transport/). + +then the contents of the file is the class name of a Java class on the classpath which extends the [TransportFactory class](http://activemq.codehaus.org/maven/apidocs/org/apache/activemq/transport/TransportFactory.html). + +Then once you've implemented a Transport and TransportFactory class, folks can use your new transport using a URI in the JMS client or broker XML config file using the URI using your new schema name. e.g. if you wrote a new _foo_ transport, you could use a URI of _foo://localhost?myParam=bar_ + diff --git a/hugo/content/components/classic/documentation/how-can-i-avoid-serialization-of-objects-in-objectmessage.md b/hugo/content/components/classic/documentation/how-can-i-avoid-serialization-of-objects-in-objectmessage.md new file mode 100644 index 0000000000..3a5a51a07e --- /dev/null +++ b/hugo/content/components/classic/documentation/how-can-i-avoid-serialization-of-objects-in-objectmessage.md @@ -0,0 +1,9 @@ +--- +title: How can I avoid serialization of Objects in ObjectMessage +layout: classic-doc +--- + + + +Use the VM transport and see [details on how to disable serialization to pass by value](how-should-i-use-the-vm-transport) + diff --git a/hugo/content/components/classic/documentation/how-can-i-enable-detailed-logging.md b/hugo/content/components/classic/documentation/how-can-i-enable-detailed-logging.md new file mode 100644 index 0000000000..14974d2c5f --- /dev/null +++ b/hugo/content/components/classic/documentation/how-can-i-enable-detailed-logging.md @@ -0,0 +1,35 @@ +--- +title: How can I enable detailed logging +layout: classic-doc +--- + + + +How can I enable detailed logging +--------------------------------- + +We use [slf4j](https://www.slf4j.org/) which allows the underlying logging implementation to be statically bound at startup. + +By default we ship with log4j but feel free to make your own choice. + +If you've got log4j.jar on your classpath you can use a log4j.properties file to configure the logging levels. See the [log4j.properties example](https://github.com/apache/activemq/blob/main/activemq-broker/src/test/resources/log4j.properties) for the kind of thing you'll need. + +e.g. adding the following to your log4j.properties will enable tracing of ActiveMQ Classic code: + +in 4.x +``` +log4j.logger.org.apache.activemq=INFO +log4j.logger.org.apache.activemq.spring=WARN +``` +in 3.x +``` +log4j.logger.org.activemq=TRACE +``` + +### Getting help on log4j + +Since ActiveMQ Classic 5.17.0, ActiveMQ Classic uses [log4j2](https://logging.apache.org/log4j/2.x/index.html). You can find log4j2 documentation [here](https://logging.apache.org/log4j/2.x/manual/index.html). + +ActiveMQ Classic 5.16.4+ uses [reload4j](https://reload4j.qos.ch/), a fork of log4j1 containing important security fixes, with the same configuration as log4j1. + +Before ActiveMQ Classic 5.16.4, ActiveMQ Classic uses [log4j1](https://logging.apache.org/log4j/1.2/manual.html). diff --git a/hugo/content/components/classic/documentation/how-can-i-get-a-list-of-the-topics-and-queues-in-a-broker.md b/hugo/content/components/classic/documentation/how-can-i-get-a-list-of-the-topics-and-queues-in-a-broker.md new file mode 100644 index 0000000000..eba145cdef --- /dev/null +++ b/hugo/content/components/classic/documentation/how-can-i-get-a-list-of-the-topics-and-queues-in-a-broker.md @@ -0,0 +1,18 @@ +--- +title: How can I get a list of the topics and queues in a broker +layout: classic-doc +--- + + + +How can I get a list of the topics and queues in a broker? +---------------------------------------------------------- + +As of 5.1.0 you can use the new [DestinationSource](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/advisory/DestinationSource.html) on an ActiveMQConnection to access the available queues or topics or listen to queues/topics being created or deleted. + +You can use [JMX](jmx) to browse the available topics and queues in a broker together with the connectors and connections along with their statistics etc. + +Or you can access statistics [programmatically](how-can-i-see-what-destinations-are-used). + +Finally you could just use the [Web Console](web-console) + diff --git a/hugo/content/components/classic/documentation/how-can-i-make-activemq-classic-faster.md b/hugo/content/components/classic/documentation/how-can-i-make-activemq-classic-faster.md new file mode 100644 index 0000000000..296cc14ecf --- /dev/null +++ b/hugo/content/components/classic/documentation/how-can-i-make-activemq-classic-faster.md @@ -0,0 +1,9 @@ +--- +title: How can I make ActiveMQ Classic faster? +layout: classic-doc +--- + + + +See the [Performance](performance) page for information about the performance of ActiveMQ Classic and it's tuning parameters. + diff --git a/hugo/content/components/classic/documentation/how-can-i-monitor-activemq-classic.md b/hugo/content/components/classic/documentation/how-can-i-monitor-activemq-classic.md new file mode 100644 index 0000000000..e13c9e0fca --- /dev/null +++ b/hugo/content/components/classic/documentation/how-can-i-monitor-activemq-classic.md @@ -0,0 +1,37 @@ +--- +title: How can I monitor ActiveMQ Classic +layout: classic-doc +--- + + + +How can I monitor ActiveMQ Classic +---------------------------------- + +ActiveMQ Classic comes bundled with [Jolokia](http://www.jolokia.org/) which provides a RESTful interface to ActiveMQ Classic's JMX capabilities. An open source third party tool that connects via Jolokia is [hawt.io](http://hawt.io/), an HTML-5 web console with an ActiveMQ Classic plugin that is at least worth being familiar with as ActiveMQ Classic and hawt.io share developers. + +In ActiveMQ Classic you can monitor the broker to see what destinations are being used, their activity along with connections and subscriptions using the following tools + +* [JMX](jmx) and a JMX console such as [jConsole](http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html) +* The [Web Console](web-console) +* the [Advisory Message](advisory-message) feature (using JMS messages to monitor the system) +* The [Command Agent](command-agent); ActiveMQ.Agent topic that you query for status +* The [Visualisation](visualisation) plug-in +* The [Statistics](statisticsplugin) plug-in + +### Third Party Tools + +* [ActiveMQ Monitor (AMon)](http://www.ttmsolutions.com/Transactional_Software_Solutions/Active_Monitor_AMon.php) +* [Apache ActiveMQBrowser](http://sourceforge.net/projects/activemqbrowser/) +* [FuseHQ](http://fusesource.com/products/fuse-hq/) (based on Hyperic HQ Enterprise) +* [Geronimo Administration Console](https://cwiki.apache.org/GMOxDOC11/geronimo-administration-console.html#GeronimoAdministrationConsole-JMSServer) (JMS Resources) +* [Hyperic HQ](http://www.hyperic.com/products/open-source-systems-monitoring) and [Hyperic HQ Enterprise](http://www.hyperic.com/products/enterprise-systems-monitoring) +* [iTKO LISA Test](http://www.itko.com/products/jms.jsp) +* [jmxtrans](https://github.com/jmxtrans/jmxtrans) which can be used to continuously query ActiveMQ Classic via JMX and write to a chosen output. For instance, write to a graphite database file which can then be used to graph trends over time and be queried by Nagios to alarm should your thresholds be exceeded. +* [Media Driver Integrated Console](https://mediadriver.com/software/) can manage and monitor ActiveMQ Classic, IBM MQ and Tibco EMS +* [New Relic ActiveMQ Classic Integration](https://newrelic.com/instant-observability/activemq) Get real-time Apache ActiveMQ Classic performance metrics with New Relic APM. + +### See Also + +* [How can I monitor the connection with the broker](how-can-i-monitor-the-connection-with-the-broker) + diff --git a/hugo/content/components/classic/documentation/how-can-i-monitor-the-connection-with-the-broker.md b/hugo/content/components/classic/documentation/how-can-i-monitor-the-connection-with-the-broker.md new file mode 100644 index 0000000000..4de0c428d4 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-can-i-monitor-the-connection-with-the-broker.md @@ -0,0 +1,18 @@ +--- +title: How can I monitor the connection with the broker +layout: classic-doc +--- + + + +How can I monitor the connection with the broker +------------------------------------------------ + +You can monitor the status of the connection with the broker via the [addTransportListener() method on the ActiveMQConnection](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/ActiveMQConnection.html#addTransportListener%28org.apache.activemq.transport.TransportListener). + +This method takes a [TransportListener](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/transport/TransportListener.html) which is notified as the connection is established & dropped. It also allows you to work with the [Failover Transport](failover-transport-reference) yet still know the status of the connection. + +### See Also + +* [How can I monitor ActiveMQ Classic](how-can-i-monitor-activemq-classic) + diff --git a/hugo/content/components/classic/documentation/how-can-i-see-what-destinations-are-used.md b/hugo/content/components/classic/documentation/how-can-i-see-what-destinations-are-used.md new file mode 100644 index 0000000000..a2ed4de8c2 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-can-i-see-what-destinations-are-used.md @@ -0,0 +1,13 @@ +--- +title: How can I see what destinations are used? +layout: classic-doc +--- + + + +The easiest way is to use [JMX](jmx) by pointing your JMX console or JConsole at the broker JVM. + +You can also get all of the active destinations from the broker using Java code via [getDestinations()](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/broker/region/Region.html#getDestinations-org.apache.activemq.command.ActiveMQDestination-). + +You can also get a Map of all the [Destination](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/broker/region/Destination.html) objects indexed by ActiveMQDestination via [getDestinationMap()](http://activemq.apache.org/maven/apidocs/org/apache/activemq/broker/region/Region.html#getDestinationMap--). This allows you to look at the individual destination details such as the queue depths and so forth + diff --git a/hugo/content/components/classic/documentation/how-can-i-support-auto-reconnection.md b/hugo/content/components/classic/documentation/how-can-i-support-auto-reconnection.md new file mode 100644 index 0000000000..7d29992944 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-can-i-support-auto-reconnection.md @@ -0,0 +1,22 @@ +--- +title: How can I support auto reconnection +layout: classic-doc +--- + + + +How can I support auto reconnection? +------------------------------------ + +Networks are unreliable and sockets do get dropped from time to time (it could be a network glitch, dodgy router, firewall, or someone could even just restart a broker). + +You often want a JMS client to automatically handle the fact that the connection to the broker was lost such that the JMS client either reconnnects to the same broker when it becomes available, or reconnects to another broker in the cluster. + +Its easy to perform auto-reconnection. In Apache ActiveMQ Classic using the [failover transport](failover-transport-reference) in which the JMS client (connection) will automatically reconnect to the broker if there is a socket exception. + +Just use the following connection URI (setting the brokerURL in the `ActiveMQConnectionFactory`) +``` +failover:tcp://host:port +``` +You can use a list of URIs to specify which machines to connect to and use discovery to find the brokers to connect to. More details on this see [Configuring Transports](configuring-transports) + diff --git a/hugo/content/components/classic/documentation/how-can-i-support-priority-queues.md b/hugo/content/components/classic/documentation/how-can-i-support-priority-queues.md new file mode 100644 index 0000000000..51d46bfc35 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-can-i-support-priority-queues.md @@ -0,0 +1,53 @@ +--- +title: How can I support priority queues +layout: classic-doc +--- + + + +How can I support priority queues? +---------------------------------- + +### Use Message Priority + +A common requirement is to support priority consumption; so high priority messages are consumed before low priority. + +In version 5.4 priority queues are supported. Both the message cursors and the message stores (KahaDB and JDBC) support message priority. The support is disabled by default so it needs to be be enabled using [per destination policies](per-destination-policies) through xml configuration, in the example below, 'prioritizedMessages' is enabled for all queues. +``` + + + + + ... +``` +The full range of priority values (0-9) are supported by the [JDBC](jdbc-support) message store. For [KahaDB](Persistence/kahadb) three priority categories are supported, Low (< 4), Default (= 4) and High (> 4). + +Since the message cursors (and client side) implement strict ordering of priorities, it's possible to observe strict priority ordering if message dispatching can happen from the cache and not have to hit the disk (i.e., your consumers are fast enough to keep up with producers), or if you're using non-persistent messages that never have to flush to disk (using the FilePendingMessageCursor). However, once you hit a situation where consumers are slow, or producers are just significantly faster, you'll observe that the cache will fill up (possibly with lower priority messages) while higher priority messages get stuck on disk and not available until they're paged in. In this case, you can make a decision to tradeoff optimized message dispatching for priority enforcement. You can disable the cache, message expiration check, and lower you consumer prefetch to 1 to ensure getting the high priority messages from the store ahead of lower priority messages Note, this sort of tradeoff can have significant performance implications, so you must test your scenarios thoroughly. : +``` + + + + + ... +``` + +### Alternative strategies + +#### Use Selectors + +You can have say 100 consumers using a selector to find the high priority stuff +``` +JMSPriority > 6 +``` +then have 50 consumers doing average or above +``` +JMSPriority >= 4 +``` +Then say 10 consumers consuming all messages (so all priorities). Then this way you'll have a pool of threads always processing high priority messages - giving you very efficient priority based dispatching of messages without ActiveMQ Classic having to batch up messages and reorder them before dispatching them. + +#### Use Resequencer + +You can reorder messages on some input queue A and send them to queue B in sorted order to avoid having to change your clients. This avoids the need to use selectors in your application as shown above. + +To do this use the [Resequencer](http://activemq.apache.org/camel/resequencer.html) from the [Enterprise Integration Patterns](enterprise-integration-patterns) + diff --git a/hugo/content/components/classic/documentation/how-can-i-use-different-network-protocols.md b/hugo/content/components/classic/documentation/how-can-i-use-different-network-protocols.md new file mode 100644 index 0000000000..1846308bf9 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-can-i-use-different-network-protocols.md @@ -0,0 +1,9 @@ +--- +title: How can I use different network protocols +layout: classic-doc +--- + + + +For easy configuration, ActiveMQ Classic supports a configurable URL to denote the connection mechanism to other clients. There is an example of how to do this along with a description of the available protocols in the [Protocols overview](uri-protocols) + diff --git a/hugo/content/components/classic/documentation/how-do-distributed-queues-work.md b/hugo/content/components/classic/documentation/how-do-distributed-queues-work.md new file mode 100644 index 0000000000..b3e3e25581 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-distributed-queues-work.md @@ -0,0 +1,56 @@ +--- +title: How do distributed queues work +layout: classic-doc +--- + + + +There are various [Topologies](topologies) that you can employ with ActiveMQ Classic, where clients are connected to message brokers in various ways like + +* peer based +* client server +* hub and spoke + +Each client communicates with a broker using some kind of [client library and network protocol](cross-language-clients). + +To create distributed queues or topics we need to have the message brokers communicate with each other. There are two different types of broker to broker communication... + +Master/Slave for High Availability +---------------------------------- + +A [Master/Slave Cluster](masterslave) is used for [HA](ha). Basically it means that all messages are replicated across each broker in the master/slave cluster. If the Master goes down, the clients can automatically failover to a slave which will have all the messages already, so each message is highly available. The Slave(s) provide a hot standby broker which will always be in sync ready to take over if the master goes away due to hardware failure etc. + +Master/Slave works by having some form of replication; each message is owned by every broker in the logical cluster. A master/slave cluster then acts as one logical message broker which could then be connected via store and forward to other brokers (as we'll see in the next section). + +### Distributed Queues and Topics + +In Master/Slave, queues and topics are all replicated between each broker in the cluster (so often to a master and maybe a single slave). So each broker in the cluster has exactly the same messages available at any time so if a master fails, clients failover to a slave and you don't loose a message. + +Store and forward networks of brokers +------------------------------------- + +A [Store and Forward Network of Brokers](networks-of-brokers) means the messages travel from broker to broker until they reach a consumer; with each message being owned by a single broker at any point in time. When a JMS producer sends a message to a JMS consumer, it may travel through several brokers to reach its final destination. ActiveMQ Classic uses [Consumer Priority](consumer-priority) so that local JMS consumers are always higher priority than remote brokers in a store and forward network. + +Note though that a store and forward network is not a solution for message [HA](ha); if a broker fails in a Store and Forward network, the messages owned by that broker remain inside the broker's persistent store until the broker comes back online. If you need [HA](ha) of messages then you need to use Master/Slave described above. + +Store and forward is often used in large networks where producers are on one LAN and consumers are on another LAN and you wish to use a broker on each LAN as a kind of network concentrator to minimise chattiness over the WAN between them (and to minimise the number of connections required across the WAN too). Similar uses of store and forward can be found when using firewalls or SSL across certain networks etc. One other use case for store and forward networks is if your OS does not support many sockets (and you can't reconfigure that) you could use a store and forward network to connect massive numbers of clients together in one logical network. + +### Distributed Queues in Store/Forward + +When we publish a message on a queue, it is stored in the persistent store of the broker that the publisher is communicating. Then if that broker is configured to store/foward to other brokers and clients, the broker will send it to _one_ of these clients (which could be a node or a broker depending on the dispatch algorithm). This dispatch algorithm continues until the message is finally dispatched and consumed by a client. + +At any point in time the message will only exist in one broker's store until its consumed. Note that messages are only distributed onto other brokers if there is a consumer on those brokers. + +e.g. if we had broker A, B, C and a publisher on a queue on A. If we have consumers on the queue on A and B then messages for the queue will be spread across both brokers A and B; some messages going to B, some being consumed on A, none going to C. If a consumer on the queue starts on C, then messages will flow there too. If the consumer stops then no more messages will be dispatched to C. + +Distributed Topics in Store/Forward +----------------------------------- + +For topics the above algorithm is followed except, every interested client receives a copy of the message - plus ActiveMQ Classic will check for loops (to avoid a message flowing infinitely around a ring of brokers). + +### See Also + +* [How do I configure distributed queues or topics](how-do-i-configure-distributed-queues-or-topics) +* [MasterSlave](masterslave) +* [Networks of Brokers](networks-of-brokers) + diff --git a/hugo/content/components/classic/documentation/how-do-durable-queues-and-topics-work.md b/hugo/content/components/classic/documentation/how-do-durable-queues-and-topics-work.md new file mode 100644 index 0000000000..d5d452034b --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-durable-queues-and-topics-work.md @@ -0,0 +1,21 @@ +--- +title: How do durable queues and topics work +layout: classic-doc +--- + + + +Durable queues keep messages around persistently for any suitable consumer to consume them. Durable queues do not need to concern themselves with which consumer is going to consume the messages at some point in the future. There is just one copy of a message that any consumer in the future can consume. + +Durable topics however are different as they must logically persist an instance of each suitable message for every durable consumer - since each durable consumer gets their own copy of the message. + +For example imagine a durable subscriber S starts up subscribing to topic T at time D1. Some publisher sends messages M1, M2, M3 to the topic and S will receive each of these messages. Then S is stopped and the publisher continues to send M4, M5. + +When S restarts at D2, the publisher sends M6 and M7. Now S will receive M4, M5 followed by M6 and M7 and all future messages. i.e. S will receive all messages from M1..M7. + +This is the difference between durable and non-durable consuming. If S were a non-durable consumer then it would only have received M1, M2, M3 and M6, M7 - not M4 and M5. i.e. because the subscription is durable, S will receive every message sent to T whether the subscriber is running or not. For non-durable topics, only messages delivered to the topic T when S is running are delivered. + +So for durable topic subscription, the JMS provider needs to be able to identify S when it shuts down and later on in the future reconnects, so it can know what messages to send to it while it was not running. JMS specification dictates that the identification of S is done by a combination of the clientID and the durable subscriber name. This is so that the JMS connection S uses can have many different durable subscriptions on different topics or on the same topic with different selectors - yet the JMS provider can know which message for which subscription to keep around for it. + +So setting the clientID on a JMS connection is vital (along with using a sensible durable consumer name) for durable topic subscription. Its not an issue for other [QoS](qos) + diff --git a/hugo/content/components/classic/documentation/how-do-i-access-activemq-classic-from-c.md b/hugo/content/components/classic/documentation/how-do-i-access-activemq-classic-from-c.md new file mode 100644 index 0000000000..2be3089623 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-access-activemq-classic-from-c.md @@ -0,0 +1,9 @@ +--- +title: How do I access ActiveMQ Classic from C +layout: classic-doc +--- + + + +See the [C Integration](c-integration) page for the available options. + diff --git a/hugo/content/components/classic/documentation/how-do-i-access-activemq-classic-from-csharp-or-dotnet.md b/hugo/content/components/classic/documentation/how-do-i-access-activemq-classic-from-csharp-or-dotnet.md new file mode 100644 index 0000000000..37e3f44194 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-access-activemq-classic-from-csharp-or-dotnet.md @@ -0,0 +1,9 @@ +--- +title: How do I access ActiveMQ Classic from CSharp or dotNet +layout: classic-doc +--- + + + +Unable to render {include} The included page could not be found. + diff --git a/hugo/content/components/classic/documentation/how-do-i-access-activemq-classic-from-ruby-perl-python-php.md b/hugo/content/components/classic/documentation/how-do-i-access-activemq-classic-from-ruby-perl-python-php.md new file mode 100644 index 0000000000..b72fdd9bb5 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-access-activemq-classic-from-ruby-perl-python-php.md @@ -0,0 +1,9 @@ +--- +title: How do I access ActiveMQ Classic from Ruby, Perl, Python, PHP +layout: classic-doc +--- + + + +Use [Stomp](http://stomp.codehaus.org/) which is a simple to implement client protocol for working with ActiveMQ Classic and other messaging systems. + diff --git a/hugo/content/components/classic/documentation/how-do-i-add-my-own-plugins.md b/hugo/content/components/classic/documentation/how-do-i-add-my-own-plugins.md new file mode 100644 index 0000000000..996bce321e --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-add-my-own-plugins.md @@ -0,0 +1,8 @@ +--- +title: How do I add my own plugins +layout: classic-doc +--- + + + +See [Developing Plugins](developing-plugins) for how to add your own functionality into Apache ActiveMQ Classic. \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/how-do-i-avoid-maven-downloading-latest-jars.md b/hugo/content/components/classic/documentation/how-do-i-avoid-maven-downloading-latest-jars.md new file mode 100644 index 0000000000..b80aaefbca --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-avoid-maven-downloading-latest-jars.md @@ -0,0 +1,15 @@ +--- +title: How do I avoid Maven downloading latest jars +layout: classic-doc +--- + + + +You can use the -o switch (for offline mode) to avoid maven auto-downloading new snapshot jars (e.g. the Geronimo jars at the time of writing). +``` +maven -o +``` +or to run a server go to the \\assembly module and run +``` +maven -o server +``` \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/how-do-i-back-up-kahadb.md b/hugo/content/components/classic/documentation/how-do-i-back-up-kahadb.md new file mode 100644 index 0000000000..911f7b9d85 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-back-up-kahadb.md @@ -0,0 +1,14 @@ +--- +title: How do I back-up KahaDB +layout: classic-doc +--- + + + +In creating a backup, there may be an issue with the lock file, or with an inuse journal file. The lock file is not important but you would want the latest journal files. + +1. Freeze the filesystem containing the database to ensure that you get a consistent snapshot of the journal. +2. Back-up the database using any of the standard back-up mechanisms. + +Batch writes are serialised and followed by an fsync, so the fsfreeze will either block the next write or the next fsync. Either way is fine from a consistency point of view. The index is checkpointed to the journal periodically, so recovery of the index will at worst be from the last know good state. + diff --git a/hugo/content/components/classic/documentation/how-do-i-bridge-different-jms-providers.md b/hugo/content/components/classic/documentation/how-do-i-bridge-different-jms-providers.md new file mode 100644 index 0000000000..4b88bd0a93 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-bridge-different-jms-providers.md @@ -0,0 +1,11 @@ +--- +title: How do I bridge different JMS providers +layout: classic-doc +--- + + + +To bridge from ActiveMQ Classic to another JMS provider use the [JMS bridge](jms-to-jms-bridge). + +To bridge to another kind of transport completely, use [Camel](http://camel.apache.org) or [ServiceMix](http://servicemix.apache.org) + diff --git a/hugo/content/components/classic/documentation/how-do-i-build-but-disable-the-unit-tests.md b/hugo/content/components/classic/documentation/how-do-i-build-but-disable-the-unit-tests.md new file mode 100644 index 0000000000..f85aa1a782 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-build-but-disable-the-unit-tests.md @@ -0,0 +1,16 @@ +--- +title: How do I build but disable the unit tests +layout: classic-doc +--- + + + +How do I build but disable the unit tests +----------------------------------------- + +The test cases in ActiveMQ Classic can take a very long time to run! + +To disable this you can try the following +``` +mvn install -Dmaven.test.skip=true +``` \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/how-do-i-change-dispatch-policy.md b/hugo/content/components/classic/documentation/how-do-i-change-dispatch-policy.md new file mode 100644 index 0000000000..405973bd35 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-change-dispatch-policy.md @@ -0,0 +1,34 @@ +--- +title: How do I change dispatch policy +layout: classic-doc +--- + + + +This is much simpler and more powerful in ActiveMQ Classic 4.0 - you can configure different [Dispatch Policies](dispatch-policies) directly. + +For now in ActiveMQ Classic 3.x we have a [PrefetchPolicy configuration](what-is-the-prefetch-limit-for). This allows a certain number of messages to be dispatched to a consumer before they are acknowledged. This feature is to achieve high performance; the higher the value the less likely it is that a client has to wait for messages to arrive before processing the message and so the higher the throughput. + +e.g. under heavy load of a busy system you probably want to dispatch 1000 or so messages to a consumer, so as soon as its ready to receive a message, there are a bunch of them in memory waiting to be used - rather than having a slow request-response RPC each time. + +However the effect of this is that when you send a small number of messages, they tend to all go to one consumer unless you've lots of messages. Note that this issue can be avoided in 4.x as there is now a configurable DispatchPolicy so that you can enforce, say, round robin dispatch policy to ensure that messages are dispatched fairly to avoid this issue. + +In ActiveMQ Classic 3.x or later a work around for this issue is to reconfigure the PrefetchPolicy on the ConnectionFactory/Connection so that the broker only prefetches a single message per consumer; though this will greatly reduce the performance and throughput of the system. + +### Configuring the dispatch policy in ActiveMQ Classic 4.x + +In AMQ 4.x, the dispatch policy can now be configured on the xml configuration file (ie. activemq.xml) i.e.: +``` + + + + + + + + + + + + +``` diff --git a/hugo/content/components/classic/documentation/how-do-i-change-the-logging.md b/hugo/content/components/classic/documentation/how-do-i-change-the-logging.md new file mode 100644 index 0000000000..2bac902e50 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-change-the-logging.md @@ -0,0 +1,123 @@ +--- +title: How do I change the logging +layout: classic-doc +--- + + + +How do I change the logging +--------------------------- + +We use slf4j to log information in the broker client and the broker itself so you can fully configure which logging levels are used and whether to log to files or the console etc. For more information see the [log4j manual](http://logging.apache.org/log4j/docs/manual.html). + +You can disable the ActiveMQ Classic logging by editing the **conf/log4j.properties** file to disable all INFO level logging for activemq by adding this line +``` +log4j.logger.org.apache.activemq=WARN +``` +or to disable stdout logging all together change this line +``` +log4j.rootLogger=INFO, stdout, out +``` +to +``` +log4j.rootLogger=INFO, out +``` + +How Do I Change the Logging at Runtime? +--------------------------------------- + +The default logging level in ActiveMQ Classic is INFO. This can be seen by starting up the default ActiveMQ Classic binary in a terminal. In doing so, you will see the output shown below: +``` +$ ./bin/activemq +ACTIVEMQ_HOME: /Users/bsnyder/amq/apache-activemq-5.1.0 +ACTIVEMQ_BASE: /Users/bsnyder/amq/apache-activemq-5.1.0 +Loading message broker from: xbean:activemq.xml +INFO BrokerService - Using Persistence Adapter: AMQPersistenceAdapter(/Users/bsnyder/amq/apache-activemq-5.1.0/data) +INFO BrokerService - ActiveMQ 5.1.0 JMS Message Broker (localhost) is starting +INFO BrokerService - For help or more information please see: http://activemq.apache.org/ +INFO AMQPersistenceAdapter - AMQStore starting using directory: /Users/bsnyder/amq/apache-activemq-5.1.0/data +INFO KahaStore - Kaha Store using data directory /Users/bsnyder/amq/apache-activemq-5.1.0/data/kr-store/state +INFO AMQPersistenceAdapter - Active data files: [] +INFO KahaStore - Kaha Store using data directory /Users/bsnyder/amq/apache-activemq-5.1.0/data/kr-store/data +INFO TransportServerThreadSupport - Listening for connections at: tcp://mongoose.local:61616 +INFO TransportConnector - Connector openwire Started +INFO TransportServerThreadSupport - Listening for connections at: ssl://mongoose.local:61617 +INFO TransportConnector - Connector ssl Started +INFO TransportServerThreadSupport - Listening for connections at: stomp://mongoose.local:61613 +INFO TransportConnector - Connector stomp Started +INFO TransportServerThreadSupport - Listening for connections at: xmpp://mongoose.local:61222 +INFO TransportConnector - Connector xmpp Started +INFO NetworkConnector - Network Connector default-nc Started +INFO BrokerService - ActiveMQ JMS Message Broker (localhost, ID:mongoose.local-56138-1224025139259-0:0) started +INFO log - Logging to org.slf4j.impl.JCLLoggerAdapter(org.mortbay.log) via org.mortbay.log.Slf4jLog +INFO log - jetty-6.1.9 +INFO WebConsoleStarter - ActiveMQ WebConsole initialized. +INFO /admin - Initializing Spring FrameworkServlet 'dispatcher' +INFO log - ActiveMQ Console at http://0.0.0.0:8161/admin +INFO log - ActiveMQ Web Demos at http://0.0.0.0:8161/demo +INFO log - RESTful file access application at http://0.0.0.0:8161/fileserver +INFO log - Started SelectChannelConnector@0.0.0.0:8161 +INFO FailoverTransport - Successfully connected to tcp://localhost:61616 +``` +But stopping ActiveMQ Classic to change the logging level is not always feasible. There are many cases where the logging level and other configuration details may need to be changed at runtime. Using a JMX tool such as jconsole, the logging configuration file can be changed and reloaded without shutting down ActiveMQ Classic. + +To change the ActiveMQ Classic logging level from INFO to DEBUG while ActiveMQ Classic is running, start up jconsole, point to the ActiveMQ Classic instance and navigate to the Broker object's Operations tab as shown below: + +![](assets/img/reloadLog4jProperties1.png) + +To enable debug level logging in ActiveMQ Classic, edit the `conf/log4j.properties` file that is part of the ActiveMQ Classic binary distribution to disable INFO level logging and enable DEBUG level logging from this: +``` +log4j.rootLogger=INFO, stdout, out +log4j.logger.org.apache.activemq.spring=WARN +log4j.logger.org.springframework=WARN +log4j.logger.org.apache.xbean.spring=WARN + +# When debugging or reporting problems to the ActiveMQ team, +# comment out the above lines and uncomment the next. + +#log4j.rootLogger=DEBUG, out, stdout +``` +to this: +``` +#log4j.rootLogger=INFO, stdout, out +log4j.logger.org.apache.activemq.spring=WARN +log4j.logger.org.springframework=WARN +log4j.logger.org.apache.xbean.spring=WARN + +# When debugging or reporting problems to the ActiveMQ team, +# comment out the above lines and uncomment the next. + +log4j.rootLogger=DEBUG, out, stdout +``` +Notice that the line `log4j.rootLogger=INFO, stdout, out` has been commented out and the line `log4j.rootLogger=DEBUG, out, stdout` has been uncommented. Save this change and then, in jconsole, click the button named **reloadLog4jProperties** as shown below: + +![](assets/img/reloadLog4jProperties2.png) + +After clicking the **reloadLog4jProperties** button, the dialog pops up stating, 'Method successfully invoked'. This just lets you know that the `reloadLog4jProperties` method was invoked to reload the `conf/log4j.properties` file. Now notice in the terminal where ActiveMQ Classic is running that the logging that is being output is now DEBUG: +``` +INFO WebConsoleStarter - ActiveMQ WebConsole initialized. +INFO /admin - Initializing Spring FrameworkServlet 'dispatcher' +INFO log - ActiveMQ Console at http://0.0.0.0:8161/admin +INFO log - ActiveMQ Web Demos at http://0.0.0.0:8161/demo +INFO log - RESTful file access application at http://0.0.0.0:8161/fileserver +INFO log - Started SelectChannelConnector@0.0.0.0:8161 +INFO FailoverTransport - Successfully connected to tcp://localhost:61616 +DEBUG InactivityMonitor - 10000 ms elapsed since last write check. +DEBUG InactivityMonitor - 10000 ms elapsed since last write check. +DEBUG AbstractRegion - Removing consumer: ID:mongoose.local-56517-1224026019987-0:0:-1:1 +DEBUG AbstractRegion - Removing consumer: ID:mongoose.local-56511-1224026011897-0:0:1:1 +DEBUG TransportConnection - Stopping connection: /127.0.0.1:56518 +DEBUG TcpTransport - Stopping transport tcp:///127.0.0.1:56518 +DEBUG TransportConnection - Stopped connection: /127.0.0.1:56518 +DEBUG TransportConnection - Connection Stopped: /127.0.0.1:56518 +DEBUG AbstractRegion - Removing consumer: ID:mongoose.local-56511-1224026011897-0:0:-1:1 +DEBUG TransportConnection - Stopping connection: /127.0.0.1:56512 +DEBUG TcpTransport - Stopping transport tcp:///127.0.0.1:56512 +DEBUG TransportConnection - Stopped connection: /127.0.0.1:56512 +DEBUG TransportConnection - Connection Stopped: /127.0.0.1:56512 +DEBUG InactivityMonitor - 9999 ms elapsed since last write check. +DEBUG InactivityMonitor - 10000 ms elapsed since last write check. +DEBUG InactivityMonitor - 29999 ms elapsed since last read check. +``` +Disabling `DEBUG` level logging and enabling `INFO` level logging is done by editing the `log4j.properties` file and clicking the **reloadLog4jProperties** button again. + diff --git a/hugo/content/components/classic/documentation/how-do-i-change-the-message-store-directory-for-an-embedded-broker.md b/hugo/content/components/classic/documentation/how-do-i-change-the-message-store-directory-for-an-embedded-broker.md new file mode 100644 index 0000000000..74c6216b1f --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-change-the-message-store-directory-for-an-embedded-broker.md @@ -0,0 +1,13 @@ +--- +title: How do I change the message store directory for an embedded broker +layout: classic-doc +--- + + + +Embedded brokers create an ActiveMQ Classic directory under the current working directory to store it's persistent message data. To change the location of the directory used by the message store, set the **activemq.store.dir** system property to the directory you want it to use. + +Example: +``` +java -Dactivemq.store.dir=/temp your.Application +``` \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/how-do-i-compile-from-the-source.md b/hugo/content/components/classic/documentation/how-do-i-compile-from-the-source.md new file mode 100644 index 0000000000..56a78fc6a9 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-compile-from-the-source.md @@ -0,0 +1,12 @@ +--- +title: How do I compile from the source +layout: classic-doc +--- + + + +How do I compile from the source code? +-------------------------------------- + +See the [Building](building) page + diff --git a/hugo/content/components/classic/documentation/how-do-i-configure-10s-of-1000s-of-queues-in-a-single-broker.md b/hugo/content/components/classic/documentation/how-do-i-configure-10s-of-1000s-of-queues-in-a-single-broker.md new file mode 100644 index 0000000000..84548a8de0 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-configure-10s-of-1000s-of-queues-in-a-single-broker.md @@ -0,0 +1,42 @@ +--- +title: How do I configure 10s of 1000s of Queues in a single broker +layout: classic-doc +--- + + +Scaling to tens of thousands of Queues in a single broker is relatively straightforward - but requires some configuration changes from the default. + +Reducing Threads +---------------- + +With the default configuration, ActiveMQ Classic is configured to use a dispatch thread per Queue - you can use set the optimizedDispatch property on the destination policy entry - see [configuring Queues](per-destination-policies). + +ActiveMQ Classic can optionally use internally a thread pool to control dispatching of messages - but as a lot of deployment operating systems are good at handling a large number of threads, this is off by default. To enable this option, either set the ACTIVEMQ_OPTS to disable dedicated task runners in the start up script, INSTALL\_DIR/bin/activemq -e.g. +``` +ACTIVEMQ_OPTS="-Xmx512M -Dorg.apache.activemq.UseDedicatedTaskRunner=false" +``` +or you can set `ACTIVEMQ_OPTS` in `/etc/activemq.conf`. + +**Note:** From ActiveMQ Classic 5.6 onwards the dedicated task runner is disabled by default (see jira-issue [AMQ-3667](https://issues.apache.org/jira/browse/AMQ-3667)). + +To reduce the number of threads used for the transport - take a look at using the NIO transport - see [Configuring Transports](configuring-transports) + +Here is an [example](http://svn.apache.org/repos/asf/activemq/trunk/assembly/src/sample-conf/activemq-scalability.xml) of this in use in one of the provided sample broker configuration files. + +Reducing Memory Consumption +--------------------------- + +Reduce the memory used per thread - see [reducing memory consumption](javalangoutofmemory) + +Reduce number of file descriptors +--------------------------------- + +ActiveMQ Classic uses the `amqPersistenceAdapter` by default for persistent messages. Unfortunately, this persistence adapter (as well as the kahaPersistenceAdapter) opens a file descriptor for each queue. When creating large numbers of queues, you'll quickly run into the limit for your OS. + +You can either choose another [persistence option](persistence) or - try out the new [KahaDB](kahadb) in version 5.3 and higher + +Increase the limit on file descriptors per process +-------------------------------------------------- + +Try [googling for the OS you are using](http://tinyurl.com/o9qs2f) + diff --git a/hugo/content/components/classic/documentation/how-do-i-configure-activemq-classic-to-hold-100s-of-millions-of-queue-messages.md b/hugo/content/components/classic/documentation/how-do-i-configure-activemq-classic-to-hold-100s-of-millions-of-queue-messages.md new file mode 100644 index 0000000000..a80dcd33ff --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-configure-activemq-classic-to-hold-100s-of-millions-of-queue-messages.md @@ -0,0 +1,15 @@ +--- +title: How do I configure ActiveMQ Classic to hold 100s of millions of Queue Messages? +layout: classic-doc +--- + + + +Nearly all messaging systems (certainly open source ones) hold either a copy of a persistent message or a reference to a persisted message in memory. This is primarily to try and improve performance, but it also can significantly decrease the complexity of implementation. In fact ActiveMQ Classic version 4 and below worked this - way - by holding references to persisted messages in memory. + +However there is a limitation to this approach, no matter how much memory you have at your disposal, you will hit a limit to the number persistent messages a broker can handle at any particular time. + +To get around this limitation, ActiveMQ Classic introduced a paging cache - for all message stores (except the memory store) to get the best of both worlds - great performance and the ability to hold 100s of millions of messages in persistent store. ActiveMQ Classic is **not** limited by memory availability, but by the size of the disk available to hold the persistent messages. + +For more information see: [Message Cursors](message-cursors) + diff --git a/hugo/content/components/classic/documentation/how-do-i-configure-activemq-classic-to-use-aio-server-transport.md b/hugo/content/components/classic/documentation/how-do-i-configure-activemq-classic-to-use-aio-server-transport.md new file mode 100644 index 0000000000..9676e1c490 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-configure-activemq-classic-to-use-aio-server-transport.md @@ -0,0 +1,45 @@ +--- +title: How do I configure ActiveMQ Classic to use AIO server transport +layout: classic-doc +--- + + + +For Windows XP: + +1. Download AIO (Asynchronous IO for Java) from IBM ([http://www.alphaworks.ibm.com/tech/aio4j](http://www.alphaworks.ibm.com/tech/aio4j)). + +2. Unzip the downloaded file and copy the following files: + + * ibmaio.dll + * ibmaio-1.0.jar + +3. Place ibmaio.dll into Windows System32 folder. (You may need to restart afterwards for this to take effect) + +4. Include ibmaio-1.0.jar in the classpath. + +5. Edit ActiveMQ Classic's configuration file (**activemq.xml**, found in the conf folder). Look the following snippet: + ``` + + + + + + + + . + . + + ``` + Change the connector settings, change **tcpServerTransport** to **serverTransport** and remove the unneeded parameters): + ``` + + + + ``` + Example: + ``` + + + + ``` \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/how-do-i-configure-automatic-reconnection.md b/hugo/content/components/classic/documentation/how-do-i-configure-automatic-reconnection.md new file mode 100644 index 0000000000..e69a75d428 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-configure-automatic-reconnection.md @@ -0,0 +1,17 @@ +--- +title: How do I configure automatic reconnection +layout: classic-doc +--- + + + +If a JMS broker goes down, ActiveMQ Classic can automatically reconnect to an available JMS broker using the `failover:` protocol. Not only does this automatically reconnect, it will also resume any temporary destinations, sessions, producers and most importantly consumers. + +All of this happens silently inside the JMS client so you don't need to worry about it in your application code. + +e.g. connecting to the URL +``` +failover:tcp://host1:port1,tcp://host2:port2 +``` +For more detail see [Failover Transport Reference](failover-transport-reference) + diff --git a/hugo/content/components/classic/documentation/how-do-i-configure-distributed-queues-or-topics.md b/hugo/content/components/classic/documentation/how-do-i-configure-distributed-queues-or-topics.md new file mode 100644 index 0000000000..67feca7a1b --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-configure-distributed-queues-or-topics.md @@ -0,0 +1,24 @@ +--- +title: How do I configure distributed queues or topics +layout: classic-doc +--- + + + +How do I configure distributed queues or topics +----------------------------------------------- + +You don't need to explicitly [configure distributed queues or topics](how-do-i-configure-the-queues-i-want) as any queue or topic is automatically distributed across other brokers when the brokers are configured in either a store and forward network or a master/slave cluster. + +So you just need to connect brokers together to form either + +* a [Store and Forward Network of Brokers](networks-of-brokers), which means the messages travel from broker to broker until they reach a consumer; with each message being owned by a single broker at any point in time +* a [Master/Slave Cluster](masterslave), which means all messages are replicated across each broker in the master/slave cluster + +### Also see + +* [How do I configure the queues I want](how-do-i-configure-the-queues-i-want) +* [How do distributed queues work](how-do-distributed-queues-work) +* [Networks of Brokers](networks-of-brokers) +* [MasterSlave](masterslave) + diff --git a/hugo/content/components/classic/documentation/how-do-i-configure-the-queues-i-want.md b/hugo/content/components/classic/documentation/how-do-i-configure-the-queues-i-want.md new file mode 100644 index 0000000000..fcca4ae14a --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-configure-the-queues-i-want.md @@ -0,0 +1,15 @@ +--- +title: How do I configure the queues I want +layout: classic-doc +--- + + + +The license could not be verified: License Certificate has expired! + +With ActiveMQ Classic there is no real resaon to explicitly setup/configure the queues you are gonna need. If you try to publish or subscribe from any queue or topic it will be silently created on the fly. + +Sometimes people put destinations into JNDI so that they can be pulled out by their application without needing to know the real, physical queue/topic name. This is fine, you can just add the ActiveMQQueue and ActiveMQTopic objects into JNDI (or any configuration mechanism you wish). + +Also if you use the ActiveMQInitialContextFactory, then you can explicitly configure which destinations appear in the context using the jndi.properties approach. For more information please refer to the [JNDI Support](jndi-Community/support) + diff --git a/hugo/content/components/classic/documentation/how-do-i-connect-to-one-of-a-number-of-message-brokers.md b/hugo/content/components/classic/documentation/how-do-i-connect-to-one-of-a-number-of-message-brokers.md new file mode 100644 index 0000000000..ea01dc39de --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-connect-to-one-of-a-number-of-message-brokers.md @@ -0,0 +1,13 @@ +--- +title: How do I connect to one of a number of message brokers +layout: classic-doc +--- + + + +You can specify a list of URLs to connect to (for example if you have message brokers running on a number of machines). To specify a list of URLs, use a comma separated list of URLs with a prefix of list:. e.g. +``` +list:tcp://localhost:61699,tcp://localhost:61617,tcp://localhost:61698 +``` +The JMS client will then try and connect to each one in turn, in a random order until one is connected. If they all fail to connect a sleep occurs and then this loop is retried a number of times until either a connection can be established or an exception is thrown. For more detail see [Configuring Transports](configuring-transports) + diff --git a/hugo/content/components/classic/documentation/how-do-i-consume-a-specific-message.md b/hugo/content/components/classic/documentation/how-do-i-consume-a-specific-message.md new file mode 100644 index 0000000000..e8240ee882 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-consume-a-specific-message.md @@ -0,0 +1,20 @@ +--- +title: How do I consume a specific message +layout: classic-doc +--- + + + +If you want to consume messages in a different order, or consume specific messages at the head, middle or tail of the queue, you can + +* browse the messages using the QueueBrowser to find the JMSMessageID's of the messages you want to consume +* create a new consumer with a selector matching the ID(s) you want. + +e.g. here is an example selector +``` +JMSMessageID = 'abc' +``` +Note that this is not a very efficient way of working with JMS (JMS is designed for consumers to be long lived objects working across many messageS), but it can be useful in certain situations. + +Another option is just to use [JMX](jmx) directly to browse messages on a queue, process them and then delete them. + diff --git a/hugo/content/components/classic/documentation/how-do-i-create-new-destinations.md b/hugo/content/components/classic/documentation/how-do-i-create-new-destinations.md new file mode 100644 index 0000000000..b6a33b9f75 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-create-new-destinations.md @@ -0,0 +1,35 @@ +--- +title: How do I create new destinations +layout: classic-doc +--- + + + +In ActiveMQ Classic you do **not** have to create destinations up front before you can use them. The ActiveMQ Classic broker auto-creates the physical resources associated with a destination on demand (i.e. when messages are sent to a new destination on a broker). + +This means that a client can create a new Queue or Topic dynamically either by + +* calling createQueue() or createTopic() on a JMS Session +* creating an instance of ActiveMQTopic or ActiveMQQueue and possibly registering them in JNDI + +and the broker will automatically create the physical destinations for you. This avoids spending large amounts of time creating every individual destination you wish to use and possibly then exposing it in some JNDI provider. + +In addition, if you are using JNDI to lookup connection factory and destinations, you can specify which destinations you wish to create by default using the properties file. See the [JNDI Support](jndi-support) for more details. + +### Creating destinations on startup + +Its completely optional but as of 4.1 you can [Configure Startup Destinations](configure-startup-destinations) to specify which destinations are automatically created when the broker starts. + +### Limiting creation of destinations + +If you need to restrict access or creation of destinations then please use the [Security](security) option to disable destinations being auto-created for certain users. + +Client side destination objects are not the same as server side resources + +Note that the ActiveMQ Classic Broker will only create server side resources for destinations when messages are actually sent to them. So you can create as many instances of ActiveMQTopic and ActiveMQQueue on a client without any real overhead until you actually send messages to them on a broker. So a JMS client creating a new ActiveMQQueue POJO does not mean you are creating server side queue resources. + +Think of the ActiveMQQueue and ActiveMQTopic classes as like java.net.URL. They are just names which refer to server side resources which are auto-created when they are used. +This means that different clients creating different ActiveMQQueue instances will communicate with the same physical queue on a JMS broker if the name is the same. + +You can browse the currently available queues and topics using [JMX](jmx). You can also use the [JMX](jmx) MBeans to create the destinations you require. + diff --git a/hugo/content/components/classic/documentation/how-do-i-debug-activemq-classic-from-my-ide.md b/hugo/content/components/classic/documentation/how-do-i-debug-activemq-classic-from-my-ide.md new file mode 100644 index 0000000000..d355c18799 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-debug-activemq-classic-from-my-ide.md @@ -0,0 +1,13 @@ +--- +title: How do I debug ActiveMQ Classic from my IDE +layout: classic-doc +--- + + + +One option is to run your broker in the same JVM as your application; see [How To Unit Test JMS Code](how-to-unit-test-jms-code). + +Or you can try uncommenting ACTIVEMQ_DEBUG_OPTS in your activemq start script (bin/activemq or bin\activemq.bat) and start remote debugging in your IDE. + +For IDEA, see this article [http://www.javaranch.com/journal/200408/DebuggingServer-sideCode.html](http://www.javaranch.com/journal/200408/DebuggingServer-sideCode.html) + diff --git a/hugo/content/components/classic/documentation/how-do-i-define-a-local-address-and-local-port-for-tcp-or-ssl.md b/hugo/content/components/classic/documentation/how-do-i-define-a-local-address-and-local-port-for-tcp-or-ssl.md new file mode 100644 index 0000000000..069e563ebd --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-define-a-local-address-and-local-port-for-tcp-or-ssl.md @@ -0,0 +1,16 @@ +--- +title: How do I define a local address and local port for TCP or SSL +layout: classic-doc +--- + + + +TCP based transport protocols (including SSL) allow you to define the local address and local port for Socket to use when it's created. +This can be useful for clients that reside on multi-homed machines or for clients operating in a DMZ, where only pre-defined ports can be used. + +To specify the local address and local port, ActiveMQ Classic supports the use of the path on the URI, e.g. +``` +ssl://localhost:5666/localhost:60606 +``` +where the path following the forward slash "localhost:60606" defines the local address and local port + diff --git a/hugo/content/components/classic/documentation/how-do-i-delete-a-destination.md b/hugo/content/components/classic/documentation/how-do-i-delete-a-destination.md new file mode 100644 index 0000000000..bf0deb2538 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-delete-a-destination.md @@ -0,0 +1,22 @@ +--- +title: How do I delete a destination +layout: classic-doc +--- + + + +How do I delete a destination +----------------------------- + +via Java code or [JMX](jmx) you can grab the [BrokerViewMBean](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/broker/jmx/BrokerViewMBean.html) and call one of the following methods + +* [removeQueue(String)](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/broker/jmx/BrokerViewMBean.html#removeQueue(java.lang.String)) +* [removeTopic(String)](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/broker/jmx/BrokerViewMBean.html#removeTopic(java.lang.String)) + +### See also + +* [How do I create new destinations](how-do-i-create-new-destinations) +* [How can I monitor ActiveMQ Classic](how-can-i-monitor-activemq-classic) +* [JMX](jmx) +* [Web Console](web-console) + diff --git a/hugo/content/components/classic/documentation/how-do-i-disable-logging.md b/hugo/content/components/classic/documentation/how-do-i-disable-logging.md new file mode 100644 index 0000000000..45b9a0acc1 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-disable-logging.md @@ -0,0 +1,12 @@ +--- +title: How do I disable logging +layout: classic-doc +--- + + + +How do I disable logging? +------------------------- + +See [How do I change the logging](how-do-i-change-the-logging) + diff --git a/hugo/content/components/classic/documentation/how-do-i-disable-persistence.md b/hugo/content/components/classic/documentation/how-do-i-disable-persistence.md new file mode 100644 index 0000000000..685c6ff2b0 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-disable-persistence.md @@ -0,0 +1,17 @@ +--- +title: How do I disable persistence +layout: classic-doc +--- + + + +There are three main ways to disable persistence, such as for unit testing JMS code + +1. Set the NON_PERSISTENT message delivery flag on your MessageProducer +2. Set the `persistent=false` flag in the `` element of the [Xml Configuration](xml-configuration) or on the property [BrokerService](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/broker/BrokerService.html) +3. Delete the persistence files before running your tests (a bit hacky) + +If you are unit testing you may be interested in [How To Unit Test JMS Code](how-to-unit-test-jms-code). + +Please refer to the [Initial Configuration](initial-configuration) guide on how to disable persistence via system properties, java code or using the [Xml Configuration](xml-configuration) + diff --git a/hugo/content/components/classic/documentation/how-do-i-embed-a-broker-inside-a-connection.md b/hugo/content/components/classic/documentation/how-do-i-embed-a-broker-inside-a-connection.md new file mode 100644 index 0000000000..4be22bd981 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-embed-a-broker-inside-a-connection.md @@ -0,0 +1,192 @@ +--- +title: How do I embed a Broker inside a Connection +layout: classic-doc +--- + + + +In many messaging topologies there are JMS Brokers (server side) and a JMS client side. Often it makes sense to deploy a broker within your JVM. This allows you to optimise away a network hop; making the networking of JMS as efficient as pure RMI, but with all the usual JMS features of location independence, reliability, load balancing etc. + +There are various ways to embed a broker in ActiveMQ Classic depending on if you are using Java, Spring, XBean or using the ActiveMQConnectionFactory . + +### Using explicit Java code + +The following Java code will create an embedded broker +``` +BrokerService broker = new BrokerService(); + +// configure the broker +broker.addConnector("tcp://localhost:61616"); + +broker.start(); +``` +If you want to lazily bind the transport connector as part of start(), useful when start() will block pending a store lock (as in a slave start), you can use the following code +``` +BrokerService broker = new BrokerService(); + +TransportConnector connector = new TransportConnector(); +connector.setUri(new URI("tcp://localhost:61616")); +broker.addConnector(connector); +broker.start(); +``` +In the same JVM clients can then use the [vm:// transport](vm-transport-reference) to connect to the embedded broker - whilst external clients can use the [tcp:// protocol](tcp-transport-reference) + +If you have more than one embedded broker, ensure that you give them a unique name and - e.g. +``` +BrokerService broker = new BrokerService(); +// configure the broker +broker.setBrokerName("fred"); +broker.addConnector("tcp://localhost:61616"); +broker.start(); +``` +Then if you want to connect to the broker named 'fred' from within the same JVM, you can by using the uri **vm://fred** + +It is possible to fully configure a broker through application code e.g. +``` +BrokerService broker = new BrokerService(); +broker.setBrokerName("fred"); +broker.setUseShutdownHook(false); +//Add plugin +broker.setPlugins(new BrokerPlugin[]{new JaasAuthenticationPlugin()}); +//Add a network connection +NetworkConnector connector = answer.addNetworkConnector("static://"+"tcp://somehost:61616"); +connector.setDuplex(true); +broker.addConnector("tcp://localhost:61616"); +broker.start(); +``` +Please note that you should add plugins before connectors or they will not be initialized + +For more details on the available properties you can specify, see the [BrokerService javadoc](http://activemq.apache.org/maven/5.11.0/apidocs/org/apache/activemq/broker/BrokerService.html) + +### Using the BrokerFactory + +There is a helper class called [BrokerFactory](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/broker/BrokerFactory.html) which can be used to create a broker via URI for configuration. +``` +BrokerService broker = BrokerFactory.createBroker(new URI(someURI)); +``` +The available values of the URI are: + +URI scheme|Example|Description +---|---|--- +xbean:|bean:activemq.xml|Searches the classpath (and file system) for an XML document with the given URI (activemq.xml in this case) which will then be used as the [Xml Configuration](xml-configuration) +broker:|broker:tcp://localhost:61616|Uses the [Broker Configuration URI](broker-configuration-uri) to confgure the broker + +### Using Spring + +There is a factory bean that can refer to an external ActiveMQ Classic XML configuration file +``` + + + + +``` +In this case the usual Spring `classpath:org/apache/activemq/xbean/activemq.xml` resource mechanism is being used so that the activemq.xml file would be found on the classpath by looking inside all the directories on the classpath then looking for `org/apache/activemq/xbean/activemq.xml`. You can of course change this to any value you like. e.g. use `classpath:activemq.xml` if you just want to drop it in a directory that is in the classpath; like `WEB-INF/classes` in a web application. + +If you wish you can use a URL instead using the **file:* or *http:** prefixes. For more details see how [Spring deals with resources](http://static.springframework.org/spring/docs/1.2.x/reference/beans.html#context-functionality-resources) + +### Using XBean + +If you are already using [XBean](http://geronimo.apache.org/xbean/) then you can just mix and match your Spring/XBean [XML configuration](https://github.com/apache/activemq/tree/main/activemq-core/src/test/resources/org/apache/activemq/xbean/activemq.xml) with ActiveMQ Classic's configuration. +``` + + + + + + + + + + + + + + + + +``` + +### Using Spring 2.0 + +If you are using Spring 2.0 and ActiveMQ Classic 4.1 or later (and xbean-spring 2.5 or later) you can embed the ActiveMQ Classic broker XML inside any regular Spring.xml file without requiring the above factory bean. e.g. here is an [example](http://svn.apache.org/repos/asf/incubator/activemq/trunk/activemq-core/src/test/resources/spring-embedded-xbean.xml) of a regular Spring XML file in Spring 2.0 which also configures a broker. +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 + + + + + + + + + + +``` + +### Using ActiveMQConnectionFactory + +An embedded broker can also be created using an ActiveMQConnectionFactory and using a vm connector as a uri. e.g. +``` +ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false"); +``` +Use the query parameters "broker." to configure the broker, where matches the bean properties on the BrokerService. + +The broker will be created upon creation of the first connection. + +You can turn off auto creation by setting the create property on the VM Transport to false: +``` +ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost?create=false"); +``` diff --git a/hugo/content/components/classic/documentation/how-do-i-enable-asynchronous-sending.md b/hugo/content/components/classic/documentation/how-do-i-enable-asynchronous-sending.md new file mode 100644 index 0000000000..801285125d --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-enable-asynchronous-sending.md @@ -0,0 +1,17 @@ +--- +title: How do I enable asynchronous sending +layout: classic-doc +--- + + + +The default setting for ActiveMQ Classic is that all persistent messages outside of a transaction are sent to a broker are synchronous. This means that the send method is blocked until the message is received by the broker, its then written to disk - then a response is returned to the client and the send() unblocks with success or throws a JMSException if the send could not complete (e.g. due to a security exception).  In the case of the persistent messages being sent in a transaction, only the commit is synchronous since if the commit succeeds, then it means that all of the sends and acknowledgements in the transaction succeeded. + +For performance reasons you may wish to stream messages to the broker as fast as possible even if you are using persistent messages. So you can enable **asynchronous sending** of persistent messages using one of the following options + +* set the useAsyncSend property on the ActiveMQConnectionFactory +* set the property using the URI when you connect to the broker + +``` +tcp://localhost:61616?jms.useAsyncSend=true +``` \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/how-do-i-enable-debug-logging.md b/hugo/content/components/classic/documentation/how-do-i-enable-debug-logging.md new file mode 100644 index 0000000000..86e3e5738a --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-enable-debug-logging.md @@ -0,0 +1,16 @@ +--- +title: How do I enable debug logging +layout: classic-doc +--- + + + +How do I enable debug logging? +------------------------------ + +For background see [How do I change the logging](how-do-i-change-the-logging). + +You can enable debug logging in ActiveMQ Classic by adding the following line to the `conf/log4j.properties` file +``` +log4j.logger.org.apache.activemq=DEBUG +``` diff --git a/hugo/content/components/classic/documentation/how-do-i-find-the-size-of-a-queue.md b/hugo/content/components/classic/documentation/how-do-i-find-the-size-of-a-queue.md new file mode 100644 index 0000000000..0be572dc88 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-find-the-size-of-a-queue.md @@ -0,0 +1,25 @@ +--- +title: How do I find the Size of a Queue +layout: classic-doc +--- + + + +How do I check on the size of the queue? I know it's not JMS standard, but most JMS implementations have a way to do this. + +You can view the queue depth using the MBeans in ActiveMQ Classic 5.x. Use any JMX management console to see the statistics. See [How can I monitor ActiveMQ Classic](how-can-i-monitor-activemq-classic). + +You can also browse the contents of a queue using the JMS [QueueBrowser](http://java.sun.com/j2ee/1.4/docs/api/javax/jms/QueueBrowser.html). + +Or you can access statistics [programmatically](how-can-i-see-what-destinations-are-used) + +Through the MBeans, you can monitor individual destinations including message statistics related to the destination. For example, you'll see the following attributes on a destination (Queue or Topic): + +* Enqueue Count - the total number of messages sent to the queue since the last restart +* Dequeue Count - the total number of messages removed from the queue (ack'd by consumer) since last restart +* Inflight Count - the number of messages sent to a consumer session and have not received an ack +* Dispatch Count - the total number of messages sent to consumer sessions (Dequeue + Inflight) +* Expired Count - the number of messages that were not delivered because they were expired + +The "size of a queue" is also explicitly called out in an attribute "QueueSize." QueueSize is the total number of messages in the queue/store that have not been ack'd by a consumer. This can become confusing at times when compared to the Enqueue Count because the Enqueue Count is a count over a period of time (since the last broker restart) while the Queue Size is not dependent on a period of time but instead on the actual number of messages in the store. + diff --git a/hugo/content/components/classic/documentation/how-do-i-get-started-with-jms.md b/hugo/content/components/classic/documentation/how-do-i-get-started-with-jms.md new file mode 100644 index 0000000000..c2a4d3f311 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-get-started-with-jms.md @@ -0,0 +1,14 @@ +--- +title: How do I get started with JMS +layout: classic-doc +--- + + + +How do I get started with JMS +----------------------------- + +Your best way to get started understanding the JMS API is [Sun's JMS tutorial](http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JMS.html#wp84181). + +Alternatively you could stick to writing business level POJOs and hide the middleware via [Apache Camel](http://activemq.apache.org/camel/) which hides the JMS API from you letting you focus on your business logic via the [Bean Integration](http://activemq.apache.org/camel/bean-integration.html) + diff --git a/hugo/content/components/classic/documentation/how-do-i-make-messages-durable.md b/hugo/content/components/classic/documentation/how-do-i-make-messages-durable.md new file mode 100644 index 0000000000..8497700d5a --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-make-messages-durable.md @@ -0,0 +1,14 @@ +--- +title: How do I make messages durable +layout: classic-doc +--- + + + +Durability of messages is defined by the [MessagerProducer](http://java.sun.com/j2ee/1.4/docs/api/javax/jms/MessageProducer.html). You can explicitly configure the durability via the [setDeliveryMode() method](http://java.sun.com/j2ee/1.4/docs/api/javax/jms/MessageProducer.html#setDeliveryMode(int)). e.g. +``` +MessageProducer producer = ...; +producer.setDeliveryMode(DeliveryMode.PERSISTENT); +``` +Note that the default is for durable messages to be used if you don't specify a delivery mode. + diff --git a/hugo/content/components/classic/documentation/how-do-i-preserve-order-of-messages.md b/hugo/content/components/classic/documentation/how-do-i-preserve-order-of-messages.md new file mode 100644 index 0000000000..89149e5e88 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-preserve-order-of-messages.md @@ -0,0 +1,14 @@ +--- +title: How do I preserve order of messages +layout: classic-doc +--- + + + +ActiveMQ Classic will preserve the order of messages sent by a single producer to all consumers on a topic. If there is a single consumer on a queue then the order of messages sent by a single producer will be preserved as well. + +If you have multiple consumers on a single queue the consumers will compete for messages and ActiveMQ Classic will load balance across them, so order will be lost. For background on the issue and how it can be solved see + +* [Exclusive Consumer](exclusive-consumer) which allows only a single consumer to consume from the queue at once to preseve order +* [Message Groups](message-groups) which splits the messages on a queue into parallel virtual exclusive queues to ensure that messages to a single message group (defined by the JMSXGroupID header) will have their order preserved but that different groups will be load balanced to different consumers. + diff --git a/hugo/content/components/classic/documentation/how-do-i-purge-a-queue.md b/hugo/content/components/classic/documentation/how-do-i-purge-a-queue.md new file mode 100644 index 0000000000..99541d8303 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-purge-a-queue.md @@ -0,0 +1,26 @@ +--- +title: How do I purge a queue +layout: classic-doc +--- + + + +A frequent requirement is to purge a queue (i.e. delete all the messages on it). + +### Solution + +You can use the [Web Console](web-console) to view queues, add/remove queues, purge queues or delete/forward individual messages. + +Another option is to use [JMX](jmx) to browse the queues and call the **purge()** method on the [QueueViewMBean](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/broker/jmx/QueueViewMBean.html). + +You could also delete the queue via removeQueue(String) or removeTopic(String) methods on the [BrokerViewMBean](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/broker/jmx/BrokerViewMBean.html) + +You can also do it [programmatically](how-can-i-see-what-destinations-are-used) + +### Also See + +* [Web Console](web-console) +* [JMX](jmx) +* [How do I find the Size of a Queue](how-do-i-find-the-size-of-a-queue) +* [How can I see what destinations are used](how-can-i-see-what-destinations-are-used) + diff --git a/hugo/content/components/classic/documentation/how-do-i-restart-embedded-broker.md b/hugo/content/components/classic/documentation/how-do-i-restart-embedded-broker.md new file mode 100644 index 0000000000..8b3996ec79 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-restart-embedded-broker.md @@ -0,0 +1,37 @@ +--- +title: How do I restart embedded broker +layout: classic-doc +--- + + + +Pure restart of the embedded broker is not advisable, since it's state could be corrupted. Therefore, you're advised to instantiate the broker again before restarting it. +``` +BrokerService service = BrokerFactory.createBroker("xbean:activemq.xml"); +service.start(); +service.waitUntilStarted(); + +service.stop(); +service.waitUntilStopped(); + +service = BrokerFactory.createBroker("xbean:activemq.xml"); +service.start(); +``` +In 5.3 however, we allowed the force start of the broker that has been stopped for use cases that need this functionality. You can do it by using +``` +BrokerService.start(boolean force); +``` +method. + +The following example demonstrates it. +``` +BrokerService service = BrokerFactory.createBroker("xbean:activemq.xml"); +service.start(); +service.waitUntilStarted(); + +service.stop(); +service.waitUntilStopped(); + +service.start(true); +``` +However, it's better (more reliable) to instantiate the broker again if it is possible. \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/how-do-i-restrict-connections-from-creating-new-queues-or-topics.md b/hugo/content/components/classic/documentation/how-do-i-restrict-connections-from-creating-new-queues-or-topics.md new file mode 100644 index 0000000000..c106b9b8bf --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-restrict-connections-from-creating-new-queues-or-topics.md @@ -0,0 +1,14 @@ +--- +title: How do I restrict connections from creating new queues or topics +layout: classic-doc +--- + + + +How do I restrict connections from creating new queues or topics? +----------------------------------------------------------------- + +As is described in [How do I create new destinations](how-do-i-create-new-destinations) there is no need to create all the destinations up front, you can let the broker create them on the fly. + +However if you don't want this behaviour, or wish to restrict this behaviour to certain topic or queue [Wildcards](wildcards) (areas of the queue or topic name space) then you can use the [Security](security) plugins to disallow the **admin** role on whatever areas of the queue and topic namespace you wish + diff --git a/hugo/content/components/classic/documentation/how-do-i-run-a-broker.md b/hugo/content/components/classic/documentation/how-do-i-run-a-broker.md new file mode 100644 index 0000000000..b6b1b806ef --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-run-a-broker.md @@ -0,0 +1,11 @@ +--- +title: How do I run a broker +layout: classic-doc +--- + + + +### For ActiveMQ Classic 3.x/4.x + +Please see the [running a broker page](run-broker) + diff --git a/hugo/content/components/classic/documentation/how-do-i-run-activemq-classic-under-the-kaffe-jvm.md b/hugo/content/components/classic/documentation/how-do-i-run-activemq-classic-under-the-kaffe-jvm.md new file mode 100644 index 0000000000..5fff04c531 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-run-activemq-classic-under-the-kaffe-jvm.md @@ -0,0 +1,42 @@ +--- +title: How do I run ActiveMQ Classic under the Kaffe JVM +layout: classic-doc +--- + + + +ActiveMQ Classic will run under Kaffe with a few adjustments to the default configuration. + +We have found the Kaffe does not properly implement: + +* File based NIO +* Multicast Sockets +* JMX connector JNDI handling + +Therefore, the default ActiveMQ Classic configuration must be adjusted to disable the Journal (uses NIO), disable Multicast discovery, and JMX. + +The Kaffe and OS Version that was tested against was: + +> kaffe version info: Engine: Interpreter Version: 1.1.7 Java Version: 1.4 +> OS & version: Linux dev-10 2.6.13-15.8-smp #1 SMP Tue Feb 7 11:07:24 UTC + +The following is the activemq.xml that was used: +``` + + + + + + + + + + + + + + + + + +``` \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/how-do-i-send-messages-to-different-destinations-from-a-single-messageproducer.md b/hugo/content/components/classic/documentation/how-do-i-send-messages-to-different-destinations-from-a-single-messageproducer.md new file mode 100644 index 0000000000..a745400af5 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-send-messages-to-different-destinations-from-a-single-messageproducer.md @@ -0,0 +1,18 @@ +--- +title: How do I send messages to different Destinations from a single MessageProducer +layout: classic-doc +--- + + + +How do I send messages to different Destinations from a single MessageProducer? +------------------------------------------------------------------------------- + +Create the MessageProducer using a null destination; then specify the destination each time you send... +``` +MessageProducer producer = session.createProducer(null); +... +producer.send(someDestination, message); +... +producer.send(anotherDestination, message); +``` \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/how-do-i-set-the-message-expiration.md b/hugo/content/components/classic/documentation/how-do-i-set-the-message-expiration.md new file mode 100644 index 0000000000..d685aa3773 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-set-the-message-expiration.md @@ -0,0 +1,12 @@ +--- +title: How do I set the message expiration +layout: classic-doc +--- + + + +JMSExpiration on a message is set by the MessageProducer in JMS - either via + +* [producer.setTimeToLive()](http://java.sun.com/j2ee/1.4/docs/api/javax/jms/MessageProducer.html#setTimeToLive(long)) +* [producer.send(Destination, Message, int, int, long)](http://java.sun.com/j2ee/1.4/docs/api/javax/jms/MessageProducer.html#send(javax.jms.Destination,%20javax.jms.Message,%20int,%20int,%20long)) + diff --git a/hugo/content/components/classic/documentation/how-do-i-turn-off-creating-an-embedded-activemq-classic-broker-when-using-the-vm-transport.md b/hugo/content/components/classic/documentation/how-do-i-turn-off-creating-an-embedded-activemq-classic-broker-when-using-the-vm-transport.md new file mode 100644 index 0000000000..2314b3a70a --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-turn-off-creating-an-embedded-activemq-classic-broker-when-using-the-vm-transport.md @@ -0,0 +1,11 @@ +--- +title: How do I turn off creating an embedded ActiveMQ Classic broker when using the VM transport +layout: classic-doc +--- + + + +You can turn off auto creation by setting the create property on the VM Transport to false: +``` +ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost?create=false"); +``` \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/how-do-i-unack-the-message-with-stomp.md b/hugo/content/components/classic/documentation/how-do-i-unack-the-message-with-stomp.md new file mode 100644 index 0000000000..b1839d68ef --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-unack-the-message-with-stomp.md @@ -0,0 +1,58 @@ +--- +title: How do I unack the message with Stomp +layout: classic-doc +--- + + + +There is no explicit "unack" command in Stomp. Once the client receives the message it cannot be marked as "unconsumed" and sent to another subscriber (or redelivered to the same subscriber again). It's up to your application (or Stomp client) to handle failed processing of received messages and implement "message redelivery". + +Stomp transactions are often mistakenly considered to be a solution for this use case. But that's not the case, since transactions are only related to sending messages and acknowledgments. If you start a transaction, send a message ack in a transaction and finally abort it, the message will not be redelivered again. It just means that broker will not send any more messages to the client if the prefetch limit is reached. + +Take a look at the following example: +``` +StompConnection connection = new StompConnection(); +connection.open("localhost", 61613); + +connection.connect("system", "manager"); + +connection.send("/queue/test", "message 1"); +connection.send("/queue/test", "message 2"); +connection.send("/queue/test", "message 3"); + +HashMap headers = new HashMap(); +headers.put("activemq.prefetchSize", "1"); +connection.subscribe("/queue/test", "client", headers); + +connection.begin("tx1"); +StompFrame frame = connection.receive(); +System.out.println(frame.getBody()); +connection.ack(frame, "tx1"); +connection.abort("tx1"); + +connection.begin("tx2"); +connection.ack(frame, "tx2"); //sending the ack again +frame = connection.receive(); +System.out.println(frame.getBody()); +connection.ack(frame, "tx2"); +connection.commit("tx2"); + +connection.begin("tx3"); +frame = connection.receive(); +System.out.println(frame.getBody()); +connection.ack(frame, "tx3"); +connection.commit("tx3"); +``` +This simple application will print +``` +message 1 +message 2 +message 3 +``` +Since the transaction `tx1` has been aborted, we needed to acknowledge that message again in `tx2` in order to be able to receive the next message (since the prefetch size used is 1). + +Also take a look at these pages for more info: + +* [http://activemq.apache.org/stomp/stomp10/additional.html#transaction_handling](http://activemq.apache.org/stomp/stomp10/additional.html#transaction_handling) +* [what-is-the-prefetch-limit-for](what-is-the-prefetch-limit-for) + diff --git a/hugo/content/components/classic/documentation/how-do-i-use-activemq-classic-using-in-jvm-messaging.md b/hugo/content/components/classic/documentation/how-do-i-use-activemq-classic-using-in-jvm-messaging.md new file mode 100644 index 0000000000..94932e9613 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-use-activemq-classic-using-in-jvm-messaging.md @@ -0,0 +1,19 @@ +--- +title: How do I use ActiveMQ Classic using in JVM messaging +layout: classic-doc +--- + + + +### For ActiveMQ Classic 3.x/4.x + +To use pure in-memory messaging you just need to set the broker URL to be +``` +vm://localhost +``` +Actually you can use any text after _vm://_ so that you can segment multiple logical JMS brokers within the same JVM and classloader, using the name to distinguish between them. + +There is an example of how to do this along with a description of the available protocols in the [Protocols overview](uri-protocols). + +Also see: [how to optimise the VM transport](how-should-i-use-the-vm-transport) + diff --git a/hugo/content/components/classic/documentation/how-do-i-use-durable-subscribers-in-a-network-of-brokers.md b/hugo/content/components/classic/documentation/how-do-i-use-durable-subscribers-in-a-network-of-brokers.md new file mode 100644 index 0000000000..4ac4e45890 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-use-durable-subscribers-in-a-network-of-brokers.md @@ -0,0 +1,27 @@ +--- +title: How do I use durable subscribers in a network of brokers +layout: classic-doc +--- + + + +Durable subscribers behave a little differently across a cluster of ActiveMQ Classic brokers. The two main issues surround messages getting stuck on other brokers in the network after a durable subscriber has disconnected and reconnected to a different broker in the network without fully unsubscribing. The reasons for disconnecting/reconnecting can be voluntary (where the subscriber is using the failover transport), or involuntary (one of the brokers in the cluster fails). + +For example, if you have two brokers A and B networked together in both directions to form a cluster, and a durable subscriber connects to broker B, a producer P on broker A will have its messages properly forwarded to broker B and the durable subscriber. However, if the subscriber disconnects and reconnects to broker A, any messages sent by P while the subscriber was away will be stuck on B until the subscriber reconnects to B. + +The solution is to use [Virtual Destinations](virtual-destinations) + +Virtual topics use queues under the covers and this allows ActiveMQ Classic to treat each subscriber as a plain old Queue subscriber. This allows ActiveMQ Classic to replay messages that have been orphaned on another broker in the cluster using this configuration as explained in the [Networks of Brokers](networks-of-brokers) documentation: +``` + + + + + + + + + +``` +Also, take a look at [this unit test to see the full configuration and usage](http://svn.apache.org/viewvc/activemq/trunk/activemq-unit-tests/src/test/java/org/apache/activemq/usecases/VirtualTopicNetworkClusterReactivationTest.java?view=markup) + diff --git a/hugo/content/components/classic/documentation/how-do-i-use-ivy-with-activemq-classic.md b/hugo/content/components/classic/documentation/how-do-i-use-ivy-with-activemq-classic.md new file mode 100644 index 0000000000..e1782f5308 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-use-ivy-with-activemq-classic.md @@ -0,0 +1,39 @@ +--- +title: How do I use Ivy with ActiveMQ Classic +layout: classic-doc +--- + + +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` diff --git a/hugo/content/components/classic/documentation/how-do-i-use-jms-efficiently.md b/hugo/content/components/classic/documentation/how-do-i-use-jms-efficiently.md new file mode 100644 index 0000000000..76100806ca --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-use-jms-efficiently.md @@ -0,0 +1,44 @@ +--- +title: How do I use JMS efficiently +layout: classic-doc +--- + + + +How do I use JMS efficiently? +----------------------------- + +JMS is designed for high performance. In particular its design is such that you are meant to create a number of objects up front on the startup of your application and then resuse them throughout your application. e.g. its a good idea to create upfront and then reuse the following + +* Connection +* Session +* MessageProducer +* MessageConsumer + +The reason is that each create & destroy of the above objects typically requires an individual request & response with the JMS broker to ensure it worked. e.g. creating a connection, session, producer, then sending a message, then closing everything down again - could result in 7 request-responses with the server! + +Note a little trick - you can reuse the same MessageProducer for sending messages to different destinations; just create it with a null destination and specify it on the send method. + +MessageProducer instances that are created with a null destination are anonymous producers and as such the broker cannot fire an advisory for producer when these are created. This means that when the pooled MessageProducer is in use no advisories for producers will ever be sent. + +### Using Pooling with JMS + +To use JMS efficiently we recommend you use [Camel](http://activemq.apache.org/camel/) to hide the JMS API and [bind the messaging to your beans](http://activemq.apache.org/camel/bean-integration.html). + +Alternatively try using Spring's [MessageListenerContainer](http://static.springsource.org/spring/docs/2.5.x/reference/FAQ/jms.md#Community/FAQ/jms.mdp) for consuming messages and [JmsTemplate](http://static.springsource.org/spring/docs/2.5.x/reference/FAQ/jms.md#jms-jmstemplate) for sending - but be [aware of the gotchas](http://activemq.apache.orgConnectivity/Containers/Spring SupportConnectivity/Containers/Spring Support/Connectivity/Containers/Spring Support/jmstemplate-gotchas) + +### Other performance tips + +Also see + +* [Should I use transactions](should-i-use-transactions) +* [Should I use XA](should-i-use-xa) + +### Java Connector Architecture + +[Java Connector Architecture](http://java.sun.com/j2ee/connector/) supports the pooling of JMS connections, sessions and MessageListeners, parallel message processing, thread pooling and transaction & exception handling, through the use of a JCA [Resource Adapter](resource-adapter). + +All of these benefits are also available through Spring's MessageListenerContiner **except** for the XA transactions. If you need XA support then you must use JCA + +Typically JCA is used in a J2EE container via MDBs; though there is a POJO Spring based [JCA Container](jca-container) you can use, which is simple and lightweight and easy to embed inside Tomcat or any J2SE application. + diff --git a/hugo/content/components/classic/documentation/how-do-i-use-log4j-jms-appender-with-activemq-classic.md b/hugo/content/components/classic/documentation/how-do-i-use-log4j-jms-appender-with-activemq-classic.md new file mode 100644 index 0000000000..16f934b2e6 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-use-log4j-jms-appender-with-activemq-classic.md @@ -0,0 +1,81 @@ +--- +title: How do I use log4j JMS appender with ActiveMQ Classic +layout: classic-doc +--- + + + +[Log4j JMS appender](http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/net/JMSAppender.html) can be used to send your log messages to JMS broker. To use ActiveMQ Classic as a destination of your messages, you need to configure JMS appender properly. The code sample below shows example configuration: +``` +log4j.rootLogger=INFO, stdout, jms + +## Be sure that ActiveMQ Classic messages are not logged to 'jms' appender +log4j.logger.org.apache.activemq=INFO, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %-5p %c - %m%n + +## Configure 'jms' appender. You'll also need jndi.properties file in order to make it work +log4j.appender.jms=org.apache.log4j.net.JMSAppender +log4j.appender.jms.InitialContextFactoryName=org.apache.activemq.jndi.ActiveMQInitialContextFactory +log4j.appender.jms.ProviderURL=tcp://localhost:61616 +log4j.appender.jms.TopicBindingName=logTopic +log4j.appender.jms.TopicConnectionFactoryBindingName=ConnectionFactory +``` +The important thing is not to send ActiveMQ Classic logs to JMS appender, as it can cause errors since the broker will want to log before the connection is established. You will also need a JNDI configuration, so that appender can find appropriate topic to send log messages to. The example `jndi.properties` file can look like this: +``` +topic.logTopic=logTopic +``` +Finally, you can subscribe to the topic and listen for log messages: +``` +public class Log4jJMSAppenderExample implements MessageListener { + + public Log4jJMSAppenderExample() throws Exception { + // create a logTopic topic consumer + ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); + Connection conn = factory.createConnection(); + Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + conn.start(); + MessageConsumer consumer = sess.createConsumer(sess.createTopic("logTopic")); + consumer.setMessageListener(this); + // log a message + Logger log = Logger.getLogger(Log4jJMSAppenderExample.class); + log.info("Test log"); + // clean up + Thread.sleep(1000); + consumer.close(); + sess.close(); + conn.close(); + System.exit(1); + } + + public static void main(String[] args) throws Exception { + new Log4jJMSAppenderExample(); + } + + public void onMessage(Message message) { + try { + // receive log event in your consumer + LoggingEvent event = (LoggingEvent)((ActiveMQObjectMessage)message).getObject(); + System.out.println("Received log [" + event.getLevel() + "]: "+ event.getMessage()); + } catch (Exception e) { + e.printStackTrace(); + } + } +} +``` +Note that appender send logging event wrapped in an object message, so you can extract information such as logger name, level and of course the message. + +Starting with ActiveMQ Classic 5.3, this example is included in the standard distribution. You can run it by executing +``` +ant log4j-jms +``` +inside `example/` folder. You can expect the following output as a result: +``` +log4j-jms: + [echo] Running a Log4j JMS Appender example + [java] 2009-08-11 13:58:46,767 INFO Log4jJMSAppenderExample - Test log + [java] Received log [INFO]: Test log + [java] Java Result: 1 +``` diff --git a/hugo/content/components/classic/documentation/how-do-i-use-ssl.md b/hugo/content/components/classic/documentation/how-do-i-use-ssl.md new file mode 100644 index 0000000000..41481fa92c --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-i-use-ssl.md @@ -0,0 +1,121 @@ +--- +title: How do I use SSL +layout: classic-doc +--- + + +### Setting up the Key and Trust Stores + +Also see [Tomcat's SSL instructions](http://jakarta.apache.org/tomcat/tomcat-5.5-doc/ssl-howto.html) for more info. The following was provided by Colin Kilburn. Thanks Colin! + +> ActiveMQ Classic uses dummy credentials by default +> +> ActiveMQ Classic includes key and trust stores that reference a dummy self signed cert. When you create a broker certificate and stores for your installation, either overwrite the values in the conf directory or delete the existing dummy key and trust stores so they cannot interfere) + +1. Using keytool, create a certificate for the broker: + ``` + keytool -genkey -alias broker -keyalg RSA -keystore broker.ks + ``` +2. Export the broker's certificate so it can be shared with clients: + ``` + keytool -export -alias broker -keystore broker.ks -file broker_cert + ``` +3. Create a certificate/keystore for the client: + ``` + keytool -genkey -alias client -keyalg RSA -keystore client.ks + ``` +4. Create a truststore for the client, and import the broker's + certificate. This establishes that the client "trusts" the broker: + ``` + keytool -import -alias broker -keystore client.ts -file broker_cert + ``` + +### Starting the Broker + +#### Using the javax.net.ssl.* System Properties + +Before starting the broker's VM set the ACTIVEMQ_SSL_OPTS environment variable so that it knows to use the broker keystore. (note that in previous versions of ActiveMQ Classic this property was called SSL_OPTS in some scripts. As of v5.12.0 all scripts use ACTIVEMQ_SSL_OPTS) + +``` +export ACTIVEMQ_SSL_OPTS = -Djavax.net.ssl.keyStore=/path/to/broker.ks -Djavax.net.ssl.keyStorePassword=password +``` + +#### Using Spring to configure SSL for a Broker instance + +Sometimes the use of javax.net.ssl.* system properties is not appropriate as they effect all SSL users in a JVM. ActiveMQ Classic 5.2.x adds an element to the that allows a broker specific set of SSL properties to be configured. + +The SslContext [test case](https://github.com/apache/activemq/tree/main/activemq-unit-tests/src/test/java/org/apache/activemq/transport/tcp/SslContextBrokerServiceTest.java) validates starting an SSL transport listener using the configuration specified in the broker Xbean. The SslContext element is added to the broker as follows: + +The SslContext is used to configure the [SslTransportFactory](https://github.com/apache/activemq/tree/main/activemq-client/src/main/java/org/apache/activemq/transport/tcp/SslTransportFactory.java) for that broker. Full details of the configuration options available can be seen in the [schema definition](http://activemq.apache.org/schema/core/activemq-core-5.2-SNAPSHOT.xsd) or in the accessors of [org.apache.activemq.spring.SpringSslContext](https://github.com/apache/activemq/tree/main/activemq-spring/src/main/java/org/apache/activemq/spring/SpringSslContext.java) + +### Starting the Client + +When starting the client's VM, specify the following system properties: +``` +javax.net.ssl.keyStore=/path/to/client.ks +javax.net.ssl.keyStorePassword=password +javax.net.ssl.trustStore=/path/to/client.ts +``` + +In Linux, do not use absolute path to keystore. By default, keytool uses `~/.keystore`, but in some setups passing `-Djavax.net.ssl.keyStore=/home/account/.keystore` to Java VM does not work. This is not specific to ActiveMQ Classic but good to keep in mind anyway. + +### Client certificates + +If you want to verify client certificates, you need to take a few extra +steps: + +1. Export the client's certificate so it can be shared with broker: + ``` + keytool -export -alias client -keystore client.ks -file client_cert + ``` +2. Create a truststore for the broker, and import the client's certificate. This establishes that the broker "trusts" the client: + ``` + keytool -import -alias client -keystore broker.ts -file client_cert + ``` +3. Add + ``` + -Djavax.net.ssl.trustStore=/path/to/broker.ts + ``` + to `ACTIVEMQ_SSL_OPTS` + +4. Instruct ActiveMQ Classic to require client authentication by setting the following in activemq.xml: + +### Certificate revocation + +Starting with version **5.12**, you can define certificate revocation list (CRL) path on ssl context, so that invalid certificates can revoked + +``` + + + +``` + +This list is static and loaded on broker startup. + +Starting with version **5.14.0**, you can also enable more advanced Online Certificate Status Protocol (OCSP) protocol. For that you need to configure a location for the `java.security` configuration extension by setting appropriate system properties (in `${ACTIVEMQ_HOME}/bin/env`) like + +``` +ACTIVEMQ_SSL_OPTS="-Djava.security.properties=$ACTIVEMQ_CONF/java.security" +``` + +Then you need to configure OCSP responder properties in `java.security` file like +``` +ocsp.enable=true ocsp.responderURL= +``` + +A demo of the broker configuration working with OCSP responder can be found at + +### Working Around Java 7 SSL Bugs + +As noted by issue AMQ-5970, it seems some versions of Java 7 have problems with SSL sessions that need to use the Diffie-Hellman cypher suite. If you run into this issue, just copy the Bouncy Castle bcprov-jdk15on-148.jar to ActiveMQ Classic's lib directory and restart your broker. + +### Useful links + +These links might also help + +- [Sun's JSSE guide](http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html#CreateKeystore) +- [Thawte SSL Troubleshooting Tips](https://search.thawte.com/support/ssl-digital-certificates/index?page=content&id=SO10061) diff --git a/hugo/content/components/classic/documentation/how-do-message-groups-compare-to-selectors.md b/hugo/content/components/classic/documentation/how-do-message-groups-compare-to-selectors.md new file mode 100644 index 0000000000..b2f2f1613c --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-message-groups-compare-to-selectors.md @@ -0,0 +1,23 @@ +--- +title: How do Message Groups compare to Selectors +layout: classic-doc +--- + + + +Selectors are just filters. Message Groups are a way of grouping messages together to the same consumer to partition your application or insure ordering is maintained. + +Now you could implement message groups by hand, by having each consumer use its own selector for a specific header. e.g. if you had consumers A, B, C; you could use the values "A", "B", "C" as values of the JMSXGroupID header (or any other header name you like). + +Then if consumer A used `JMXGroupID = 'A'` as a selector it would be the only consumer getting the A messages; ditto for B and C. + +So that kinda simulates message groups a little. The downside is + +* you have to know the set of consumers that are running to know what values of A, B or C you can put on the header. So if you start up a new consumer D, you have to change the producer to now be aware of D. Wtih message groups you can use any string whatsoever - typically the string will come from your business such as a product code, a customer ID, a stock ticker name or something (or some combination of data such as IBM and NASDAQ and Tuesday). + +* if for whatever reason consumer B stops running, noone consumes any messages for B - you have to know to restart B manually. With message groups things auto-partition and load balance for you with immediate failover. + +* there's nothing to stop you accidentally creating 2 threads with the same selector - or 2 processes on the network starting up with the same selector and accidentally consuming from the same group of messages which completely breaks ordering; with message groups you don't have to worry about this - since it guarrentees that only 1 thread in your entire system will process messages from one group at once in order - irrespective how many consumers you start. + +So in general; you can manually partition yourself using selectors. Message Groups however are a self-partitioning and auto-failvoer mechanism which also guarrentees that a single thread will process a specific message group at once, in order. + diff --git a/hugo/content/components/classic/documentation/how-do-multiple-transports-work.md b/hugo/content/components/classic/documentation/how-do-multiple-transports-work.md new file mode 100644 index 0000000000..b3d82bacf5 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-multiple-transports-work.md @@ -0,0 +1,13 @@ +--- +title: How do multiple transports work +layout: classic-doc +--- + + + +### For ActiveMQ Classic 3.x/4.x + +The transport a client uses to connect to the broker is just the transport your client uses. So messages the broker sends to your client will be sent over that transport. However the broker can support many transports. + +So client A could connect over HTTP and client B could connect over tcp. Messages client A sends via HTTP will be delivered to B using B's transport, tcp. + diff --git a/hugo/content/components/classic/documentation/how-do-transactions-work.md b/hugo/content/components/classic/documentation/how-do-transactions-work.md new file mode 100644 index 0000000000..6870c4cef2 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-do-transactions-work.md @@ -0,0 +1,18 @@ +--- +title: How Do Transactions Work +layout: classic-doc +--- + + + +There are two levels of transaction support in ActiveMQ Classic: + +* JMS Transactions - the `commit()`/`rollback()` methods on a Session (which is like doing `commit()`/`rollback()` on a JDBC connection) +* XA Transactions - where the [XASession](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/ActiveMQXASession.html) acts as an [XAResource](http://java.sun.com/j2ee/1.4/docs/api/javax/transaction/xa/XAReDevelopers/source) by communicating with the Message Broker, rather like a JDBC Connection takes place in an XA transaction by communicating with the database. + +They are both implemented in a similar manner. When operations are carried out on a transacted (or XA transacted) session, a transaction command is sent to the broker, with a unique transaction ID which is then followed by all the usual commands (send message, acknowledge message etc). When a `commit()` or `rollback()` is called on the Session, this command is sent to the broker for it to commit or rollback the transaction. + +Now the operations carried out on a transacted session inside a transaction, like a send message or acknowledge message, do not really perform a real send or acknowledge until the commit occurs. So the Broker explicitly handles these cases separately - essentially buffering up the commands until the commit occurs when the messages are really sent or acknowledged. + +ActiveMQ Classic uses [TransactionStore](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/store/TransactionStore.html) (implemented by all persistence adapters) to handle transactions. `TransactionStore` will cache all messages and ACKs until commit or rollback occurs. Besides storing messages, the broker will withhold dispatching any of the messages until the session commit. If you wanna see the code, take a look at [MemoryTransactionStore](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/store/memory/MemoryTransactionStore.html) which proxies transactions for Memory and JDBC persistence adapters.  The only real difference with XA transactions is that at the PREPARE stage we MUST write every command we have received (the send message or acknowledge message commands) to a persistent store so that we can recover properly. + diff --git a/hugo/content/components/classic/documentation/how-does-a-queue-compare-to-a-topic.md b/hugo/content/components/classic/documentation/how-does-a-queue-compare-to-a-topic.md new file mode 100644 index 0000000000..d7d03719be --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-a-queue-compare-to-a-topic.md @@ -0,0 +1,17 @@ +--- +title: How does a Queue compare to a Topic +layout: classic-doc +--- + + + +### Topics + +In JMS a Topic implements _publish and subscribe_ semantics. When you publish a message it goes to all the subscribers who are interested - so zero to many subscribers will receive a copy of the message. Only subscribers who had an active subscription at the time the broker receives the message will get a copy of the message. + +### Queues + +A JMS Queue implements _load balancer_ semantics. A single message will be received by exactly one consumer. If there are no consumers available at the time the message is sent it will be kept until a consumer is available that can process the message. If a consumer receives a message and does not acknowledge it before closing then the message will be redelivered to another consumer. A queue can have many consumers with messages _load balanced_ across the available consumers. + +So Queues implement a reliable load balancer in JMS. + diff --git a/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-amqp.md b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-amqp.md new file mode 100644 index 0000000000..7859bc5e13 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-amqp.md @@ -0,0 +1,19 @@ +--- +title: How does ActiveMQ Classic compare to AMQP +layout: classic-doc +--- + + + +[AMQP](amqp) stands for the _Advanced Message Queue Protocol_ and is a specification for how messaging clients and brokers can interoperate. AMQP is a specification of a wire-level protocol for client to message broker communication. It is not a messaging system like ActiveMQ Classic, but just a messaging protocol. + +ActiveMQ Classic now implements AMQP 1.0! + +ActiveMQ Classic also supports other open wire protocols: + +* [OpenWire](openwire), a fast binary format +* [Stomp](stomp), a simple and easily implemented text based-protocol +* [MQTT](mqtt), a compact binary format for limited devices on an unreliable network + +Through these protocols, ActiveMQ Classic can support clients in C, C++, C#, Ruby, Python, Perl, PHP, Pike etc. AMQP is most similar to OpenWire, because both OpenWire and AMQP are designed for high performance messaging, through a binary (rather than text-based) format. As a text-based format, STOMP is much easier to implement, but gives somewhat slower performance. + diff --git a/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-fuse-message-broker.md b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-fuse-message-broker.md new file mode 100644 index 0000000000..7e21ebb4e9 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-fuse-message-broker.md @@ -0,0 +1,9 @@ +--- +title: How does ActiveMQ Classic compare to Fuse Message Broker +layout: classic-doc +--- + + + +[Fuse Message Broker](http://fusesource.com/products/enterprise-activemq/) is a certified distribution of Apache ActiveMQ Classic provided by FuseSource. [FuseSource](http://fusesource.com) does all of its development and bug fixes as part of the Apache ActiveMQ Classic community, so there are no functional differences between the two. FuseSource may do more frequent releases than Apache, so it is possible to get bug fixes from a Fuse Message Broker release sooner than from an official Apache ActiveMQ Classic release. + diff --git a/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-jbossmq.md b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-jbossmq.md new file mode 100644 index 0000000000..12e7cfa6f4 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-jbossmq.md @@ -0,0 +1,32 @@ +--- +title: How does ActiveMQ Classic compare to JBossMQ +layout: classic-doc +--- + + + +There are some similarities between the two; they both support JMS 1.1 and run inside [JBoss 4.x](jboss-integration). + +However ActiveMQ Classic does offer some specific differences and advantages (at least from our perspective) + +* ActiveMQ Classic works great in any JVM not just inside the JBoss application server +* ActiveMQ Classic comes complete with a large number of [Cross Language Clients](cross-language-clients) +* ActiveMQ Classic supports many different [Protocols](protocols) such as [Ajax](ajax), [REST](rest), [Stomp](stomp), [OpenWire](openwire), [XMPP](xmpp.md) +* ActiveMQ Classic supports a large number of advanced features like [Message Groups](message-groups), [Exclusive Consumer](exclusive-consumer), [Composite Destinations](composite-destinations), [Advisory Message](advisory-message) support +* ActiveMQ Classic supports reliable connections with [configurable](configuring-transports) automatic reconnection +* ActiveMQ Classic has great [Spring Support](spring-Community/support) +* ActiveMQ Classic supports distributed destinations across networks +* ActiveMQ Classic is very fast; often 10x faster than JBossMQ. + +Performance guides +------------------ + +If you're not convinced by performance reports then please do try running performance tests yourself. You might wanna check out our overview of [Performance](performance) or try using out the [ActiveMQ Classic Performance Module Users Manual](activemq-classic-performance-module-users-manual) + +[Commercial providers](support#commercial-support) may also be able to help diagnose performance issues, suggest changes, etc... + +More on JBoss Integration +------------------------- + +[Integrating Apache ActiveMQ Classic with JBoss](integrating-apache-activemq-classic-with-jboss) + diff --git a/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-mantaray.md b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-mantaray.md new file mode 100644 index 0000000000..3df81069f3 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-mantaray.md @@ -0,0 +1,15 @@ +--- +title: How does ActiveMQ Classic compare to Mantaray +layout: classic-doc +--- + + + +We are obviously biased, and will tell you "just use ActiveMQ Classic!" ![(smile)](https://cwiki.apache.org/confluence/s/en_GB/5997/6f42626d00e36f53fe51440403446ca61552e2a2.1/_/images/icons/emoticons/smile.png) But Mantaray is an OK JMS provider. The interesting thing about MantaRay is it can support a peer-based network, just as ActiveMQ Classic does with its [peer transport](peer-transport-reference). + +We [benchmark](performance) against Mantaray and other open source JMS providers and in our tests (in which we try to be as objective as possible) ActiveMQ Classic exhibits higher performance in most scenarios. + +A peer transport can be useful when using non-persistent messaging. But if you want persistent messaging you often want to use a federated network with certain brokers on the network being the persistence brokers (so you can backup the file systems etc). + +The ideal topology often depends on your requirements and how you want to manage persistence and deal with hardware failures such as with [MasterSlave](masterslave). + diff --git a/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-mule.md b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-mule.md new file mode 100644 index 0000000000..f7fb60deda --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-mule.md @@ -0,0 +1,31 @@ +--- +title: How does ActiveMQ Classic compare to Mule +layout: classic-doc +--- + + + +Apache ActiveMQ Classic is a messaging provider, with extensive capabilities for message brokering. Mule is described as an ESB, in that it defines and executes the brokering of message exchanges among integrated software components. + +#### Architecture + +Mule provides an accessible programming model for integration, designed to work well with - and leverage - other middleware technologies. For this reason, Mule does not provide a native messaging system, and it is therefore frequently used with Apache ActiveMQ Classic. + +If you use Mule to define an integration based on Apache ActiveMQ Classic, you would use a distinct framework, (the Mule Component Model) to define interfaces for connectivity, as well as mediating activities such as transformations and exception handling. (Note that the Mule framework model presumes a SEDA process model.)Used in this manner, you could think of Mule as a library for defining the interactions among components, with the advantage that it is loosely coupled to both the integrated components and the messaging infrastructure. + +If you have made the choice to use Apache ActiveMQ Classic for messaging and such loose coupling to the messaging infrastructure is not required, you can also configure ActiveMQ Classic directly or through the [Apache Camel container](http://activemq.apache.org/camel/). This may give you access to message handling features not defined in the Mule framework, while still providing connectivity to non-JMS clients through ActiveMQ Classic's numerous options for client connectivity. Working with ActiveMQ Classic directly also allows you to take advantage of clustering and failover capabilities that lie outside the scope of the Mule Component Model. + +#### Points in Common + +The Mule framework is quite user-friendly, is Java-based (Mule components, called Universal Model Objects, are essentially POJOs), and is both flexible (deploys to virtually any Java environment) and lightweight (can be deployed in Spring). These are advantages that it shares with ActiveMQ Classic, so it's not surprising that the two technologies were often used together, before the advent of [Apache Camel](http://activemq.apache.org/camel) + +#### "ESB" versus "Messaging" + +Mule supports a number of integration capabilities that go beyond the scope of messaging, such as BPEL-based orchestration and (SOAP-to-Java) Web Services support. These are rightly described as ESB features, in that they are more than what one would expect from a messaging platform alone. For environments with these requirements, Camel or Mule provides a good extension to the capabilities of ActiveMQ Classic. + +Additional ESB requirements, such as support for a distributed architecture and a native JBI container and components, are not supported by Mule. If you require these capabilities, we encourage you to investigate other open source ESBs that also integrate Apache ActiveMQ Classic, such as [Apache ServiceMix](http://servicemix.org/), and even the [Apache CXF](http://incubator.apache.org/cxf/) service framework. + +#### Commercial Support, Copyright and License + +Both Mule and ActiveMQ Classic have commercial support available from companies dedicated to the technologies. Commercial support options for ActiveMQ Classic are listed [here](../../../support.md). + diff --git a/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-spread-toolkit.md b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-spread-toolkit.md new file mode 100644 index 0000000000..c2c40dc42a --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-activemq-classic-compare-to-spread-toolkit.md @@ -0,0 +1,17 @@ +--- +title: How does ActiveMQ Classic compare to Spread Toolkit +layout: classic-doc +--- + + + +Spread Toolkit is a C++ library for messaging and only has [partial support for JMS](http://www.spread.org/JMS4Spread/docs/). It doesn't support durable messaging, transactions, XA or full JMS 1.1. It is also dependent on a native code Spread daemon running on the machine. + +Apache ActiveMQ Classic on the other hand is the JMS provider used in [Apache Geronimo](http://geronimo.apache.org) and is J2EE 1.4 certified in Geronimo and is 100% pure Java. ActiveMQ Classic supports transient and durable messaging, transactions, XA, J2EE 1.4, JMS 1.1, JCA 1.5 as well as heaps of different features like [Message Groups](message-groups) and [Clustering](clustering) + +Performance guides +------------------ + +If you're not convinced by performance reports then please do try running performance tests yourself. You might wanna check out our overview of [Performance](performance) or try using out the [ActiveMQ Classic Performance Module Users Manual](activemq-classic-performance-module-users-manual) + +[Commercial providers](support#commercial-support) may also be able to help diagnose performance issues, suggest changes, etc... diff --git a/hugo/content/components/classic/documentation/how-does-classic-compare-to-artemis.md b/hugo/content/components/classic/documentation/how-does-classic-compare-to-artemis.md new file mode 100644 index 0000000000..0030ea228c --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-classic-compare-to-artemis.md @@ -0,0 +1,10 @@ +--- +title: How does Classic compare to Artemis? +layout: classic-doc +--- + + + +[Artemis](../../../components/artemis) is the codename used for the HornetQ code that was donated to the Apache Foundation. + +It's a complete broker, similar to ActiveMQ Classic. diff --git a/hugo/content/components/classic/documentation/how-does-connectionfactory-relate-to-the-broker.md b/hugo/content/components/classic/documentation/how-does-connectionfactory-relate-to-the-broker.md new file mode 100644 index 0000000000..e84462e786 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-connectionfactory-relate-to-the-broker.md @@ -0,0 +1,18 @@ +--- +title: How does ConnectionFactory relate to the Broker +layout: classic-doc +--- + + + +How does ConnectionFactory relate to the Broker? +------------------------------------------------ + +The ConnectionFactory is a JMS specification client side interface for creating connections to a JMS broker. The Broker is a service on the network or [embedded in the same JVM](how-do-i-embed-a-broker-inside-a-connection) which provides the message provider. So think of the ConnectionFactory as the client API for sending and receiving messages and the broker is a server side implementation. + +### See Also + +* [How do I create new destinations](how-do-i-create-new-destinations) +* [How do I embed a Broker inside a Connection](how-do-i-embed-a-broker-inside-a-connection) +* [What are administered objects](what-are-administered-objects) + diff --git a/hugo/content/components/classic/documentation/how-does-jms-compare-with-email.md b/hugo/content/components/classic/documentation/how-does-jms-compare-with-email.md new file mode 100644 index 0000000000..13e4d7cb9f --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-jms-compare-with-email.md @@ -0,0 +1,13 @@ +--- +title: How does JMS compare with email +layout: classic-doc +--- + + + +Certainly they both do similar things. The main difference between them is their history and design criteria. + +JMS has a bunch of different qualities of service (durable v non-durable, queue v topic) designed for very high performance messaging with low latency together with reliability. Email is designed for connectivitiy on the web. So they have different design trade offs. e.g. its not a big deal to get multiple copies of an email (which I get fairly often if I loose a connection with an email server over POP for example). It would be a major disaster to get 2 copies of the "remove $1000 from my bank account" messages ![(smile)](https://cwiki.apache.org/confluence/s/en_GB/5997/6f42626d00e36f53fe51440403446ca61552e2a2.1/_/images/icons/emoticons/smile.png) + +The main reasons for using JMS is performance (throughput & latency), together with support for transactions & XA together with avoiding duplicates and message loss. + diff --git a/hugo/content/components/classic/documentation/how-does-journaling-work-with-multiple-brokers.md b/hugo/content/components/classic/documentation/how-does-journaling-work-with-multiple-brokers.md new file mode 100644 index 0000000000..178de11cd7 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-journaling-work-with-multiple-brokers.md @@ -0,0 +1,9 @@ +--- +title: How does journaling work with multiple brokers +layout: classic-doc +--- + + + +Brokers cannot share a journal. Each must be configured with it's own journal. + diff --git a/hugo/content/components/classic/documentation/how-does-openwire-compare-to-stomp.md b/hugo/content/components/classic/documentation/how-does-openwire-compare-to-stomp.md new file mode 100644 index 0000000000..21452b4322 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-openwire-compare-to-stomp.md @@ -0,0 +1,11 @@ +--- +title: How does OpenWire compare to Stomp +layout: classic-doc +--- + + + +[OpenWire](openwire) is the native protocol that Apache ActiveMQ Classic uses. It is designed for performance and size on the wire - sacrificing some ease of implementation with higher performance and reduced network bandwidth as a priority. OpenWire was first released in Apache ActiveMQ Classic 4.0. + +[Stomp](stomp) is a simpler text based protocol which is designed to be very simple to implement in a few hours in any language or platform (e.g. you can use a telnet client to communicate via Stomp). A Stomp client is not going to be as efficient as an client that uses OpenWire, but it much simpler so you can generally be up and running with it much quicker. + diff --git a/hugo/content/components/classic/documentation/how-does-the-journal-work.md b/hugo/content/components/classic/documentation/how-does-the-journal-work.md new file mode 100644 index 0000000000..91a109231a --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-the-journal-work.md @@ -0,0 +1,9 @@ +--- +title: How does the journal work +layout: classic-doc +--- + + + +See the description [here](persistence) + diff --git a/hugo/content/components/classic/documentation/how-does-xbean-compare-to-spring-2.md b/hugo/content/components/classic/documentation/how-does-xbean-compare-to-spring-2.md new file mode 100644 index 0000000000..5f4af591c1 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-does-xbean-compare-to-spring-2.md @@ -0,0 +1,29 @@ +--- +title: How does XBean compare to Spring 2 +layout: classic-doc +--- + + + +Spring 2.0 has introduced the ability to handle custom XML languages inside the spring.xml. This is something we developed [XBean](http://geronimo.apache.org/xbean/) for way back in the Spring 1.x days. + +The Spring hook requires component developers to write their own XML handling, processing DOMs and so forth. On various projects like ActiveMQ Classic, Jencks, Jetty, ServiceMix, XFire - we didn't want to have to spend time hand-crafting parsing of XML code. So XBean is used to auto-create the parsing code along with an XSD and reference documentation for how to configure these services in custom XML languages. + +So you can think of XBean as being like a JAXB2 tool for working inside Spring XML files + +### Spring versions supported + +So you can use XBean in Spring 1.x or Spring 2.x (for Spring 2.0 support you need XBean 2.6 or later along with the matching release of ActiveMQ Classic). + +If you are using Spring 1.x you use the XBean versions of the Spring ApplicationContext classes. In Spring 2.0 the XBean functionality works perfectly fine inside a regular spring.xml file. The only main difference between using the XBean ApplicationContext files and the Spring ones is that the Spring ones mandate validation, so your XML must include all the XSD information (which is handy for IDE completion anyway) whereas this is not mandatory in the XBean configuraiton files. + +### Examples + +Here's a regular Spring 2 XML file using ActiveMQ Classic's XML inside it to configure a broker & destinations & a connection factory + +[http://svn.apache.org/repos/asf/activemq/trunk/activemq-core/src/test/resources/spring-embedded-xbean.xml](http://svn.apache.org/repos/asf/activemq/trunk/activemq-core/src/test/resources/spring-embedded-xbean.xml) + +Here's an example Spring XML for Spring 2 which configures ActiveMQ Classic, ActiveMQ Classic Resource Adapter and Jencks all using Spring 2 with XSD validation (and so completion) + +[http://svn.codehaus.org/jencks/trunk/jencks/src/test/resources/org/jencks/xbean/xbean-validating.xml](http://svn.codehaus.org/jencks/trunk/jencks/src/test/resources/org/jencks/xbean/xbean-validating.xml) + diff --git a/hugo/content/components/classic/documentation/how-fast-is-activemq-classic.md b/hugo/content/components/classic/documentation/how-fast-is-activemq-classic.md new file mode 100644 index 0000000000..0506a33702 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-fast-is-activemq-classic.md @@ -0,0 +1,18 @@ +--- +title: How fast is ActiveMQ Classic +layout: classic-doc +--- + + + +How fast is ActiveMQ Classic? +----------------------------- + +It all depends on the configuration, the operating system, hardware, JVM, JVM configuration and what you're doing. For more details see [Performance](performance) + +Performance guides +------------------ + +If you're not convinced by performance reports then please do try running performance tests yourself. You might wanna check out our overview of [Performance](performance) or try using out the [ActiveMQ Classic Performance Module Users Manual](activemq-classic-performance-module-users-manual) + +[Commercial providers](support#commercial-support) may also be able to help diagnose performance issues, suggest changes, etc... diff --git a/hugo/content/components/classic/documentation/how-lightweight-is-sending-a-message.md b/hugo/content/components/classic/documentation/how-lightweight-is-sending-a-message.md new file mode 100644 index 0000000000..b0825787f6 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-lightweight-is-sending-a-message.md @@ -0,0 +1,19 @@ +--- +title: How lightweight is sending a message +layout: classic-doc +--- + + + +### For ActiveMQ Classic 3.x/4.x + +It depends. + +If you are in a JMS transaction, are using non-durable messaging then its fairly lightweight and fast - typically just blocking until the message has got onto the socket buffer. Though if you are using durable messaging and not using JMS transactions then by default we will perform a blocking request-response with the broker to ensure the message is persisted to disk by the time the call to send() is complete - which is pretty slow. + +However if you really want it to be very lightweight and fast, [enable async sending](configuring-transports) on your JMS connection. + +If you really want low latency, such as in a GUI thread or very high performance server, you probably want to enable asynchronous sending. The only downside of asynchronous sending is if the send fails for whatever reason (security exception typically or some transport failure), then you don't get an exception thrown in the sender thread, since all the work is done asynchronously, though your ErrorListener will get notified. + +(If you use the reliable transport, then you can let the JMS client handle transport errors and drop & reconnect to another broker to handle auto-reconnection for you). + diff --git a/hugo/content/components/classic/documentation/how-should-i-implement-request-response-with-jms.md b/hugo/content/components/classic/documentation/how-should-i-implement-request-response-with-jms.md new file mode 100644 index 0000000000..6749a22083 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-should-i-implement-request-response-with-jms.md @@ -0,0 +1,255 @@ +--- +title: How should I implement request response with JMS +layout: classic-doc +--- + + + +How should I implement request response with JMS? +------------------------------------------------- + +The simplest solution is to use [Camel as a Spring Remoting provider](http://activemq.apache.org/camel/spring-remoting.html) which allows you to hide all the JMS API from your business logic and letting Camel provide the request/response handling code for you. + +However if you wish to write the JMS client code yourself, please read on how it works... + +### Using the JMS API to implement request-response + +You might think at first that to implement request-response type operations in JMS that you should create a new consumer with a selector per request; or maybe create a new temporary queue per request. + +Creating temporary destinations, consumers, producers and connections are all synchronous request-response operations with the broker and so should be avoided for processing each request as it results in lots of chat with the JMS broker. + +The best way to implement request-response over JMS is to create a temporary queue and consumer per client on startup, set JMSReplyTo property on each message to the temporary queue and then use a [correlationID on each message](http://java.sun.com/j2ee/1.4/docs/api/javax/jms/Message.html#setJMSCorrelationID(java.lang.String)) to correlate request messages to response messages. This avoids the overhead of creating and closing a consumer for each request (which is expensive). It also means you can share the same producer & consumer across many threads if you want (or pool them maybe). + +The [Lingo library](http://lingo.codehaus.org/) is an implementation of Spring remoting using JMS. (Spring remoting is a kind of POJO based remoting where the remoting code is invisible to your business logic code). + +It uses exactly this pattern; of using correlation IDs to correlate requests to responses. The server side just has to remember to put the inbound message's correlation ID on the response. + +The actual class which does this is the [MultiplexingRequestor](http://lingo.codehaus.org/maven/apidocs/org/logicblaze/lingo/jms/impl/MultiplexingRequestor.html) . It may be just using Spring remoting with Lingo is the simplest way of implementing request response - or maybe you could just use Lingo's [Requestor](http://lingo.codehaus.org/maven/apidocs/org/logicblaze/lingo/jms/Requestor.html) interface to keep the JMS semantics. + +More details [here](http://docs.codehaus.org/display/LINGO/Request+Response+with+JMS) + +### Client side + +So the client side creates a consumer on a temporary queue as follows... +``` +// client side +Destination tempDest = session.createTemporaryQueue(); +MessageConsumer responseConsumer = session.createConsumer(tempDest); +... + +// send a request.. +message.setJMSReplyTo(tempDest) +message.setJMSCorrelationID(myCorrelationID); + +producer.send(message); +``` + +### Server side +``` +public void onMessage(Message request) { + + Message response = session.createMessage(); + response.setJMSCorrelationID(request.getJMSCorrelationID()) + + producer.send(request.getJMSReplyTo(), response) +} +``` + +Full Examples +------------- + +### Server Side +``` +import org.apache.activemq.broker.BrokerService; +import org.apache.activemq.ActiveMQConnectionFactory; + +import javax.jms.*; + +public class Server implements MessageListener { + private static int ackMode; + private static String messageQueueName; + private static String messageBrokerUrl; + + private Session session; + private boolean transacted = false; + private MessageProducer replyProducer; + private MessageProtocol messageProtocol; + + static { + messageBrokerUrl = "tcp://localhost:61616"; + messageQueueName = "client.messages"; + ackMode = Session.AUTO_ACKNOWLEDGE; + } + + public Server() { + try { + //This message broker is embedded + BrokerService broker = new BrokerService(); + broker.setPersistent(false); + broker.setUseJmx(false); + broker.addConnector(messageBrokerUrl); + broker.start(); + } catch (Exception e) { + //Handle the exception appropriately + } + + //Delegating the handling of messages to another class, instantiate it before setting up JMS so it + //is ready to handle messages + this.messageProtocol = new MessageProtocol(); + this.setupMessageQueueConsumer(); + } + + private void setupMessageQueueConsumer() { + ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(messageBrokerUrl); + Connection connection; + try { + connection = connectionFactory.createConnection(); + connection.start(); + this.session = connection.createSession(this.transacted, ackMode); + Destination adminQueue = this.session.createQueue(messageQueueName); + + //Setup a message producer to respond to messages from clients, we will get the destination + //to send to from the JMSReplyTo header field from a Message + this.replyProducer = this.session.createProducer(null); + this.replyProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + + //Set up a consumer to consume messages off of the admin queue + MessageConsumer consumer = this.session.createConsumer(adminQueue); + consumer.setMessageListener(this); + } catch (JMSException e) { + //Handle the exception appropriately + } + } + + public void onMessage(Message message) { + try { + TextMessage response = this.session.createTextMessage(); + if (message instanceof TextMessage) { + TextMessage txtMsg = (TextMessage) message; + String messageText = txtMsg.getText(); + response.setText(this.messageProtocol.handleProtocolMessage(messageText)); + } + + //Set the correlation ID from the received message to be the correlation id of the response message + //this lets the client identify which message this is a response to if it has more than + //one outstanding message to the server + response.setJMSCorrelationID(message.getJMSCorrelationID()); + + //Send the response to the Destination specified by the JMSReplyTo field of the received message, + //this is presumably a temporary queue created by the client + this.replyProducer.send(message.getJMSReplyTo(), response); + } catch (JMSException e) { + //Handle the exception appropriately + } + } + + public static void main(String\[\] args) { + new Server(); + } +} +``` + +### Client Side +``` +import org.apache.activemq.ActiveMQConnectionFactory; + +import javax.jms.*; +import java.util.Random; + +public class Client implements MessageListener { + private static int ackMode; + private static String clientQueueName; + + private boolean transacted = false; + private MessageProducer producer; + + static { + clientQueueName = "client.messages"; + ackMode = Session.AUTO_ACKNOWLEDGE; + } + + public Client() { + ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); + Connection connection; + try { + connection = connectionFactory.createConnection(); + connection.start(); + Session session = connection.createSession(transacted, ackMode); + Destination adminQueue = session.createQueue(clientQueueName); + + //Setup a message producer to send message to the queue the server is consuming from + this.producer = session.createProducer(adminQueue); + this.producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + + //Create a temporary queue that this client will listen for responses on then create a consumer + //that consumes message from this temporary queue...for a real application a client should reuse + //the same temp queue for each message to the server...one temp queue per client + Destination tempDest = session.createTemporaryQueue(); + MessageConsumer responseConsumer = session.createConsumer(tempDest); + + //This class will handle the messages to the temp queue as well + responseConsumer.setMessageListener(this); + + //Now create the actual message you want to send + TextMessage txtMessage = session.createTextMessage(); + txtMessage.setText("MyProtocolMessage"); + + //Set the reply to field to the temp queue you created above, this is the queue the server + //will respond to + txtMessage.setJMSReplyTo(tempDest); + + //Set a correlation ID so when you get a response you know which sent message the response is for + //If there is never more than one outstanding message to the server then the + //same correlation ID can be used for all the messages...if there is more than one outstanding + //message to the server you would presumably want to associate the correlation ID with this + //message somehow...a Map works good + String correlationId = this.createRandomString(); + txtMessage.setJMSCorrelationID(correlationId); + this.producer.send(txtMessage); + } catch (JMSException e) { + //Handle the exception appropriately + } + } + + private String createRandomString() { + Random random = new Random(System.currentTimeMillis()); + long randomLong = random.nextLong(); + return Long.toHexString(randomLong); + } + + public void onMessage(Message message) { + String messageText = null; + try { + if (message instanceof TextMessage) { + TextMessage textMessage = (TextMessage) message; + messageText = textMessage.getText(); + System.out.println("messageText = " + messageText); + } + } catch (JMSException e) { + //Handle the exception appropriately + } + } + + public static void main(String\[\] args) { + new Client(); + } +} +``` + +### Protocol Class + +This class is needed to run the client/server example above. Delegating the handling of messages to a seperate class is solely a personal preference. +``` +public class MessageProtocol { + public String handleProtocolMessage(String messageText) { + String responseText; + if ("MyProtocolMessage".equalsIgnoreCase(messageText)) { + responseText = "I recognize your protocol message"; + } else { + responseText = "Unknown protocol message: " + messageText; + } + + return responseText; + } +} +``` diff --git a/hugo/content/components/classic/documentation/how-should-i-package-applications-using-camel-and-activemq-classic.md b/hugo/content/components/classic/documentation/how-should-i-package-applications-using-camel-and-activemq-classic.md new file mode 100644 index 0000000000..66f413c9d3 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-should-i-package-applications-using-camel-and-activemq-classic.md @@ -0,0 +1,18 @@ +--- +title: How should I package applications using Camel and ActiveMQ Classic +layout: classic-doc +--- + + +How should I package applications using Camel and ActiveMQ Classic +---------------------------------------------------------- + +So you may wish to use Camel's [Enterprise Integration Patterns](enterprise-integration-patterns) inside the ActiveMQ Classic Broker. In which case the stand alone broker is already packaged to work with Camel out of the box; just add your EIP routing rules to ActiveMQ Classic's [Xml Configuration](xml-configuration) like the example routing rule which ships with ActiveMQ Classic 5.x or later. If you want to include some Java routing rules, then just add your jar to somewhere inside ActiveMQ Classic's lib directory. + +If you wish to use ActiveMQ Classic and/or Camel in a standalone application, we recommend you just create a normal Spring application; then add the necessary jars and customise the Spring XML and you're good to go. + +### What jars do I need + +* [what jars are required for ActiveMQ Classic](initial-configuration) +* [what jars are required for Camel](what-jars-do-i-need) + diff --git a/hugo/content/components/classic/documentation/how-should-i-use-the-vm-transport.md b/hugo/content/components/classic/documentation/how-should-i-use-the-vm-transport.md new file mode 100644 index 0000000000..7648cc0b2b --- /dev/null +++ b/hugo/content/components/classic/documentation/how-should-i-use-the-vm-transport.md @@ -0,0 +1,30 @@ +--- +title: How should I use the VM transport +layout: classic-doc +--- + + + +### For ActiveMQ Classic 3.x/4.x + +[Using the VM transport](how-do-i-use-activemq-classic-using-in-jvm-messaging) to connect to an in-JVM broker is the fastest and most efficient transport you can use. + +This is because by default there is no serialization to a socket or operating system socket resources used up; its purely an in-JVM List used to exchange messages with clients and the broker. Sometimes you want the VM transport to work as an async SEDA queue; other times you want to inline the processing so that there are less thread context switches which can improve throughput in high performance scenarios. + +One thing to note with the VM transport is that messages are passed by reference. One slight exception to this is the JMS ObjectMessage. (see below for details on how to disable it in ActiveMQ Classic 4.x) + +You can also further optimise things by setting the **copyMessageOnSend** property to be false; which avoids making a copy of the ObjectMessage to send; though this assumes that you don't try and resuse the ObjectMessage instance; you just create it once and send it once and don't try and change the body of the message after sending it. + +Be careful of ClassLoaders + +Note that you should only perform the above optimisation if all the producers and consumers are in a compatible class loader. For example if you have 2 WARs with their own jars which are sending messages to each other, you could get strange ClassCastExceptions occuring due to the same class being loaded in each class loader; so sometimes serializing ObjectMessage is a good thing to avoid ClassPath hell - so only perform the above optimisation if you are sure you're ClassPaths are OK + +### Disabling Object serialization with ObjectMessage for ActiveMQ Classic 4.x + +The JMS specification dictates that the body of an ObjectMessage must be serialized when you call send() to avoid the object changing under your feet affecting what view the consumer sees of the object. + +You can disable the automatic serialization of ObjectMessage payloads so that the objects are passed by value in 4.x by setting the **objectMessageSerializationDefered** flag to true on the ActiveMQConnectionFactory (or ActiveMQConnection). +``` +ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost"); +factory.setObjectMessageSerializationDefered(true); +``` diff --git a/hugo/content/components/classic/documentation/how-to-configure-a-new-database.md b/hugo/content/components/classic/documentation/how-to-configure-a-new-database.md new file mode 100644 index 0000000000..e991ae0f31 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-to-configure-a-new-database.md @@ -0,0 +1,44 @@ +--- +title: How to configure a new database +layout: classic-doc +--- + + + +ActiveMQ Classic explicity supports Derby, Axion, HSQL, Oracle, and SQLServer. Below are the steps on how to configure a new database. + +1. Modify activemq.xml found in the directory "activemq_home/conf" by editing or adding a JDBC DataSource Configuration, e.g.: + + ``` + + + + + + + + ``` + **For AMQ 3.x** + ``` + + + com.microsoft.jdbc.sqlserver.SQLServerDriver + + + jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=activedb + + + sa + + + + + + true + + + ``` +2. Set the datasource reference to use the new jdbc configuration e.g `` + +3. Place the jdbc driver in the directory "activemq_home/lib/optional". + diff --git a/hugo/content/components/classic/documentation/how-to-deal-with-large-number-of-threads-in-clients.md b/hugo/content/components/classic/documentation/how-to-deal-with-large-number-of-threads-in-clients.md new file mode 100644 index 0000000000..36d25bdbcf --- /dev/null +++ b/hugo/content/components/classic/documentation/how-to-deal-with-large-number-of-threads-in-clients.md @@ -0,0 +1,36 @@ +--- +title: How to deal with large number of threads in clients +layout: classic-doc +--- + + + +If you study thread allocation in ActiveMQ Classic clients, you'll notice that by default there is one thread allocated by every session. This basically means that session will use its [ThreadPoolExecutor](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html) to execute its tasks. Up until version 5.7 this executor was unbound which could lead to OOM problems in rare case where are a large number of busy sessions in the same JVM could cause uncontrollable spikes in thread creation. + +In 5.7 we bounded this executor to a maximum of 1000 threads by default, which we believe should be enough for most use cases. In case of large number of busy sessions, each of them could end up using large number of threads and eventually OOM your application. There are couple of things you can do. The first obvious thing is to decrease the max thread limit a session can use, like this: +``` +ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); +connectionFactory.setMaxThreadPoolSize(10); +Connection conn = connectionFactory.createConnection(); +conn.start(); +``` +On the other hand this can lead to the scenario where a single session exaust its max thread number. A default behavior of `ThreadPoolExecutor` in this case is to throw an exception, so you'll notice it. A workaround for this scenario is to provide a rejected task handler that will synchronize the execution with the calling thread, like this +``` +ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); +connectionFactory.setRejectedTaskHandler(new ThreadPoolExecutor.CallerRunsPolicy()); +Connection conn = connectionFactory.createConnection(); +conn.start(); +``` +This will prevent the `ThreadPoolExecutor` from throwing an exception when it reaches its bound. Instead it will execute the rejected task in the calling thread. + +Finally, you can eliminate these threads completly, you can do that by setting `alwaysSessionAsync` property to false +``` +ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); +connectionFactory.setAlwaysSessionAsync(false); +Connection conn = connectionFactory.createConnection(); +conn.start(); +``` +However you need to have in mind that this approach can affect performance of the whole system. + +So there you go. In the unlikely scenario where your application has trouble with the number of threads created by JMS session, you can use one of the shown techniques to deal with it. As always there's no silver bullet for all scenarios, so measure and tune for your system. + diff --git a/hugo/content/components/classic/documentation/how-to-deploy-activemq-ra-versionrar-to-weblogic.md b/hugo/content/components/classic/documentation/how-to-deploy-activemq-ra-versionrar-to-weblogic.md new file mode 100644 index 0000000000..d93dfb9511 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-to-deploy-activemq-ra-versionrar-to-weblogic.md @@ -0,0 +1,35 @@ +--- +title: How to deploy activemq-ra-version.rar to weblogic +layout: classic-doc +--- + + + +### This is a guide on how to deploy ActiveMQ Classic's resouce adapter to weblogic 9.1. + +1. Create a new domain in weblogic using the configuration wizard (Start menu BEA Products -> Tools -> configuration Wizard ). +2. Add the jar dependencies (these are the jars inside the rar file..for some reason weblogic is not loading these from the rar file)  in the classpath . One way to do this is by dropping the jars in the lib directory of the domain (`<%BEA\_HOME%>`\user_projects\domains\\`<%DOMAIN_NAME%>`\lib).  +3. Add the BrokerXmlConfig file called "broker-config.xml" in the classpath. This can be found in the rar file "activemq-rar-*.rar". Otherwise, modify ra.xml by providing an absolute path to "broker-config.xml", see below. + ``` + + + Sets the XML configuration file used to configure the ActiveMQ Classic broker via + Spring if using embedded mode. + + BrokerXmlConfig is the filename which is assumed to be on the classpath unless + a URL is specified. So a value of foo/bar.xml would be assumed to be on the + classpath whereas file:dir/file.xml would use the file system. + Any valid URL string is supported. + + BrokerXmlConfig + java.lang.String + xbean:file:C:\\broker-config.xml + + ``` +2. Start the domain's weblogic server (BEA Products -> User Projects -> `` -> Start Admin Server for Weblogic Server Domain). +3. Start the domain's admin console (BEA Products -> User Projects -> `` -> Admin Server Console) and enter the username and password. +4. On the main menu, click "Deployments" under "Your Deployed Resources" +5. On the deployment table, click "install" button. If the button is disabled, then click "Lock & Edit" to enable it. +6. Browse for the activemq-ra-*.rar file then click next (for testing purpose, choose the default onwards). +7. Click the "activate changes" button to check if the resource adapter is properly deployed. + diff --git a/hugo/content/components/classic/documentation/how-to-disable-auto-destination-creation.md b/hugo/content/components/classic/documentation/how-to-disable-auto-destination-creation.md new file mode 100644 index 0000000000..69788debed --- /dev/null +++ b/hugo/content/components/classic/documentation/how-to-disable-auto-destination-creation.md @@ -0,0 +1,9 @@ +--- +title: How to disable auto destination creation +layout: classic-doc +--- + + + +see [How do I restrict connections from creating new queues or topics](how-do-i-restrict-connections-from-creating-new-queues-or-topics) + diff --git a/hugo/content/components/classic/documentation/how-to-disable-multicast-discovery.md b/hugo/content/components/classic/documentation/how-to-disable-multicast-discovery.md new file mode 100644 index 0000000000..7df7991420 --- /dev/null +++ b/hugo/content/components/classic/documentation/how-to-disable-multicast-discovery.md @@ -0,0 +1,28 @@ +--- +title: How to disable multicast discovery +layout: classic-doc +--- + + + +By default, the [ActiveMQ Classic xml configuration](xml-configuration) includes the [multicast discovery](discovery) mechanism. The tcp transport connector advertises its self using multicast and a multicast network connector is configured to listen to the same address. In this way, all brokers that share the default multicast address will automatically network with each other. +If multicast is not required, the multicast attributes of the Transport Connector and Network Connector can be removed. + +To stop advertising your connection URI on the multicast network remove the discoveryUri attribute from the ``: + +replace: +``` + +``` +with: +``` + +``` +If you do not require any networked broker support remove the altogether. Remove +``` + +``` +Alternatively, provide a static networkConnector for each broker you wish to network with by replacing the the discoveryUri with the static transport connection URI of your target broker. + +For more information see the [Discovery Transport Reference](discovery-transport-reference) + diff --git a/hugo/content/components/classic/documentation/how-to-unit-test-jms-code.md b/hugo/content/components/classic/documentation/how-to-unit-test-jms-code.md new file mode 100644 index 0000000000..947445f1ab --- /dev/null +++ b/hugo/content/components/classic/documentation/how-to-unit-test-jms-code.md @@ -0,0 +1,114 @@ +--- +title: How To Unit Test JMS Code +layout: classic-doc +--- + + + +When unit testing code with JMS you'll typically want to avoid the overhead of running separate proceses; plus you'll want to increase startup time as fast as possible as you tend to run unit tests often and want immediate feedback. Also persistence can often cause problems - as previous test case results can adversely affect future test case runs - so you often need to purge queues on startup. + +So when unit testing JMS code we recommend the following + +* Use [an embedded broker](how-do-i-embed-a-broker-inside-a-connection) to avoid a separate broker process being required. +* Disable [broker persistence](broker-configuration-uri) so that no queue purging is required before/after tests. +* It's often simpler and faster to just use Java code to create the broker via an XML configuration file using Spring etc. + +You can do all of this using the following Java code to create your JMS `ConnectionFactory` which will also automatically create an embedded broker +``` +ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false"); +``` +For more configuration options see the [VM Transport Reference](vm-transport-reference) and the [Broker Configuration URI](broker-configuration-uri) + +Or if you really would rather be more explicit you can create the broker first using the following Java code +``` +BrokerService broker = new BrokerService(); +broker.setPersistent(false); +broker.start(); +``` +or you could use [Spring Support.](spring-Community/support) + +### Using JNDI + +If your application code is using JNDI to lookup the JMS `ConnectionFactory` and `Destination`'s to use, then you could use the [JNDI Support](jndi-support) in ActiveMQ Classic. + +Add the following `jndi.properties` to your classpath, e.g., in `src/test/resources`, if you are using maven: +``` +java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory +java.naming.provider.url = vm://localhost?broker.persistent=false +``` +You should then consider using [Dynamic destinations in JNDI](jndi-Community/support) so that your code looks up destinations via +``` +context.lookup("dynamicQueues/FOO.BAR"); +``` + +### Using The `EmbeddedActiveMQBroker` JUnit Rule (ActiveMQ 5.13) + +If your test code is using JUnit, then you could use the `EmbeddedActiveMQBroker` JUnit Rule provided in the `activemq-junit` library. Add the `activemq-junit` library along with the `activemq-broker` libraries for the version of ActiveMQ Classic you want to test with.  The rule will use whatever version of ActiveMQ Classic it finds in the classpath, so the ActiveMQ Classic libraries need to be specified if they are not already there. + +If you are using Maven, add the following to your `pom.xml`: +``` + + org.apache.activemq.tooling + activemq-junit + ${activemq-junit-version} + test + + + + org.apache.activemq + activemq-broker + ${activemq-version} + test + +``` + Then add the `EmbeddedActiveMQBroker` JUnit Rule to your test, and JUnit will start the embedded broker at the beginning of each test and stop the broker at the end of the test. + +**Use The ActiveMQ Classic JUnit Rule** +``` +@Rule +public EmbeddedActiveMQBroker broker = new EmbeddedActiveMQBroker(); +``` +By default, the `EmbeddedActiveMQBroker` will configure the broker as non-persistent, and the only transport available will be the VM transport. To customize this configuration, either extend the `EmbeddedActiveMQBroker` class and override the `configure()` method, or use an XML configuration for the broker.   + +**Note**: to configure an `EmbeddedActiveMQBroker` using XML configuration, you may need to add additional libraries to the classpath to support XBean configuration of ActiveMQ. + +**Customizing An EmbeddedActiveMQBroker Using Java** +``` +@Rule +EmbeddedActiveMQBroker customizedBroker = new EmbeddedActiveMQBroker() { + @Override + protected void configure() { + // Perform additional configuration here... + } +} +``` + +**Customizing An EmbeddedActiveMQBroker Using XML Configuration** +``` +@Rule +EmbeddedActiveMQBroker customizedBroker = new EmbeddedActiveMQBroker("bean:customize-activemq.xml"); +``` +Note that to use the XML configuration, you may need to add additional libraries on the classpath to support the XBean configuration of ActiveMQ Classic.  The versions of the `spring-context` library should correspond with the version used by your selected version of ActiveMQ Classic. + +**Maven Configuration For XBean Configuration** +``` + + org.springframework + spring-context + Appropriate version for activemq-version + + + + org.apache.activemq + activemq-spring + ${activemq-version> + +``` +Then you can use the VM URI to connect with the broker +``` +ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://embedded-broker?create=false"); +``` +You can also get a connection factory from the `EmbeddedActiveMQBroker`: +``` +ConnectionFactory connectionFactory = embeddedBroker.createConnectionFactory(); +``` diff --git a/hugo/content/components/classic/documentation/i-am-having-problems-with-the-spring-jmstemplate.md b/hugo/content/components/classic/documentation/i-am-having-problems-with-the-spring-jmstemplate.md new file mode 100644 index 0000000000..e173dc3434 --- /dev/null +++ b/hugo/content/components/classic/documentation/i-am-having-problems-with-the-spring-jmstemplate.md @@ -0,0 +1,12 @@ +--- +title: I am having problems with the Spring JmsTemplate +layout: classic-doc +--- + + + +I am having problems with the Spring JmsTemplate +------------------------------------------------ + +For more detail see the [JmsTemplate Gotchas](jmstemplate-gotchas) page along with the [Spring Support](spring-Community/support) + diff --git a/hugo/content/components/classic/documentation/i-am-not-receiving-any-messages-what-is-wrong.md b/hugo/content/components/classic/documentation/i-am-not-receiving-any-messages-what-is-wrong.md new file mode 100644 index 0000000000..d67e15a420 --- /dev/null +++ b/hugo/content/components/classic/documentation/i-am-not-receiving-any-messages-what-is-wrong.md @@ -0,0 +1,21 @@ +--- +title: I am not receiving any messages, what is wrong +layout: classic-doc +--- + + + +### I am not receiving any messages - what is wrong? + +A _very_ common gotcha when working with JMS is forgetting to start the JMS connection, creating a consumer and not having it receive any messages. I myself have tripped up over this one many many times! ![(smile)](https://cwiki.apache.org/confluence/s/en_GB/5997/6f42626d00e36f53fe51440403446ca61552e2a2.1/_/images/icons/emoticons/smile.png) + +Make sure you call the [start()](http://java.sun.com/j2ee/1.4/docs/api/javax/jms/Connection.html#start()) method on the JMS connection, otherwise messages will not be dispatched to your consumer. + +This is such a common gotcha that as of 4.2 onwards, ActiveMQ Classic will now [log a warning if a message](https://issues.apache.org/activemq/browse/AMQ-1253) is received shortly after the connection was created if the connection was not started (as its so easy to forget to do this part ![(smile)](https://cwiki.apache.org/confluence/s/en_GB/5997/6f42626d00e36f53fe51440403446ca61552e2a2.1/_/images/icons/emoticons/smile.png). + +For more details see the discussion of the **warnAboutUnstartedConnectionTimeout** property on the [Connection Configuration URI](connection-configuration-uri) + +### If you are calling connection.start() + +Another common gotcha is [due to another consumer grabbing the messages](i-do-not-receive-messages-in-my-second-consumer). If it's not that then please look at [JMX](jmx) or the [Web Console](web-console) to determine what consumers are available and their status. Then report an [issue](issues) to help you resolve your issue. + diff --git a/hugo/content/components/classic/documentation/i-cannot-connect-to-activemq-classic-from-jconsole.md b/hugo/content/components/classic/documentation/i-cannot-connect-to-activemq-classic-from-jconsole.md new file mode 100644 index 0000000000..4dc60205e7 --- /dev/null +++ b/hugo/content/components/classic/documentation/i-cannot-connect-to-activemq-classic-from-jconsole.md @@ -0,0 +1,19 @@ +--- +title: I cannot connect to ActiveMQ Classic from JConsole +layout: classic-doc +--- + + + +Make sure that the machine you are talking to has a valid **java.rmi.server.hostname-property** value + +e.g. on unix (OS X, Linux, Solaris) +``` +export ACTIVEMQ\_OPTS=$ACTIVEMQ\_OPTS -Djava.rmi.server.hostname= +activemq +``` +or on Windows +``` +SET ACTIVEMQ\_OPTS=%ACTIVEMQ\_OPTS% -Djava.rmi.server.hostname= +activemq +``` diff --git a/hugo/content/components/classic/documentation/i-do-not-receive-messages-in-my-second-consumer.md b/hugo/content/components/classic/documentation/i-do-not-receive-messages-in-my-second-consumer.md new file mode 100644 index 0000000000..638d9968bc --- /dev/null +++ b/hugo/content/components/classic/documentation/i-do-not-receive-messages-in-my-second-consumer.md @@ -0,0 +1,38 @@ +--- +title: I do not receive messages in my second consumer +layout: classic-doc +--- + + + +### Scenario + +* You send 100 messages to a queue. +* Start consumer A, it receives the message +* You start another consumer B, it doesn't receive any messages. +* You kill A. +* Consumer B receives messages now, why? + +### Answer + +This is to do with [prefetch buffers](what-is-the-prefetch-limit-for). + +ActiveMQ Classic will try and deliver a number of messages to each consumer as soon as possible to achieve maximum throughput. That means that each consumer typically has 100-1000 messages in RAM ready to be processed so that there is no latency waiting for another message to arrive under periods of high throughput of messages. + +The problem is, if consumer A is set with a prefetch value of >= 100 then it will receive all of the messages before consumer B starts. Then when B starts there are actually no messages available to be dispatched to B (since they are all dispatched to A) until either + +* new messages are sent to the queue +* consumer A stops or its JVM dies + +The solution to this problem is to configure the pre-fetch value to something smaller - such as 1, start the consumers together or publish the messages after the consumers have started. + +You can also [change the dispatch policy](how-do-i-change-dispatch-policy) to ensure round robin dispatch. + +To help diagnose these kinds of issues, try [JMX](jmx) or the [Web Console](web-console) + +### See also + +* [How do I change dispatch policy](how-do-i-change-dispatch-policy) +* [JMX](jmx) +* [Web Console](web-console) + diff --git a/hugo/content/components/classic/documentation/i-get-errors-building-the-code-whats-wrong.md b/hugo/content/components/classic/documentation/i-get-errors-building-the-code-whats-wrong.md new file mode 100644 index 0000000000..cc530e667e --- /dev/null +++ b/hugo/content/components/classic/documentation/i-get-errors-building-the-code-whats-wrong.md @@ -0,0 +1,15 @@ +--- +title: I get errors building the code whats wrong +layout: classic-doc +--- + + + +We currently use a multi-project maven build system, which can be a little fragile. If you are ever having problems building we suggest you try the following in the root _activemq_ directory +``` +mvn clean +rm -rf ~/.m2/repository +mvn +``` +You may also want to [disable the unit tests](how-do-i-build-but-disable-the-unit-tests) + diff --git a/hugo/content/components/classic/documentation/i-see-nc-client-ids-what-does-that-mean.md b/hugo/content/components/classic/documentation/i-see-nc-client-ids-what-does-that-mean.md new file mode 100644 index 0000000000..8eac5f91d2 --- /dev/null +++ b/hugo/content/components/classic/documentation/i-see-nc-client-ids-what-does-that-mean.md @@ -0,0 +1,16 @@ +--- +title: I see NC_ client-ids, what does that mean +layout: classic-doc +--- + + + +Durable subscription ClientIds and SubscriptionNames using the **NC** prefix are the result of durable subscriptions in a [Networks of Brokers](networks-of-brokers). +When a durable subscription is being forwarded by a network connector (or demand forwarding bridge), the network durable subscription needs to outlive the subscription that created it. This is achieved by using a well known name for the clientId and subscriptionName that can be easily be mapped to the original subscription. The prefix NC_, and NC-DS_ are used, where NC denotes Network Connector and DS denotes Durable Subscription. The prefix is combined with the local broker name and the target destination. + +The expectation is that the connectionId associated with these subscriptions can change on a reconnect, but the durable subsctiption remains. In this way, the durable subscription can continue to receive messages even if there is a network partition between the originating broker and the forwarding broker. + +On a restart, the NC durable subscriptions are activated by default, to ensure that no messages are lost. If lost messages are acceptable, it is possible to ensure that the NC durable sub is activated dynamically, when the original subscription is again activated on the remote broker and propagated to the network connector. The network connector configuration 'dynamicOnly' attribute is used to control this behavior. + +A NC durable subscription is only deleted when the original durable consumer is unsubscribed. + diff --git a/hugo/content/components/classic/documentation/integration-tests.md b/hugo/content/components/classic/documentation/integration-tests.md new file mode 100644 index 0000000000..a0a634c371 --- /dev/null +++ b/hugo/content/components/classic/documentation/integration-tests.md @@ -0,0 +1,49 @@ +--- +title: Integration Tests +layout: classic-doc +--- + +## Integration Tests + +The Integration Tests validate that the ActiveMQ Classic Resource Adapter operates correctly when deployed with a J2EE application running in an Application Server such as Apache Geronimo. + +### Getting Ready + +The instructions on this page reference a few directories that you will need to substitute appropriate values for: + +- `activemq-core` is where your ActiveMQ Classic source code is located. +- `geronimo-home` is where your Geronimo home directory is located. + +### Building the ActiveMQ Classic Resource Adapter + +The ActiveMQ Classic Resource Adapter allows a J2EE Application Server to provide transaction management, connection pooling and security to ActiveMQ Classic connections when used by EJBs. +``` +cd activemq-ra +maven rar:install-snapshot +``` + +### Building the Integration Test EJB Module +``` +cd systest/itests/ejb +maven +``` + +### Building and Deploying the Integration Test EAR Module +``` +cd systest/itests/ear +maven -Dgeronimo.home=geronimo-home +``` + +### Starting Geronimo with the Integration Test EAR Configuration + +In a separate console: +``` +cd geronimo-home +java -jar bin/server.jar org/activemq/ear/itest +``` + +### Building and Running the Integration Tests +``` +cd systest/itests/client +maven +``` diff --git a/hugo/content/components/classic/documentation/ioexception-could-not-find-class-for-resource.md b/hugo/content/components/classic/documentation/ioexception-could-not-find-class-for-resource.md new file mode 100644 index 0000000000..a09c997165 --- /dev/null +++ b/hugo/content/components/classic/documentation/ioexception-could-not-find-class-for-resource.md @@ -0,0 +1,30 @@ +--- +title: IOException - could not find class for resource +layout: classic-doc +--- + + + +If you get an exception looking like this +``` +Reason: java.io.exception : could not find class for resource: META-INF/services/org/apache/activemq/transport/tcp +``` + +### Cause + +You are probably using the ActiveMQ Classic source code without using the resources + +### Quick fix + +Try one of these + +* use one of the distribution jars for ActiveMQ Classic +* use Maven to run your program +* try adding activemq/src/conf to your classpath + +### Background + +Then it means that the files in META-INF/services could not be found on the classpath. These files are used to support loose coupling on ActiveMQ Classic with the transport protocols (e.g. to avoid a classpath dependency on JXTA) and to allow dynamic protocol enhancement without a change to the core. + +So we're using the META-INF/services files as a way of coupling a protocol used in URL connections to a Java class name. + diff --git a/hugo/content/components/classic/documentation/is-there-a-specified-size-of-the-journal.md b/hugo/content/components/classic/documentation/is-there-a-specified-size-of-the-journal.md new file mode 100644 index 0000000000..8fca431001 --- /dev/null +++ b/hugo/content/components/classic/documentation/is-there-a-specified-size-of-the-journal.md @@ -0,0 +1,9 @@ +--- +title: Is there a specified size of the journal +layout: classic-doc +--- + + + +There is a "preferred" size for each log file of the journal. By default there are 2 20 meg log files. + diff --git a/hugo/content/components/classic/documentation/j2ee.md b/hugo/content/components/classic/documentation/j2ee.md new file mode 100644 index 0000000000..4e8668dd43 --- /dev/null +++ b/hugo/content/components/classic/documentation/j2ee.md @@ -0,0 +1,58 @@ +--- +title: J2EE +layout: classic-doc +--- + + + +In J2EE 1.4 or later the standard way to integrate with a JMS provider is via JCA 1.5 and a [Resource Adapter](resource-adapter). + +Introduction +------------ + +ActiveMQ Classic includes a Java Connector Architecture (JCA) 1.5 Resource Adapter. JCA 1.5 defines the contract between an J2EE application server and external resources such as databases and messaging middleware. It allows the application server to efficiently pool connections, control transactions and manage security. The Resource Adapter allows ActiveMQ Classic to be used from any J2EE 1.4 application server. We have tested that the Resource Adapter works in the following J2EE 1.4 containers + +* [TomEE](http://tomee.apache.org/tomcat-jms) 1 +* Geronimo 1 +* GlassFish +* JBoss 4 +* WebLogic 9 +* WebSphere 6 + +Features +-------- + +* Inbound connection delivers messages to MDBs via XA or local transactions. +* Outbound connections support standard container pooling or can reuse the inbound connection/session to avoid XA. +* JTA support: Can be enlisted in XA and local transactions. +* XA transaction recovery via XAResource.recover() supported. +* When used outside a JTA transaction, session transaction settings retain normal JMS semantics so that it be used by your web-app tier. +* Can configure and start up embedded broker. +* Can connect to external ActiveMQ Classic broker or embedded broker. +* Inbound message delivery supports fine grain control of concurrency and prefetching. +* Batching so that multiple messages can be delivered within the same transaction for optimal performances. + +Downloading the RAR +------------------- + +The RAR is available via [maven central](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22activemq-rar%22) + +Deployment Guides + +* [TomEE](Resource Adapter/tomee) +* [Geronimo](geronimo) +* [Integrating Apache ActiveMQ Classic with Glassfish](integrating-apache-activemq-classic-with-glassfish) +* [JBoss Integration](jboss-integration) + +The use of an Embedded Broker +----------------------------- + +The ActiveMQ Classic Resource Adapter can connect to a remote broker using any of the available transports, or it can start up an embedded broker. As described in the [Resource Adapter Properties](Resource Adapter/resource-adapter-properties), you can enable an embedded broker using the **BrokerXmlConfig** property. + +Configuration Reference +----------------------- + +* [Resource Adapter Properties](Resource Adapter/resource-adapter-properties) +* [Connection Factory Properties](Resource Adapter/connection-factory-properties) +* [Activation Spec Properties](Resource Adapter/activation-spec-properties) + diff --git a/hugo/content/components/classic/documentation/java-service-wrapper.md b/hugo/content/components/classic/documentation/java-service-wrapper.md new file mode 100644 index 0000000000..e808d3571a --- /dev/null +++ b/hugo/content/components/classic/documentation/java-service-wrapper.md @@ -0,0 +1,54 @@ +--- +title: Java Service Wrapper +layout: classic-doc +--- + + + +This page provides some useful information on running the ActiveMQ Classic broker as a windows-NT service or a daemon thread in Linux or Unix systems. + +64bit 4gb memory limit + +The ActiveMQ Classic distribution uses an older and free community release of the service wrapper library. This wrapper has a memory limit of 4gb when running on 64bit platforms. You can manually [download a newer release](http://wrapper.tanukisoftware.com/doc/english/download.jsp) of the wrapper library that does not have this limit, from the vendors website at. It us not possible for Apache ActiveMQ Classic to update and distribute a newer release of the service wrapper, as the vendor changed licensing terms, which does not comply with ASF licensing terms. Therefore out of the box the service wrapper is stuck on that older release. + +However you can manually upgrade the library. + +### Windows-NT Service + +Here are the steps to install the ActiveMQ Classic broker as an NT service: + +1. Download the windows binary distribution (i.e. apache-activemq-5.9.0.zip) +2. Go to ACTIVEMQ_HOME/bin/win32 +3. Run InstallService.bat + +After running InstallService.bat, the ActiveMQ Classic service should be added to the list of NT services. It is not started by default. + +To verify, go to control panel -> administrative tools -> services and look for the ActiveMQ Classic service. Here you can start the ActiveMQ Classic service or configure it to start automatically every time the system boots. + +To remove the ActiveMQ Classic service: + +1. Run UninstallService.bat + +### Linux/Mac OS X Daemon + +Here are the steps to run the ActiveMQ Classic broker as a daemon in Linux or Unix systems: + +1. Download the linux/unix binary distribution (i.e. apache-activemq-5.9.0.tar.gz) +2. Go to ACTIVEMQ\_HOME/linux for linux systems or ACTIVEMQ\_HOME/macosx for Mac OS X systems. +3. Run ./activemq start + +To stop the daemon process: + +1. Go to ACTIVEMQ\_HOME/linux for linux systems or ACTIVEMQ\_HOME/macosx for Mac OS X systems. +2. Run ./activemq stop + +###  Configuring the Java Service Wrapper + +ActiveMQ Classic uses the [Java Service Wrapper](http://wrapper.tanukisoftware.org/doc/english/introduction.html) to run the broker. To configure how the Java Service Wrapper starts up, you can edit the wrapper.conf located in the bin/win32, bin/linux, or bin/macosx depending on which system you are running it. For more information on the different properties of the Java Service Wrapper, refer to this [page](http://wrapper.tanukisoftware.org/doc/english/properties.html) + +###  Troubleshooting + +If you are having problems running the service, turn on the wrapper debugging in the corresponding wrapper.conf file via (wrapper.debug=TRUE) + +Each time you run the wrapper, a log file will be created in ACTIVEMQ_HOME/data/wrapper.log  + diff --git a/hugo/content/components/classic/documentation/javaiointerruptedioexception.md b/hugo/content/components/classic/documentation/javaiointerruptedioexception.md new file mode 100644 index 0000000000..d421680e91 --- /dev/null +++ b/hugo/content/components/classic/documentation/javaiointerruptedioexception.md @@ -0,0 +1,15 @@ +--- +title: java.io.InterruptedIOException +layout: classic-doc +--- + + + +The activemq client will throw an [java.io](http://java.io).InterruptedIOException if  the calling thread has been interrupted while the transport (ResponseCorrelator) is waiting for a response. + +Thread interruption while waiting for a response is treated as an IOException and reported to the transport listener. For an ActiveMQConnection, this will force an async close of the transport, closing the underlying socket. + +Because commands are not idempotent and with an interruption, it is not possible to know if the broker received the command, the only safe course of action is to close the connection. + +If the thread has been interrupted before a request is attempted, the interrupted state is cleared and reset after the request has completed. This allows shutdown operations to complete in the interrupted state. + diff --git a/hugo/content/components/classic/documentation/javaioioexception-failed-to-create-database-derbydb-see-the-next-exception-for-details.md b/hugo/content/components/classic/documentation/javaioioexception-failed-to-create-database-derbydb-see-the-next-exception-for-details.md new file mode 100644 index 0000000000..d4e1d60aae --- /dev/null +++ b/hugo/content/components/classic/documentation/javaioioexception-failed-to-create-database-derbydb-see-the-next-exception-for-details.md @@ -0,0 +1,61 @@ +--- +title: java.io.IOException Failed to create database 'derbydb', see the next exception for details +layout: classic-doc +--- + + + +If you get an error like this +``` +Jun 19, 2006 10:35:27 PM org.apache.activemq.broker.BrokerService getBroker +INFO: ActiveMQ Classic 4.0 JMS Message Broker (localhost) is starting +Jun 19, 2006 10:35:27 PM org.apache.activemq.broker.BrokerService getBroker +INFO: For help or more information please see: http://incubator.apache.org/activemq/ +java.io.IOException: Failed to create database 'derbydb', see the next exception for details. + at org.apache.activemq.util.IOExceptionSupport.create(IOExceptionSupport.java:42) + at org.apache.activemq.store.jdbc.TransactionContext.getConnection(TransactionContext.java:58) + at org.apache.activemq.store.jdbc.JDBCPersistenceAdapter.createAdapter(JDBCPersistenceAdapter.java:229) + at org.apache.activemq.store.jdbc.JDBCPersistenceAdapter.getAdapter(JDBCPersistenceAdapter.java:213) + at org.apache.activemq.store.jdbc.JDBCPersistenceAdapter.start(JDBCPersistenceAdapter.java:139) + at org.apache.activemq.store.journal.JournalPersistenceAdapter.start(JournalPersistenceAdapter.java:215) + at org.apache.activemq.broker.BrokerService.createRegionBroker(BrokerService.java:930) + at org.apache.activemq.broker.BrokerService.createBroker(BrokerService.java:888) + at org.apache.activemq.broker.BrokerService.getBroker(BrokerService.java:458) + at org.apache.activemq.broker.BrokerService.addConnector(BrokerService.java:143) + at org.apache.activemq.broker.BrokerService.addConnector(BrokerService.java:133) + at com.ic.ntn.message.HelloWorld$HelloWorldBroker.run(HelloWorld.java:92) + at java.lang.Thread.run(Thread.java:595) +Caused by: SQL Exception: Failed to create database 'derbydb', see the next exception for details. + at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source) + at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source) + at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source) + at org.apache.derby.impl.jdbc.EmbedConnection.newSQLException(Unknown Source) + at org.apache.derby.impl.jdbc.EmbedConnection.createDatabase(Unknown Source) + at org.apache.derby.impl.jdbc.EmbedConnection.(Unknown Source) + at org.apache.derby.impl.jdbc.EmbedConnection30.(Unknown Source) + at org.apache.derby.jdbc.Driver30.getNewEmbedConnection(Unknown Source) + at org.apache.derby.jdbc.InternalDriver.connect(Unknown Source) + at org.apache.derby.jdbc.EmbeddedDataSource.getConnection(Unknown Source) + at org.apache.derby.jdbc.EmbeddedDataSource.getConnection(Unknown Source) + at org.apache.activemq.store.jdbc.TransactionContext.getConnection(TransactionContext.java:54) + ... 11 more +``` +Then the error is probably that the JDBC driver (Apache Derby by default) could not write to the persistent file area. + +### Workaround + +Create a directory for the broker to write its files. e.g. in Java code call [setDataDirectory](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/broker/BrokerService.html#setDataDirectory(java.io.File)) +``` +File dir = new File("foo"); +dir.mkdir(); +broker.setDataDirectory(dir); +``` +or in XML use +``` +... +``` + +### See + +* [How do I embed a Broker inside a Connection](how-do-i-embed-a-broker-inside-a-connection) + diff --git a/hugo/content/components/classic/documentation/javalangnosuchmethoderror.md b/hugo/content/components/classic/documentation/javalangnosuchmethoderror.md new file mode 100644 index 0000000000..eef9f43d8d --- /dev/null +++ b/hugo/content/components/classic/documentation/javalangnosuchmethoderror.md @@ -0,0 +1,30 @@ +--- +title: java.lang.NoSuchMethodError +layout: classic-doc +--- + + + +If you get an error like +``` +java.lang.NoSuchMethodError: +javax.jms.Session.createConsumer(Ljavax/jms/Destination;)Ljavax/jms/MessageConsumer; +``` +or +``` +java.lang.AbstractMethodError: +javax.jms.ConnectionFactory.createConnection()Ljavax/jms/Connection; +``` + +### Fix + +You probably have old JMS 1.0.2b versions of the JMS API on your classpath. This is because various methods were added in JMS 1.1 to work with destinations in a polymorphic way (such as to create a consumer from a Destination like the above stack trace). + +Please add the JMS 1.1 jars to your container/classpath and try again. + +Add to the correct ClassPath + +If the JMS 1.0.2b classes come from your application server you may need to add the JMS 1.1 to your boot classpath to ensure that the JMS 1.1 classes take precedence to the container supplied classes + +Note that to a user of the JMS API, JMS 1.1 is completely backwards compatible. The only issue with upgrading to JMS 1.1 is that any JMS provider which implements only JMS 1.0.2b and does not implement JMS 1.1 will not work; however if you're using ActiveMQ Classic you should be fine. + diff --git a/hugo/content/components/classic/documentation/javalangnosuchmethodexception-orgactivemqraactivemqresourceadaptersetuseembeddedbroker.md b/hugo/content/components/classic/documentation/javalangnosuchmethodexception-orgactivemqraactivemqresourceadaptersetuseembeddedbroker.md new file mode 100644 index 0000000000..0aef00ac50 --- /dev/null +++ b/hugo/content/components/classic/documentation/javalangnosuchmethodexception-orgactivemqraactivemqresourceadaptersetuseembeddedbroker.md @@ -0,0 +1,25 @@ +--- +title: java.lang.NoSuchMethodException org.activemq.ra.ActiveMQResourceAdapter.setUseEmbeddedBroker +layout: classic-doc +--- + + + +If you get an error like this +``` +2005-08-14 17:18:45,618 ERROR [org.jboss.resource.deployment.RARDeployment] Starting failed jboss.jca:service=RARDeployment,name='activemq-ra-3.0.rar' org.jboss.deployment.DeploymentException: Error for resource adapter class org.activemq.ra.ActiveMQResourceAdapter accessing property setter ConfigPropertyMetaData@e62121[name=UseEmbeddedBroker type=java.lang.Boolean value=false descriptions=[DescriptionMetaData@1ad093c[language=en description=Boolean to configure if the connector should create an embedded broker.]]]; - nested throwable: (java.lang.NoSuchMethodException: org.activemq.ra.ActiveMQResourceAdapter.setUseEmbeddedBroker(java.lang.Boolean)) + at org.jboss.deployment.DeploymentException.rethrowAsDeploymentException(DeploymentException.java:39) + at org.jboss.resource.deployment.ResourceAdapterFactory.createResourceAdapter(ResourceAdapterFactory.java:90) + at org.jboss.resource.deployment.RARDeployment.startService(RARDeployment.java:101) + at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:272) + at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:222) + at org.jboss.system.ServiceDynamicMBeanSupport.invoke(ServiceDynamicMBeanSupport.java:110) + at org.jboss.mx.server.RawDynamicInvoker.invoke(RawDynamicInvoker.java:150) + at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644) + at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:897) +``` + +### Fix + +You are using 3.0 of ActiveMQ Classic. This bug is fixed in 3.1.x so use 3.1-M6 or later. + diff --git a/hugo/content/components/classic/documentation/javalangoutofmemory.md b/hugo/content/components/classic/documentation/javalangoutofmemory.md new file mode 100644 index 0000000000..ea6d20c38c --- /dev/null +++ b/hugo/content/components/classic/documentation/javalangoutofmemory.md @@ -0,0 +1,68 @@ +--- +title: java.lang.OutOfMemory +layout: classic-doc +--- + + + +Ok, this is manageable. It is possible to configure just about all of the memory utilisation of ActiveMQ Classic. The first thing to determine is what part of the system is running out of memory. Is it the JVM, the broker, the consumers or the producers? + +This entry refers to ActiveMQ Classic versions 5.1.x and greater. + +#### Memory + +##### JVM Memory + +Try running the broker in a standalone JVM using `bin/activemq`. Note the default JVM heap size option that is passed to the Java executable by the script (the exact options may depend upon the JVM that you are using, the examples are for the Sun JVM). + +* -Xmx: If your OS has more available memory, consider increasing the total heap memory available to the broker JVM. Note that the JVM will require more memory than the -Xmx value. Thread stacks and the JMVs internal classes will consume additional memory. +* -Xss: If you have [massive numbers of threads](javalangoutofmemory) in the Broker JVM, consider reducing the default JVM stack size of each thread with the -Xss option. + +If you are running an embedded broker or in a third party container, ensure that the hosting JVM has appropriate values for the maximum heap and stack sizes. + +##### Broker Memory + +The memory that the broker is allowed to use is not determined by the amount of memory allocated to the JVM. Although the broker is constrained by the amount of memory given to the JVM, the broker manages its memory independently. That is, the broker does not just simply use up all of the memory in the JVM and then die with an OutOfMemory exception. This is where you need to understand the [systemUsage](producer-flow-control) memory limit and the per destination memory limit. + +The memory in ActiveMQ Classic works in a tiered fashion that flows from the JVM -> Broker -> broker features. E.g., the total amount of destination memory limits placed cannot exceed the memory limit of the broker. + +#### Consumer + +Along with message size, the [prefetch limit](what-is-the-prefetch-limit-for) is main reason a consumer will [run out of memory](what-is-the-prefetch-limit-for). Reducing the prefetch value will reduce the amount of messages queued/stored in memory on the Consumer. + +#### Producer + +Unless message size exceeds resource limits, a producer should not run out of memory. A producer may notice the effect of memory limit enforcement by the broker in the form of [blocking](my-producer-blocks). + +#### Other + +##### Spooling Messages to Disk + +Fast dispatch of messages is only possible when messages are stored in memory. When consumers are slow or absent, memory can quickly become exhausted. +The Broker (using [Message Cursors](message-cursors)) will spool non-persistent messages to disk when the default memory usage threshold for a destination is reached. This threshold value is specified to the Broker via the section of the configuration in [activemq.xml](xml-configuration). This feature allows producers to continue sending messages when there are slow consumers without exhausting available memory or reverting to [producer flow control](producer-flow-control). In the case of multiple destinations, the combined default memory thresholds may be excessive and they may exceed available memory. In such a case it may make sense to reduce the memory usage 'limit' threshold at which messages are spooled to disk. An alternative option is to configure the 'precentUsage' rather than the absolute usage 'limit'. In this way, memory usage can be confined to a fixed percentage of available memory. + +More specific per destination memoryUsage limits can be specified in [activemq.xml](xml-configuration) using [Per Destination Policies](per-destination-policies). Some further examples of map entries can be found in the [Message Cursors](message-cursors) reference. + +##### Number of Threads + +By default, ActiveMQ Classic uses a dedicated thread per destination. If there are large numbers of Destinations there will be a large number of threads and their associated memory resource usage. ActiveMQ Classic can be configured to use a thread pool through the use of the system property: -Dorg.apache.activemq.UseDedicatedTaskRunner=false. This is currently specified in the activemq start script via ACTIVEMQ_OPTS. Using a thread pool can restrict the number of threads required by ActiveMQ Classic and hence reduce memory usage. + +##### Really Large Messages + +When your message are really large such that you can only allow a few messages in memory at at time, the [Per Destination Policies](per-destination-policies) maxPageSize and lazyDispatch can help. maxPageSize controls the amount of messages that are paged into memory for dispatch while lazyDispatch augments that value using the prefetch capacity of the current consumer list. With a prefetch of 1, a single consumer and lazyDispatch, only one message at a time would be loaded into memory at a time. + +##### Leaking JMS resources + +This is the most obvious one for Consumers or Producers; repeatedly obtaining a Session or MessageProducer or MessageConsumer and not closing it. With a java.lang.OutOfMemory, verifying (again) that all not in use JMS resources are released, is worth the time. If you have multiple threads in your application, consider using the [PooledConnectionFactory](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/pool/PooledConnectionFactory.html) as this will allow JMS resource to be safely shared among threads that follow the pattern: +``` +obtainJmsResource(); + +try +{ + useJmsResource() +} finally { + releaseJmsResource(); +} +``` +If you are using ActiveMQ Classic via [Spring Support](spring-Community/support) or with JMSTemplates, be sure to check you are not falling for any of the [JmsTemplate Gotchas](jmstemplate-gotchas). It may also be worth recapping on [How do I use JMS efficiently](how-do-i-use-jms-efficiently). + diff --git a/hugo/content/components/classic/documentation/javaxjmsjmsexception-wire-format-negociation-timeout-peer-did-not-send-his-wire-format.md b/hugo/content/components/classic/documentation/javaxjmsjmsexception-wire-format-negociation-timeout-peer-did-not-send-his-wire-format.md new file mode 100644 index 0000000000..9450f176d0 --- /dev/null +++ b/hugo/content/components/classic/documentation/javaxjmsjmsexception-wire-format-negociation-timeout-peer-did-not-send-his-wire-format.md @@ -0,0 +1,36 @@ +--- +title: javax.jms.JMSException - Wire format negociation timeout - peer did not send his wire format. +layout: classic-doc +--- + + + +If you get exception like this: +``` +javax.jms.JMSException: Wire format negociation timeout: peer did not send his wire format. + at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:58) + at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1185) + at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1263) + at org.apache.activemq.ActiveMQConnection.start(ActiveMQConnection.java:449) +``` +it can mean one of three things: + +1. You're connecting to the port not used by ActiveMQ Classic TCP transport +==================================================================== + +Make sure to check that you're connecting to the appropriate `host:port` + +2. You're using log4j JMS appender and doesn't filter out ActiveMQ Classic log messages +================================================================================ + +Be sure to read [How do I use log4j JMS appender with ActiveMQ Classic](how-do-i-use-log4j-jms-appender-with-activemq-classic) and more importantly to never send ActiveMQ Classic log messages to JMS appender + +3. Your broker is probably under heavy load (or network connection is unreliable), so connection setup cannot be completed in a reasonable time +================================================================================================================================================ + +If you experience sporadic exceptions like this, the best solution is to use [failover transport](failover-transport-reference), so that your clients can try connecting again if the first attempt fails. If you're getting these kind of exceptions more frequently you can also try extending wire format negotiation period (default 10 sec). You can do that by using `wireFormat.maxInactivityDurationInitalDelay` property on the connection URL in your client. For example +``` +tcp://localhost:61616?wireFormat.maxInactivityDurationInitalDelay=30000 +``` +will use 30 sec timeout. + diff --git a/hugo/content/components/classic/documentation/jaxb-20-api-is-being-loaded-from-the-bootstrap-classloader-but-this-ri-needs-21-api.md b/hugo/content/components/classic/documentation/jaxb-20-api-is-being-loaded-from-the-bootstrap-classloader-but-this-ri-needs-21-api.md new file mode 100644 index 0000000000..f360a218fa --- /dev/null +++ b/hugo/content/components/classic/documentation/jaxb-20-api-is-being-loaded-from-the-bootstrap-classloader-but-this-ri-needs-21-api.md @@ -0,0 +1,12 @@ +--- +title: JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI () needs 2.1 API. +layout: classic-doc +--- + + + +When using JDK 6 (up to JDK 6 Update 3) to run ActiveMQ Classic you can run into this exception. There are two solutions to this: + +* Upgrade to JDK to 1.6.0_04 or above, which includes JAXB 2.1 +* Copy JAXB 2.1 to /lib/endorsed to override the API jars that ship with the JDK + diff --git a/hugo/content/components/classic/documentation/jboss-integration.md b/hugo/content/components/classic/documentation/jboss-integration.md new file mode 100644 index 0000000000..911e0b03d5 --- /dev/null +++ b/hugo/content/components/classic/documentation/jboss-integration.md @@ -0,0 +1,726 @@ +--- +title: Integrating Apache ActiveMQ Classic with JBoss +layout: classic-doc +--- + + + +Integrating Apache ActiveMQ Classic with JBoss +====================================== + +Integration with application servers is a common scenario in the enterprise Java world, especially when it comes to messaging. ActiveMQ Classic is a JMS 1.1 compliant, open source, Apache Licensed, message oriented middleware (MOM) with [many](changes-in-40), [many](new-features-in-41) features far beyond the JMS specification. ActiveMQ Classic offers many different [points of connectivity](connectivity), many [cross language clients](cross-language-clients) and many [pluggable transport protocols](protocols) including integration with any J2EE 1.4 application server. + +One of the application servers in the open source world is JBoss. A very common requirement is to configure ActiveMQ Classic as the messaging infrastructure within JBoss. Although there is [a bit of documentation](jboss-integration) on this integration, this article seeks to provide much more detail and explanation. So if you have a need to integrate ActiveMQ Classic with JBoss, this article is for you. + +This article explains how to configure JBoss to start up ActiveMQ Classic as part of its lifecycle and how to configure the ActiveMQ Classic resource adapter to handle the messaging and transactionality between ActiveMQ Classic and JBoss. + +Requirements +------------ + +Below are the software requirements for this article with links to download each: + +* [Apache ActiveMQ Classic 4.0.1+](download) +* [JBoss 4.0.4+](http://sourceforge.net/project/showfiles.php?group_id=22866&package_id=16942&release_id=416591) +* [Sun Java 1.5+](http://www.java.com/en/download/index.jsp) +* [Apache Ant 1.6+](http://ant.apache.org/bindownload.cgi) + +Though this article is using Unix, the installation and integration will work on any platform running Sun Java. It is recommended that each piece of software be downloaded before working through the steps is this article. Once each piece of software has been downloaded, proceed to the first step. + +Install the J2SE 1.5 +-------------------- + +The first step in this process is to install Java 1.5 and verify that it runs correctly. Using the link above, find, download and install the correct version of Java for your platform. Once Java is installed and in the PATH, test it to see that it runs correctly using the following command: +``` +$ java -version +java version "1.5.0_06" +Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-112) +Java HotSpot(TM) Client VM (build 1.5.0_06-64, mixed mode, sharing) +``` +Depending upon your platform and the exact build number of Java 1.5, your output may vary slightly. As long as it's Java 1.5 and the version information is output, you should be ready to proceed to the next step. + +Install Apache Ant +------------------ + +The second step is to install Apache Ant. Simply download it using the link above, expand somewhere on your hard drive and place the `bin` directory in the PATH. This will allow you to test it quickly using the commands below: +``` +$ ant -version +Apache Ant version 1.6.2 compiled on July 16 2004 +``` +As long as you see the version output above, Ant should be usable. If you did not see the version output or received an error, consult the Ant documentation or mailing list archives to work out the issue. Please note that Ant is not used until the end of this whole exercise to test the integration. + +Install the JBoss Application Server +------------------------------------ + +The third step in this process is to install JBoss and make sure it runs correctly before installing and configuring ActiveMQ Classic. Upon downloading JBoss-4.0.4, expand it in a place where it can create a directory. Next, run the server using the following commands: +``` +$ cd jboss-4.0.4.GA +$ ./bin/run.sh -c default +========================================================================= + + JBoss Bootstrap Environment + + JBOSS_HOME: /opt/jboss-4.0.4.GA + + JAVA: java + + JAVA_OPTS: -server -Xms128m -Xmx512m -Dsun.rmi.dgc.client.gcInterval=3600000 +-Dsun.rmi.dgc.server.gcInterval=3600000 -Dprogram.name=run.sh + + CLASSPATH: /opt/jboss-4.0.4.GA/bin/run.jar:/lib/tools.jar + +========================================================================= + +15:34:47,999 INFO [Server] Starting JBoss (MX MicroKernel)... +15:34:48,001 INFO [Server] Release ID: JBoss [Zion] 4.0.4.GA (build: CVSTag=JBoss\_4\_0\_4\_GA date=200605151000) +15:34:48,004 INFO [Server] Home Dir: /opt/jboss-4.0.4.GA +15:34:48,005 INFO [Server] Home URL: file:/opt/jboss-4.0.4.GA/ +15:34:48,007 INFO [Server] Patch URL: null +15:34:48,007 INFO [Server] Server Name: default +15:34:48,007 INFO [Server] Server Home Dir: /opt/jboss-4.0.4.GA/server/default +15:34:48,011 INFO [Server] Server Home URL: file:/opt/jboss-4.0.4.GA/server/default/ +15:34:48,012 INFO [Server] Server Log Dir: /opt/jboss-4.0.4.GA/server/default/log +15:34:48,017 INFO [Server] Server Temp Dir: /opt/jboss-4.0.4.GA/server/default/tmp +15:34:48,022 INFO [Server] Root Deployment Filename: jboss-service.xml +... +15:35:17,360 INFO [Server] JBoss (MX MicroKernel) [4.0.4.GA (build: CVSTag=JBoss\_4\_0\_4\_GA date=200605151000)] +Started in 22s:238ms +``` +The first few lines of output from the JBoss startup indicates the configuration being used but the last line is the most important one. It tells you that JBoss has been started successfully on your system. For an extra measure of assurance, visit [http://localhost:8080/web-console/](http://localhost:8080/web-console/) in a web browser to make sure you are able to see the JBoss web console. If you can see this console, everything should be ready to go. + +As a side note, the left-hand side of the web-console requires that the [Java plugin](http://java.sun.com/products/plugin/) be properly installed. This is supposed to take place when installing the J2SE, so if it did not work correctly for you, I suggest that you consult some documentation about any errors you may be seeing. The Java plugin is not required for JBoss or ActiveMQ Classic to function properly, it is simply for the JBoss web-console. + +Once JBoss is installed properly, shut it down using either the shutdown script or by simply typing ctrl-c to activate the shutdown hook. Once it is shut down, proceed to the next step. + +Prepare for Integrating Apache ActiveMQ Classic with the JBoss Application Server +------------------------------------------------------------------------- + +The fourth step is to prepare your environment for integrating ActiveMQ Classic with JBoss. If you haven't done so already, download Apache ActiveMQ Classic using the link above. As of the writing of this article, the latest released version is 4.0.2-RC4. Upon downloading this archive, expand it in a place where it can create a directory, preferably in the same location where JBoss was expanded. Verify that the ActiveMQ Classic RAR file is included using the following commands: +``` +$ cd ./incubator-activemq-4.0.2.tar.gz +$ jar tvf /opt/incubator-activemq-4.0.2/lib/optional/activemq-ra-4.0.2.rar + 0 Mon Sep 25 19:00:50 MDT 2006 META-INF/ + 399 Mon Sep 25 19:00:48 MDT 2006 META-INF/MANIFEST.MF + 523 Mon Sep 25 13:07:40 MDT 2006 META-INF/DISCLAIMER.txt + 11359 Mon Sep 25 13:07:40 MDT 2006 META-INF/LICENSE.txt + 20305 Mon Sep 25 13:07:40 MDT 2006 META-INF/ra.xml + 2334 Mon Sep 25 13:07:40 MDT 2006 broker-config.xml + 70023 Mon Sep 25 19:00:48 MDT 2006 activemq-ra-4.0.2.jar +1351744 Mon Sep 25 19:00:14 MDT 2006 activemq-core-4.0.2.jar +232107 Mon Sep 25 18:22:48 MDT 2006 activeio-core-3.0-beta4.jar +2143211 Tue Aug 01 11:44:50 MDT 2006 derby-10.1.1.0.jar +1901653 Tue Aug 01 11:47:08 MDT 2006 spring-1.2.6.jar + 94713 Tue Aug 01 11:47:22 MDT 2006 xbean-spring-2.2.jar + 52915 Tue Aug 01 12:22:16 MDT 2006 commons-logging-1.1.jar + 16030 Tue Aug 01 12:22:32 MDT 2006 geronimo-j2ee-management\_1.0\_spec-1.0.jar +329586 Tue Aug 01 12:22:54 MDT 2006 backport-util-concurrent-2.1.jar +358085 Tue Aug 01 12:23:26 MDT 2006 log4j-1.2.12.jar + 523 Mon Sep 25 19:00:50 MDT 2006 META-INF/DISCLAIMER.txt + 11359 Mon Sep 25 19:00:50 MDT 2006 META-INF/LICENSE.txt +``` +This is simply a table of contents of the RAR file. There should only be one reason that this will fail - an incomplete download of the ActiveMQ Classic tarball or zip file. Beyond that, depending on the version you download, some of the library versions may be slightly different. + +Now go back to the JBoss installation and create a directory for ActiveMQ Classic in the JBoss deploy directory for the default JBoss context. Below are the commands to achieve this task: +``` +$ mkdir /opt/jboss-4.0.4.GA/server/default/deploy/activemq-ra.rar +$ cd /opt/jboss-4.0.4.GA/server/default/deploy/activemq-ra.rar +$ pwd +/opt/jboss-4.0.4.GA/server/default/deploy/activemq-ra.rar +``` +`_NOTE:_** The creation of a directory is not required but is the easiest way to set up the ActiveMQ Classic RAR when you're just getting started. This is due to the flexibility it affords during the development phase for the configuration to be changed very easily. The alternative is to JAR up the directory as a RAR file once the configuration is solid enough that it no longer needs to be changed. But leaving everything in a directory during development is the easiest path. + +Now expand the activemq-ra-4.0.2.rar into the current working directory: +``` +jar xvf /opt/incubator-activemq-4.0.2/lib/optional/activemq-ra-4.0.2.rar + created: META-INF/ + inflated: META-INF/MANIFEST.MF + inflated: META-INF/DISCLAIMER.txt + inflated: META-INF/LICENSE.txt + inflated: META-INF/ra.xml + inflated: broker-config.xml + inflated: activemq-ra-4.0.2.jar + inflated: activemq-core-4.0.2.jar + inflated: activeio-core-3.0-beta4.jar + inflated: derby-10.1.1.0.jar + inflated: spring-1.2.6.jar + inflated: xbean-spring-2.2.jar + inflated: commons-logging-1.1.jar + inflated: geronimo-j2ee-management\_1.0\_spec-1.0.jar + inflated: backport-util-concurrent-2.1.jar + inflated: log4j-1.2.12.jar + inflated: META-INF/DISCLAIMER.txt + inflated: META-INF/LICENSE.txt +``` +Below is a quick listing of the contents of that directory: +``` +$ ls -l +total 12848 +drwxr-xr-x 6 bsnyder bsnyder 204 Oct 16 16:27 META-INF +-rw-r--r-- 1 bsnyder bsnyder 232107 Oct 16 16:27 activeio-core-3.0-beta4.jar +-rw-r--r-- 1 bsnyder bsnyder 1351744 Oct 16 16:27 activemq-core-4.0.2.jar +-rw-r--r-- 1 bsnyder bsnyder 70023 Oct 16 16:27 activemq-ra-4.0.2.jar +-rw-r--r-- 1 bsnyder bsnyder 329586 Oct 16 16:27 backport-util-concurrent-2.1.jar +-rw-r--r-- 1 bsnyder bsnyder 2334 Oct 16 16:27 broker-config.xml +-rw-r--r-- 1 bsnyder bsnyder 52915 Oct 16 16:27 commons-logging-1.1.jar +-rw-r--r-- 1 bsnyder bsnyder 2143211 Oct 16 16:27 derby-10.1.1.0.jar +-rw-r--r-- 1 bsnyder bsnyder 16030 Oct 16 16:27 geronimo-j2ee-management\_1.0\_spec-1.0.jar +-rw-r--r-- 1 bsnyder bsnyder 358085 Oct 16 16:27 log4j-1.2.12.jar +-rw-r--r-- 1 bsnyder bsnyder 1901653 Oct 16 16:27 spring-1.2.6.jar +-rw-r--r-- 1 bsnyder bsnyder 94713 Oct 16 16:27 xbean-spring-2.2.jar +``` +Now it's time to configure ActiveMQ Classic. + +Configuring Apache ActiveMQ Classic +--------------------------- + +The fifth step is to actually configure ActiveMQ Classic for integration with JBoss. Remember that you should be sitting in the following directory: +``` +/opt/jboss-4.0.4.GA/server/default/deploy/activemq-ra.rar +``` +You may or may not have installed JBoss in `/opt`, that doesn't particularly matter. What does matter is that you're sitting in the directory that was created above to hold the contents of the expanded ActiveMQ Classic RAR file. + +`_NOTE:_** A RAR file is a Resource adapter ARchive (RAR). Resource adapters are a concept from the [J2EE Connector Architecture (JCA)](http://java.sun.com/j2ee/connector/) and are used to interface with Enterprise Information Systems (EIS), i.e., systems external to the application server (e.g., relational databases, mainframes, MOMs, accounting systems, etc.). Resource adapters are often referred to as J2EE connectors and are very similar to the concept of a device driver for, say, a printer in that they contain information specific to connecting to a particular system. The difference with JCA is that that connection has been formalized in specification for Java. So the overall concepts of JCA is for connection to any EIS, but what does that mean? JCA 1.5 provides connectivity and more via the following contracts: + +Version 1.0 Contracts + +In version 1.0 of the Connector Architecture, three contracts are defined to address the functions mentioned above: + +* Connection Management Contract: Lets applications connect to an EIS through the resource adapter. It also allows the application server to pool connection requests to the EIS. +* Transaction Management Contract: Allows an application to manage and perform transactional access across one-to-many EIS resource managers. +* Security Contract: Provides support for secure access to the EIS. + +New Contracts in Version 1.5 + +In version 1.5 of the J2EE Connector Architecture, there are more contracts that a resource adapter must support, as new functionality and features made their way into the specification. A resource adapter can support these four new contracts by implementing the required interfaces defined in the specification for each contract. + +* Lifecycle Management Contract: Lets the application server manage the lifecycle – that is, the startup and shutdown functionality – of the resource adapter. +* Work Management Contract: Allows the resource adapter to do work by submitting it to an application server for execution. Since the application server does the work for the resource adapter, the resource adapter needn't worry about thread management. Instead, the application server manages this aspect efficiently and can use thread pooling if necessary. Although the work management contract is not required (the resource adapter can choose to manage its own thread for work), it is definitely recommended. +* Transaction Inflow Contract: Allows a resource adapter to propagate an imported transaction to an application server, as well as flow-in transaction completion and crash recovery initiated by an EIS. +* Message Inflow Contract: Allows the resource adapter to synchronously or asynchronously deliver messages to endpoints in the application server, irrespective of message style, semantics, and infrastructure. + +Quoted from [What's New in the J2EE Connector Architecture 1.5](http://java.sun.com/developer/technicalArticles/J2EE/connectorarch1_5/) + +For more information about JCA, please consult the [J2EE Connector Architecture documentation](http://java.sun.com/j2ee/connector/index.jsp). + +Open the `META-INF/ra.xml` file and look for the following section: + +`META-INF/ra.xml** +```xml + + + The URL to the ActiveMQ Classic server that you want this connection to connect to. If using + an embedded broker, this value should be 'vm://localhost'. + + ServerUrl + java.lang.String + tcp://localhost:61616 + + +``` +The section above is used to tell the ActiveMQ Classic RAR where ActiveMQ Classic is located. By default, the in-VM protocol is commented out in favor of the tcp protocol. This will find ActiveMQ Classic running on any interface on the localhost on port 61616. It's ok to just leave this alone if you don't mind the inefficiency of communicating within the JVM via TCP. However, it is recommended that `vm://` transport be used for an embedded broker, so comment out the `tcp://` transport and uncomment the `vm://` transport. Below is an example of this: + +`META-INF/ra.xml** +```xml + + + The URL to the ActiveMQ Classic server that you want this connection to connect to. If using + an embedded broker, this value should be 'vm://localhost'. + + ServerUrl + java.lang.String + + vm://localhost + +``` +Because we're embedding ActiveMQ Classic inside of JBoss, it is more efficient to use the `vm://` transport, rather than to perform messaging over the `tcp://` transport. + +Now look further down the `META-INF/ra.xml` file and locate the following section: + +`META-INF/ra.xml** +```xml + + + Sets the XML configuration file used to configure the embedded ActiveMQ Classic broker via + Spring if using embedded mode. + + BrokerXmlConfig is the filename which is assumed to be on the classpath unless + a URL is specified. So a value of foo/bar.xml would be assumed to be on the + classpath whereas file:dir/file.xml would use the file system. + Any valid URL string is supported. + + BrokerXmlConfig + java.lang.String + + + +``` +The section above needs to be changed to uncomment the second to last line and remove/replace the empty element that is above it. Below is an example of how this should be changed: + +`META-INF/ra.xml** +```xml + + + Sets the XML configuration file used to configure the embedded ActiveMQ Classic broker via + Spring if using embedded mode. + + BrokerXmlConfig is the filename which is assumed to be on the classpath unless + a URL is specified. So a value of foo/bar.xml would be assumed to be on the + classpath whereas file:dir/file.xml would use the file system. + Any valid URL string is supported. + + BrokerXmlConfig + java.lang.String + xbean:broker-config.xml + +``` +This change tells the ActiveMQ Classic RAR to read a configuration file named `broker-config.xml` (the `xbean:` that proceeds the filename is simply a hint to class doing the reading of the configuration file) which is located on the CLASSPATH. In this case, the `broker-config.xml` file is located in the `activemq-ra.rar` directory. Save the changes to that file and then open the `broker-config.xml` file. + +The `broker-config.xml` file _is_ the ActiveMQ Classic configuration file. This is the file used to configure ActiveMQ Classic. The default contents of this file are usable, but should be customized to suit your environment. There are several items of note about this configuration. The most prominent sections to note in this file are the `` element and the `` and `` elements as seen below: + +`broker-config.xml** +```xml + + + + ... + + + + + + + + + + + + + + + + + + + + +``` +The first change to this file is to add the brokerName attribute to the broker element and provide a name: +```xml + +``` +In addition, this same name is used further down the configuration to provide a name for the `` element: +```xml + +``` +Now we'll tell ActiveMQ Classic not to initialize JMX because we'll use the existing one that JBoss has: +```xml + + + + +``` +The `` element should be reconfigured to store its data in an appropriate place. On JBoss, that's most likely within the "data" directory of the server configuration you're using. We're going to set this dynamically using an XBean and Spring feature that allows us to inject system properties values into the configuration. First this needs to be enabled: +```xml + + +``` +Now, modify the `dataDirectory` attribute of the `journaledJDBC` element to be the following: `${jboss.server.data.dir}/activemq`. + +The `` element is used to advertise the ActiveMQ Classic broker for client-to-broker communications and the `` element advertises the ActiveMQ Classic broker for broker-to-broker communications. The default configuration is to use the ActiveMQ Classic [multicast transport](multicast-transport-reference) for both. This is simply an easy configuration under which to get ActiveMQ Classic up and running, so we'll just leave it at that for the time being. + +`_NOTE:_** There are far more configuration options available for ActiveMQ Classic than are noted here. The configuration above is only enough to just get ActiveMQ Classic up and running, nothing more. For more information on the ActiveMQ Classic configuration, see the [ActiveMQ Classic 4.1 XML Reference](xbean-xml-reference-41). + +Now we just need to start up JBoss to assure that it comes up correctly without error using the same commands we used previously to start JBoss: +``` +$ cd jboss-4.0.4.GA +$ ./bin/run.sh -c default +========================================================================= + + JBoss Bootstrap Environment + + JBOSS_HOME: /opt/jboss-4.0.4.GA + + JAVA: java + + JAVA_OPTS: -server -Xms128m -Xmx512m -Dsun.rmi.dgc.client.gcInterval=3600000 +-Dsun.rmi.dgc.server.gcInterval=3600000 -Dprogram.name=run.sh + + CLASSPATH: /opt/jboss-4.0.4.GA/bin/run.jar:/lib/tools.jar + +========================================================================= + +15:34:47,999 INFO [Server] Starting JBoss (MX MicroKernel)... +15:34:48,001 INFO [Server] Release ID: JBoss [Zion] 4.0.4.GA (build: CVSTag=JBoss\_4\_0\_4\_GA date=200605151000) +15:34:48,004 INFO [Server] Home Dir: /opt/jboss-4.0.4.GA +15:34:48,005 INFO [Server] Home URL: file:/opt/jboss-4.0.4.GA/ +15:34:48,007 INFO [Server] Patch URL: null +15:34:48,007 INFO [Server] Server Name: default +15:34:48,007 INFO [Server] Server Home Dir: /opt/jboss-4.0.4.GA/server/default +15:34:48,011 INFO [Server] Server Home URL: file:/opt/jboss-4.0.4.GA/server/default/ +15:34:48,012 INFO [Server] Server Log Dir: /opt/jboss-4.0.4.GA/server/default/log +15:34:48,017 INFO [Server] Server Temp Dir: /opt/jboss-4.0.4.GA/server/default/tmp +15:34:48,022 INFO [Server] Root Deployment Filename: jboss-service.xml +... +15:35:17,360 INFO [Server] JBoss (MX MicroKernel) [4.0.4.GA (build: CVSTag=JBoss\_4\_0\_4\_GA date=200605151000)] +Started in 28s:576ms +``` +As long as JBoss comes up without error, you're ready to move on to the next step. + +Configuring JBoss +----------------- + +The sixth step is to configure JBoss to initialize and start ActiveMQ Classic whenever JBoss starts up. This is accomplished using an XML file that abides by the [JBoss JCA DTD](http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd) for data sources. Like most other Java application servers on the market, the JBoss architecture uses the J2EE Connector Architecture to manage connections of any kind including JDBC, JMS, etc. and the JBoss JCA DTD denotes the allowed contents for creating an XML data source instance to configure JBoss JCA. Below is an example XML data source instance for use with JBoss: + +`activemq-jms-ds.xml** +```xml + + + + + + + + activemq/QueueConnectionFactory + + + activemq-ra.rar + javax.jms.QueueConnectionFactory + vm://localhost + + 1 + 200 + 30000 + 3 + + + + activemq/TopicConnectionFactory + + + activemq-ra.rar + javax.jms.TopicConnectionFactory + vm://localhost + + 1 + 200 + 30000 + 3 + + + + activemq/queue/outbound + jboss.jca:service=RARDeployment,name='activemq-ra.rar' + javax.jms.Queue + PhysicalName=queue.outbound + + + + activemq/topic/inbound + jboss.jca:service=RARDeployment,name='activemq-ra.rar' + javax.jms.Topic + PhysicalName=topic.inbound + + + +``` + +This XML instance configures a JMS `QueueConnectionFactory` and a JMS `TopicConnectionFactory` and makes them available via JNDI. Also defined in this file are some {{AdminObject}}s which are used to specify a topic and a queue. This file should be dropped into the JBoss deploy directory. Its name (*-ds.xml) will cause it to be picked up by the JBoss deployer upon startup. Speaking of which, once this file is in place, a quick smoke test can be performed by simply starting up the JBoss server. Below is an example of the output that should be seen: + +``` +========================================================================= + + JBoss Bootstrap Environment + + JBOSS_HOME: /opt/jboss + + JAVA: java + + JAVA_OPTS: -server -Xms128m -Xmx512m -Dsun.rmi.dgc.client.gcInterval=3600000 +-Dsun.rmi.dgc.server.gcInterval=3600000 -Dprogram.name=run.sh + + CLASSPATH: /opt/jboss/bin/run.jar:/lib/tools.jar + +========================================================================= + +22:55:48,686 INFO [Server] Starting JBoss (MX MicroKernel)... +22:55:48,688 INFO [Server] Release ID: JBoss [Zion] 4.0.4.GA (build: CVSTag=JBoss\_4\_0\_4\_GA date=200605151000) +22:55:48,690 INFO [Server] Home Dir: /opt/jboss-4.0.4.GA +22:55:48,692 INFO [Server] Home URL: file:/opt/jboss-4.0.4.GA/ +22:55:48,695 INFO [Server] Patch URL: null +22:55:48,697 INFO [Server] Server Name: default +22:55:48,698 INFO [Server] Server Home Dir: /opt/jboss-4.0.4.GA/server/default +22:55:48,701 INFO [Server] Server Home URL: file:/opt/jboss-4.0.4.GA/server/default/ +22:55:48,702 INFO [Server] Server Log Dir: /opt/jboss-4.0.4.GA/server/default/log +22:55:48,704 INFO [Server] Server Temp Dir: /opt/jboss-4.0.4.GA/server/default/tmp +22:55:48,706 INFO [Server] Root Deployment Filename: jboss-service.xml +22:55:49,092 INFO [ServerInfo] Java version: 1.5.0_06,Apple Computer, Inc. +22:55:49,101 INFO [ServerInfo] Java VM: Java HotSpot(TM) Server VM 1.5.0_06-64,"Apple Computer, Inc." +22:55:49,102 INFO [ServerInfo] OS-System: Mac OS X 10.4.8,i386 +22:55:49,803 INFO [Server] Core system initialized +22:55:53,379 INFO [WebService] Using RMI server codebase: http://rattlesnake:8083/ +22:55:53,400 INFO [Log4jService$URLWatchTimerTask] Configuring from URL: resource:log4j.xml +22:55:54,034 INFO [NamingService] JNDI bootstrap JNP=/0.0.0.0:1099, RMI=/0.0.0.0:1098, backlog=50, +no client SocketFactory, Server SocketFactory=class +org.jboss.net.sockets.DefaultSocketFactory +22:55:58,475 INFO [Embedded] Catalina naming disabled +22:55:58,566 INFO [ClusterRuleSetFactory] Unable to find a cluster rule set in the classpath. +Will load the default rule set. +22:55:58,569 INFO [ClusterRuleSetFactory] Unable to find a cluster rule set in the classpath. +Will load the default rule set. +22:55:59,110 INFO [Http11BaseProtocol] Initializing Coyote HTTP/1.1 on http-0.0.0.0-8080 +22:55:59,114 INFO [Catalina] Initialization processed in 545 ms +22:55:59,116 INFO [StandardService] Starting service jboss.web +22:55:59,121 INFO [StandardEngine] Starting Servlet Engine: Apache Tomcat/5.5.17 +22:55:59,179 INFO [StandardHost] XML validation disabled +22:55:59,221 INFO [Catalina] Server startup in 105 ms +22:55:59,600 INFO [TomcatDeployer] deploy, ctxPath=/invoker, warUrl=.../deploy/http-invoker.sar/invoker.war/ +22:55:59,874 INFO [WebappLoader] Dual registration of jndi stream handler: factory already defined +22:56:00,899 INFO [TomcatDeployer] deploy, ctxPath=/, warUrl=.../deploy/jbossweb-tomcat55.sar/ROOT.war/ +22:56:01,700 INFO [TomcatDeployer] deploy, ctxPath=/jbossws, warUrl=.../tmp/deploy/tmp60528jbossws-exp.war/ +22:56:01,891 INFO [SubscriptionManager] Bound event dispatcher to java:/EventDispatcher +22:56:02,203 INFO [TomcatDeployer] deploy, ctxPath=/jbossmq-httpil, +warUrl=.../deploy/jms/jbossmq-httpil.sar/jbossmq-httpil.war/ +22:56:04,546 INFO [TomcatDeployer] deploy, ctxPath=/web-console, +warUrl=.../deploy/management/console-mgr.sar/web-console.war/ +22:56:05,690 INFO [MailService] Mail Service bound to java:/Mail +22:56:07,215 INFO [RARDeployment] Required license terms exist, view META-INF/ra.xml in +.../deploy/activemq-ra.rar/ +22:56:07,452 INFO [XBeanXmlBeanDefinitionReader] Loading XML bean definitions from class +path resource [broker-config.xml] +22:56:07,750 INFO [ClassPathXmlApplicationContext] Bean factory for application context +[org.apache.xbean.spring.context.ClassPathXmlApplicationContext;hashCode=13887543]: +org.springframework.beans.factory.support.DefaultListableBeanFactory defining +beans [org.apache.activemq.xbean.XBeanBrokerService]; root of BeanFactory hierarchy +22:56:07,765 INFO [ClassPathXmlApplicationContext] 1 beans defined in application context +[org.apache.xbean.spring.context.ClassPathXmlApplicationContext;hashCode=13887543] +22:56:07,773 INFO [CollectionFactory] JDK 1.4+ collections available +22:56:07,778 INFO [ClassPathXmlApplicationContext] Unable to locate MessageSource with name +'messageSource': using default +[org.springframework.context.support.DelegatingMessageSource@5fee96] +22:56:07,781 INFO [ClassPathXmlApplicationContext] Unable to locate ApplicationEventMulticaster +with name 'applicationEventMulticaster': using default +[org.springframework.context.event.SimpleApplicationEventMulticaster@78c714] +22:56:07,783 INFO [DefaultListableBeanFactory] Pre-instantiating singletons in factory + [org.springframework.beans.factory.support.DefaultListableBeanFactory +defining beans [org.apache.activemq.xbean.XBeanBrokerService]; root of BeanFactory hierarchy] +22:56:08,181 INFO [BrokerService] ActiveMQ 4.0.2 JMS Message Broker (bruce.broker1) is starting +22:56:08,181 INFO [BrokerService] For help or more information please see: +http://incubator.apache.org/activemq/ +22:56:09,989 INFO [JDBCPersistenceAdapter] Database driver recognized: +[apache\_derby\_embedded\_jdbc\_driver] +22:56:11,026 INFO [JournalPersistenceAdapter] Journal Recovery Started from: Active Journal: +using 5 x 20.0 Megs at: /opt/jboss-4.0.4.GA/activemq-data/journal +22:56:11,169 INFO [JournalPersistenceAdapter] Journal Recovered: 0 message(s) in transactions recovered. +22:56:11,489 INFO [TransportServerThreadSupport] Listening for connections at: tcp://rattlesnake:61616 +22:56:11,491 WARN [MulticastDiscoveryAgent] brokerName not set +22:56:11,519 INFO [TransportConnector] Connector bruce.broker1 Started +22:56:11,522 INFO [NetworkConnector] Network Connector bridge Started +22:56:11,522 INFO [BrokerService] ActiveMQ JMS Message Broker +(bruce.broker1, ID:rattlesnake-59052-1161060967859-1:0) started +22:56:11,556 INFO [RARDeployment] Required license terms exist, view META-INF/ra.xml in +.../deploy/jboss-ha-local-jdbc.rar +22:56:11,599 INFO [RARDeployment] Required license terms exist, view META-INF/ra.xml in +.../deploy/jboss-ha-xa-jdbc.rar +22:56:11,623 INFO [RARDeployment] Required license terms exist, view META-INF/ra.xml in +.../deploy/jboss-local-jdbc.rar +22:56:11,647 INFO [RARDeployment] Required license terms exist, view META-INF/ra.xml in +.../deploy/jboss-xa-jdbc.rar +22:56:11,737 INFO [RARDeployment] Required license terms exist, view META-INF/ra.xml in +.../deploy/jms/jms-ra.rar +22:56:11,847 INFO [RARDeployment] Required license terms exist, view META-INF/ra.xml in +.../deploy/mail-ra.rar +22:56:12,251 INFO [ConnectionFactoryBindingService] Bound ConnectionManager +'jboss.jca:service=ConnectionFactoryBinding,name=activemq/QueueConnectionFactory' to +JNDI name 'java:activemq/QueueConnectionFactory' +22:56:12,258 INFO [ConnectionFactoryBindingService] Bound ConnectionManager +'jboss.jca:service=ConnectionFactoryBinding,name=activemq/TopicConnectionFactory' to +JNDI name 'java:activemq/TopicConnectionFactory' +22:56:12,265 INFO [AdminObject] Bound admin object 'org.apache.activemq.command.ActiveMQQueue' +at 'activemq/queue/outbound' +22:56:12,330 INFO [AdminObject] Bound admin object 'org.apache.activemq.command.ActiveMQTopic' +at 'activemq/topic/inbound' +22:56:13,246 INFO [ConnectionFactoryBindingService] Bound ConnectionManager +'jboss.jca:service=DataSourceBinding,name=DefaultDS' to JNDI name 'java:DefaultDS' +22:56:13,842 INFO [A] Bound to JNDI name: queue/A +22:56:13,845 INFO [B] Bound to JNDI name: queue/B +22:56:13,846 INFO [C] Bound to JNDI name: queue/C +22:56:13,848 INFO [D] Bound to JNDI name: queue/D +22:56:13,850 INFO [ex] Bound to JNDI name: queue/ex +22:56:13,876 INFO [testTopic] Bound to JNDI name: topic/testTopic +22:56:13,879 INFO [securedTopic] Bound to JNDI name: topic/securedTopic +22:56:13,880 INFO [testDurableTopic] Bound to JNDI name: topic/testDurableTopic +22:56:13,883 INFO [testQueue] Bound to JNDI name: queue/testQueue +22:56:13,994 INFO [UILServerILService] JBossMQ UIL service available at : /0.0.0.0:8093 +22:56:14,055 INFO [DLQ] Bound to JNDI name: queue/DLQ +22:56:14,375 INFO [ConnectionFactoryBindingService] Bound ConnectionManager +'jboss.jca:service=ConnectionFactoryBinding,name=JmsXA' to JNDI name 'java:JmsXA' +22:56:14,525 INFO [TomcatDeployer] deploy, ctxPath=/jmx-console, warUrl=.../deploy/jmx-console.war/ +22:56:14,991 INFO [Http11BaseProtocol] Starting Coyote HTTP/1.1 on http-0.0.0.0-8080 +22:56:15,071 INFO [ChannelSocket] JK: ajp13 listening on /0.0.0.0:8009 +22:56:15,082 INFO [JkMain] Jk running ID=0 time=0/25 config=null +22:56:15,108 INFO [Server] JBoss (MX MicroKernel) [4.0.4.GA (build: CVSTag=JBoss\_4\_0\_4\_GA date=200605151000)] +Started in 26s:398ms +``` + +Note the startup messages from both ActiveMQ Classic and from the `AdminObjects` creating an `ActiveMQQueue` and an `ActiveMQTopic`. These are good indications that the configuration is correct, but needs to be verified a bit further. This is covered in the next section. + +Testing the Integration +----------------------- + +The seventh and final step is to perform a slightly more comprehensive smoke test of the integration. This can be accomplished using Apache Ant via the examples that come with the ActiveMQ Classic binary distribution. An Ant build.xml file is included which provides easy access to a simple consumer and a simple producer. The producer will be used to send messages that are received by the consumer. To proceed with this testing, just follow the steps below: + +1. In the first terminal, start up JBoss. The same startup script can be used here as was used above. +2. In the second terminal, use the commands below to run the ActiveMQ Classic consumer: + ``` + $ cd /opt/incubator-activemq-4.0.2/examples #note in activemq v5 the directory is just "example" not "examples" + $ ant consumer + Buildfile: build.xml + + init: + [mkdir] Created dir: /opt/incubator-activemq-4.0.2/example/target/classes + [mkdir] Created dir: /opt/incubator-activemq-4.0.2/example/src/ddl + + compile: + [javac] Compiling 6 source files to /opt/incubator-activemq-4.0.2/example/target/classes + + consumer: + [echo] Running consumer against server at $url = tcp://localhost:61616 for subject $subject = TEST.FOO + [java] Connecting to URL: tcp://localhost:61616 + [java] Consuming queue: TEST.FOO + [java] Using non-durable subscription + [java] We are about to wait until we consume: 10 message(s) then we will shutdown + ``` +3. In the third terminal, use the commands below to run the ActiveMQ Classic producer: + ``` + $ cd /opt/incubator-activemq-4.0.2/examples + $ ant producer + Buildfile: build.xml + + init: + + compile: + + producer: + [echo] Running producer against server at $url = tcp://localhost:61616 for subject $subject = TEST.FOO + [java] Connecting to URL: tcp://localhost:61616 + [java] Publishing a Message with size 1000 to queue: TEST.FOO + [java] Using non-durable publishing + [java] Sleeping between publish 0 ms + [java] Sending message: Message: 0 sent at: Mon Oct 16 23:21:08 MDT 2006 ... + [java] Sending message: Message: 1 sent at: Mon Oct 16 23:21:08 MDT 2006 ... + [java] Sending message: Message: 2 sent at: Mon Oct 16 23:21:08 MDT 2006 ... + [java] Sending message: Message: 3 sent at: Mon Oct 16 23:21:08 MDT 2006 ... + [java] Sending message: Message: 4 sent at: Mon Oct 16 23:21:08 MDT 2006 ... + [java] Sending message: Message: 5 sent at: Mon Oct 16 23:21:08 MDT 2006 ... + [java] Sending message: Message: 6 sent at: Mon Oct 16 23:21:08 MDT 2006 ... + [java] Sending message: Message: 7 sent at: Mon Oct 16 23:21:08 MDT 2006 ... + [java] Sending message: Message: 8 sent at: Mon Oct 16 23:21:08 MDT 2006 ... + [java] Sending message: Message: 9 sent at: Mon Oct 16 23:21:08 MDT 2006 ... + [java] Done. + [java] connection { + [java] session { + [java] messageCount{ count: 10 unit: count startTime: 1161062468001 lastSampleTime: + 1161062468340 description: Number of messages exchanged } + [java] messageRateTime{ count: 10 maxTime: 142 minTime: 1 totalTime: 315 averageTime: 31.5 + averageTimeExMinMax: 21.5 averagePerSecond: 31.746031746031747 + averagePerSecondExMinMax: 46.51162790697674 unit: millis startTime: 1161062468002 lastSampleTime: + 1161062468340 description: Time taken to process a message (thoughtput rate) } + [java] pendingMessageCount{ count: 0 unit: count startTime: 1161062468001 lastSampleTime: + 1161062468001 description: Number of pending messages } + [java] expiredMessageCount{ count: 0 unit: count startTime: 1161062468001 lastSampleTime: + 1161062468001 description: Number of expired messages } + [java] messageWaitTime{ count: 0 maxTime: 0 minTime: 0 totalTime: 0 averageTime: 0.0 + averageTimeExMinMax: 0.0 averagePerSecond: 0.0 + averagePerSecondExMinMax: 0.0 unit: millis startTime: 1161062468002 lastSampleTime: 1161062468002 + description: Time spent by a message before being delivered } + [java] durableSubscriptionCount{ count: 0 unit: count startTime: 1161062468002 lastSampleTime: + 1161062468002 description: The number of durable + subscriptions } + + [java] producers { + [java] producer queue://TEST.FOO { + [java] messageCount{ count: 10 unit: count startTime: 1161062468025 lastSampleTime: + 1161062468340 description: Number of messages processed } + [java] messageRateTime{ count: 10 maxTime: 142 minTime: 1 totalTime: 315 averageTime: + 31.5 averageTimeExMinMax: 21.5 averagePerSecond: + 31.746031746031747 averagePerSecondExMinMax: 46.51162790697674 unit: millis startTime: 1161062468025 + lastSampleTime: 1161062468340 description: Time taken to + process a message (thoughtput rate) } + [java] pendingMessageCount{ count: 0 unit: count startTime: 1161062468025 lastSampleTime: + 1161062468025 description: Number of pending messages } + [java] messageRateTime{ count: 10 maxTime: 142 minTime: 1 totalTime: 315 averageTime: 31.5 + averageTimeExMinMax: 21.5 averagePerSecond: + 31.746031746031747 averagePerSecondExMinMax: 46.51162790697674 unit: millis startTime: 1161062468025 + lastSampleTime: 1161062468340 description: Time taken to + process a message (thoughtput rate) } + [java] expiredMessageCount{ count: 0 unit: count startTime: 1161062468025 lastSampleTime: + 1161062468025 description: Number of expired messages } + [java] messageWaitTime{ count: 0 maxTime: 0 minTime: 0 totalTime: 0 averageTime: 0.0 + averageTimeExMinMax: 0.0 averagePerSecond: 0.0 + averagePerSecondExMinMax: 0.0 unit: millis startTime: 1161062468025 lastSampleTime: 1161062468025 + description: Time spent by a message before being delivered } + [java] } + [java] } + [java] consumers { + [java] } + [java] } + [java] } + ``` + +Step 1 above just starts up JBoss. Step 2 above starts up a simple message consumer that comes with ActiveMQ Classic. Step 3 above starts up a simple message producer that comes with ActiveMQ Classic. Though the message consumer and message producer are simple utilities, the each one accepts many parameters making them extremely useful for testing ActiveMQ Classic configurations. + +To paraphrase, what just happened was that the message producer sent 10 messages to the TEST.FOO destination and the message consumer received 10 messages from the TEST.FOO destination. Despite being a simple test, it does utilize the ActiveMQ Classic broker, albeit only on a single machine. The next logical step is to set up a full network of ActiveMQ Classic brokers. + +After setting up one broker within one instance of JBoss, setting up another is made much easier, but requires another machine or operating system instance. But that's a whole separate article and something to address another day. + +Conclusion +---------- + +What has been demonstrated here is the integration of ActiveMQ Classic with the JBoss application server. This integration is quite common and performed by many enterprises. I hope that this was helpful to people interested in the integration of ActiveMQ Classic with JBoss application server. + +### Resources + +Below are the configurations for use with both Spring 1.x and Spring 2.x: + + +[File](integrating-apache-activemq-classic-with-jboss.md?sortBy=name&sortOrder=ascending) + +[Modified](integrating-apache-activemq-classic-with-jboss.md?sortBy=date&sortOrder=descending) + +File [amq-spring-1.2.6.tgz](integrating-apache-activemq-classic-with-jboss.data/amq-spring-1.2.6.tgz?api=v2 "Download") + +Oct 03, 2007 by [Bruce Snyder](https://cwiki.apache.org/confluence/display/~bsnyder) + +Labels + +* No labels +* [Edit Labels](# "Edit Labels") + +Preview + +File [amq-spring-2.0.tgz](integrating-apache-activemq-classic-with-jboss.data/amq-spring-2.0.tgz?api=v2 "Download") + +Oct 03, 2007 by [Bruce Snyder](https://cwiki.apache.org/confluence/display/~bsnyder) + +Labels + +* No labels +* [Edit Labels](# "Edit Labels") + +Preview + +[Download All](/confluence/pages/downloadallattachments.action?pageId=67786 "Download all the latest versions of attachments on this page as single zip file.") + diff --git a/hugo/content/components/classic/documentation/jdbc-master-slave.md b/hugo/content/components/classic/documentation/jdbc-master-slave.md new file mode 100644 index 0000000000..d03dbc3240 --- /dev/null +++ b/hugo/content/components/classic/documentation/jdbc-master-slave.md @@ -0,0 +1,133 @@ +--- +title: JDBC Master Slave +layout: classic-doc +--- + + [Features](features) > [Clustering](clustering) > [MasterSlave](masterslave) > [JDBC Master Slave](jdbc-master-slave) + +JDBC Master Slave +----------------- + +First supported in ActiveMQ Classic version 4.1 + +If you are using pure JDBC and not using the high performance journal then you are generally relying on your database as your single point of failure and persistence engine. If you do not have really high performance requirements this approach can make a lot of sense as you have a single persistence engine to backup and manage etc. + +### Startup + +When using just JDBC as the data source you can use a Master Slave approach, running as many brokers as you wish as this diagram shows. On startup one master grabs an exclusive lock in the broker database - all other brokers are slaves and pause waiting for the exclusive lock. + +![](assets/img/Startup.png) + +Clients should be using the [Failover Transport](failover-transport-reference) to connect to the available brokers. e.g. using a URL something like the following +``` +failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616) +``` +Only the master broker starts up its transport connectors and so the clients can only connect to the master. + +### Master failure + +If the master looses connection to the database or looses the exclusive lock then it immediately shuts down. If a master shuts down or fails, one of the other slaves will grab the lock and so the topology switches to the following diagram + +![](assets/img/MasterFailed.png) + +One of the other other slaves immediately grabs the exclusive lock on the database to them commences becoming the master, starting all of its transport connectors. + +Clients loose connection to the stopped master and then the failover transport tries to connect to the available brokers - of which the only one available is the new master. + +### Master restart + +At any time you can restart other brokers which join the cluster and start as slaves waiting to become a master if the master is shutdown or a failure occurs. So the following topology is created after a restart of an old master... + +![](assets/img/MasterRestarted.png) + +### Configuring JDBC Master Slave + +By default if you use the **** to avoid the high performance journal you will be using JDBC Master Slave by default. You just need to run more than one broker and point the client side URIs to them to get master/slave. This works because they both try an acquire an exclusive lock on a shared table in the database and only one will succeed. + +The following example shows how to configure the ActiveMQ Classic broker in JDBC Master Slave mode +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` diff --git a/hugo/content/components/classic/documentation/jdbc-support.md b/hugo/content/components/classic/documentation/jdbc-support.md new file mode 100644 index 0000000000..d3f1226626 --- /dev/null +++ b/hugo/content/components/classic/documentation/jdbc-support.md @@ -0,0 +1,81 @@ +--- +title: JDBC Support +layout: classic-doc +--- + + + +We support a range of SQL databases for message persistence such as + +* Apache Derby +* Axion +* DB2 +* HSQL +* Informix +* MaxDB +* MySQL +* Oracle +* Postgresql +* [SQLServer](Persistence/JDBC Support/sqlserver) +* [Sybase](Persistence/JDBC Support/sybase) + +as well as a number of generic JDBC providers. + +### Auto-discovery of your JDBC provider + +We try to auto-detect from the JDBC driver which JDBCAdapter to use via these [config files](https://git-wip-us.apache.org/repos/asf?p=activemq.git;a=tree;f=activemq-jdbc-store/src/main/resources/META-INF/services/org/apache/activemq/store/jdbc) and the return string from the JDBC driver. + +If you have a JDBC database which we don't support then please let us know what JDBC driver string you're getting and [drop us a note](contact) or raise an issue in our [support database](http://issues.apache.org/activemq/browse/AMQ) and we'll fix it pretty quickly. + +If your database is not in the above list it is normally a matter of tweaking the StatementProvider to ensure that the JDBCMessageStore uses the right flavour of SQL. So normally most databases support one of these providers... + +* org.activemq.store.jdbc.adapter.BlobJDBCAdapter +* org.activemq.store.jdbc.adapter.BytesJDBCAdapter +* org.activemq.store.jdbc.adapter.DefaultJDBCAdapter +* org.activemq.store.jdbc.adapter.ImageJDBCAdapter + +You can explicitly specify the JDBC adaptor using its xbean identifier, inside the activemq.xml... +``` + +``` + +### Customizing the SQL DDL + +You can confiugure the various SQL datatypes - such as column sizes and so forth - using the statements element +``` + + + + + + + + + + + +``` +For more info on what attributes can be set on the statements element, see the [Statements class](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/store/jdbc/Statements.html). All the settable bean properties can be used as attributes of the element. + +### Using MySQL + +If you are using MySQL then you should set the **relaxAutoCommit** flag to be true. e.g. +``` + + + + + + + +``` +To see this in action see the [default configuration file](http://svn.apache.org/repos/asf/activemq/trunk/assembly/src/release/conf/activemq.xml) + +### For AMQ 3.x + +In 3.x you can specify the adapter as follows +``` + + ... + +``` diff --git a/hugo/content/components/classic/documentation/jmeter-performance-tests.md b/hugo/content/components/classic/documentation/jmeter-performance-tests.md new file mode 100644 index 0000000000..4bf428825f --- /dev/null +++ b/hugo/content/components/classic/documentation/jmeter-performance-tests.md @@ -0,0 +1,56 @@ +--- +title: JMeter Performance Tests +layout: classic-doc +--- + +## JMeter Performance Tests + +You can use JMeter to test the performance of your ActiveMQ Classic Server. Please refer to the [JMeter site](http://jmeter.apache.org/) for detailed instructions on using this software. + +### Building a Test Plan + +**For a Producer Sampler:** +1. Add a Thread Group. +2. Add the producer sampler "Producer Sampler" from the Sampler menu. +3. Highlight the Producer Sampler then right click to add the producer listener "View Producer Results" from the Listener menu. +4. Go to the Thread Group element and set the Number of Threads, Ramp-Up Period and Loop Count to 1. + +**For a Consumer Sampler:** +1. Add a Thread Group. +2. Add the consumer sampler "Consumer Sampler" from the Sampler menu. +3. Highlight the Consumer Sampler then right click to add the consumer listener "View Consumer Results" from the Listener menu. +4. Go to the Thread Group element and set the Number of Threads, Ramp-Up Period and Loop Count to 1. + +### The JMeter Performance Test Module + +**1. JMeter Producer Sampler** + +The Producer Sampler sends messages to an ActiveMQ Classic Server. Parameters: +- Server URL (e.g. `tcp://localhost:61616`) +- Duration (min) +- Ramp Up (min) +- No. of Producer +- No. of Subject (must be ≤ No. of Producer) +- Message Size (bytes) +- Delivery Mode - Default is Non-Persistent +- Messaging Domain - Default is Topic +- Message Interval - Default/Custom + +**2. JMeter Producer Listener** + +Provides statistics with the number of messages sent and average messages per second. + +**3. JMeter Consumer Sampler** + +Parameters: +- Server URL (e.g. `tcp://localhost:61616`) +- Duration (min) +- Ramp Up (min) +- No. of Consumer +- No. of Subject (must be ≤ No. of Consumer) +- Delivery Mode - Default is non-Durable +- Messaging Domain - Default is Topic + +**4. JMeter Consumer Listener** + +Provides statistics with the number of messages received and average messages per second. diff --git a/hugo/content/components/classic/documentation/jmeter-system-tests.md b/hugo/content/components/classic/documentation/jmeter-system-tests.md new file mode 100644 index 0000000000..c3c771ef98 --- /dev/null +++ b/hugo/content/components/classic/documentation/jmeter-system-tests.md @@ -0,0 +1,48 @@ +--- +title: JMeter System Tests +layout: classic-doc +--- + +## JMeter System Tests + +You can use JMeter to test your ActiveMQ Classic Server. Please refer to the [JMeter site](http://jmeter.apache.org/) for detailed instructions on using this software. + +The test checks for duplicate messages and the order of messages received. + +### Building a Test Plan + +**For a Producer System Test Sampler:** +1. Add a Thread Group. +2. Add the producer sampler "Producer System Test Sampler" from the Sampler menu. +3. Go to the Thread Group element and set the Number of Threads, Ramp-Up Period and Loop Count to 1. + +**For a Consumer Sampler:** +1. Add the consumer sampler "Consumer System Test Sampler" from the Sampler menu. +2. Highlight the Consumer Sampler then right click to add the consumer listener "View Producer System Test Results" from the Listener menu. + +### The JMeter System Test Module + +**1. JMeter Producer System Test Sampler** + +A JMeter Sampler tells JMeter to send requests to the server. The Producer System Test Sampler will send messages to an ActiveMQ Classic Server. + +Parameters: +- Server URL - defines the server url (e.g. `tcp://localhost:61616`) +- No. of Producer - The number of Producers that would be sending the message +- No. of Subject - The number of Subjects to create and send (must be ≤ No. of Producer) +- Number of Message - The number of messages to send +- Delivery Mode - Default is Non-Persistent +- Messaging Domain - Default is Topic + +**2. JMeter Consumer System Test Sampler** + +Parameters: +- Server URL - defines the server url (e.g. `tcp://localhost:61616`) +- No. of Consumer - The number of Consumers +- No. of Subject - The number of Subjects (must be ≤ No. of Consumer) +- Delivery Mode - Default is non-Durable +- Messaging Domain - Default is Topic + +**3. JMeter Producer System Test Listener** + +Provides the Consumer Identifier, Producer Name, Message, and Message Count for each received message. diff --git a/hugo/content/components/classic/documentation/jms-to-jms-bridge.md b/hugo/content/components/classic/documentation/jms-to-jms-bridge.md new file mode 100644 index 0000000000..5301dfc21d --- /dev/null +++ b/hugo/content/components/classic/documentation/jms-to-jms-bridge.md @@ -0,0 +1,329 @@ +--- +title: JMS to JMS Bridge +layout: classic-doc +--- + + + +> **Warning**, try Camel first! +> +> Note that we recommend you look at using [Apache Camel](http://camel.apache.org/) for bridging ActiveMQ Classic to or from any message broker (or indeed [any other technology, protocol or middleware](http://camel.apache.org/components.html)) as its much easier to: +> +> * keep things flexible; its very easy to map different queue/topic to one or more queues or topics on the other provider +> * perform content based routing, filtering and other [Enterprise Integration Patterns](http://camel.apache.orgFeatures/enterprise-integration-patterns) +> * allows you to work with [any technology, protocol or middleware](http://camel.apache.org/components.html), not just JMS providers +> +> e.g. in your Spring XML file just add: +> ``` +> +> +> +> +> +> +> ``` + +### Introduction + +ActiveMQ Classic provides bridging functionality to other JMS providers that implement the JMS 1.0.2 and above specification. A JMS bridge can be co-located with an ActiveMQ Classic broker or run remotely. In order to support JMS 1.0.2 there is seperation between Queues and Topics. + +temporary destinations and replyTo destinations in the inbound message exchanges are automatically handled, enabling an ActiveMQ Classic service to handle a foreign JMS TopicRequestor or QueueResquestor exchanges. + +### Properties + +**JMS Bridge Topic Connector** + +property name|default value|description +---|---|--- +localTopicConnection|null|if set will be used to connect to ActiveMQ Classic +localTopicConnectionFactory|null|used to initialize the ActiveMQ Classic JMS Connection if localTopicConnection is not set +localClientId|null|set the id of the local connection +outboundClientId|null|set the id of the outbound connection +jndiLocalTemplate|Spring default template|used for locating the Connection Factory for the ActiveMQ Classic Connection if the localTopicConnection or localTopicConnectionFactory is not set +outboundTopicConnection|null|if set will be used to connect to the foreign JMS provider +outboundTopicConnectionFactory|null|used to initialize the foreign JMS Connection if outboundTopicConnection is not set +jndiOutboundTemplate|Spring default template|used for locating the Connection Factory for the ActiveMQ Classic Connection if the localTopicConnection or localTopicConnectionFactory is not set +localUsername|null|if set will be used for authentication to the ActiveMQ Classic JMS provider +localPassword|null|if set will be used for authentication to the ActiveMQ Classic JMS provider +outboundUsername|null|if set will be used for authentication to the foreign JMS provider +outboundPassword|null|if set will be used for authentication to the foreign JMS provider +inboundMessageConvertor|null|if set will be used for converting foreign JMS Messages to a format for ActiveMQ Classic +outboundMessageConvertor|null|if set will be used for converting ActiveMQ Classic messages to a format for the foriegn JMS provider +inboundTopicBridges|null|an array of InboundTopicBridge instances - used for defining inbound (subscribe to) traffic from the foreign JMS provider +outboundTopicBridges|null|an array of OutboundTopicBridge instances - used for defining destinations that will be published to the foreign JMS provider + +**JMS Bridge Queue Connector** + +property name|default value|description +---|---|--- +localQueueConnection|null|if set will be used to connect to ActiveMQ Classic +localQueueConnectionFactory|null|used to initialize the ActiveMQ Classic JMS Connection if localQueueConnection is not set +localClientId|null|set the id of the local connection +outboundClientId|null|set the id of the outbound connection +jndiLocalTemplate|Spring default template|used for locating the Connection Factory for the ActiveMQ Classic Connection if the localQueueConnection or localQueueConnectionFactory is not set +outboundQueueConnection|null|if set will be used to connect to the foreign JMS provider +outboundQueueConnectionFactory|null|used to initialize the foreign JMS Connection if localQueueConnection is not set +jndiOutboundTemplate|Spring default template|used for locating the Connection Factory for the ActiveMQ Classic Connection if the localQueueConnection or localQueueConnectionFactory is not set +localUsername|null|if set will be used for authentication to the ActiveMQ Classic JMS provider +localPassword|null|if set will be used for authentication to the ActiveMQ Classic JMS provider +outboundUsername|null|if set will be used for authentication to the foreign JMS provider +outboundPassword|null|if set will be used for authentication to the foreign JMS provider +inboundMessageConvertor|null|if set will be used for converting foreign JMS Messages to a format for ActiveMQ Classic +outboundMessageConvertor|null|if set will be used for converting ActiveMQ Classic messages to a format for the foriegn JMS provider +inboundQueueBridges|null|an array of InboundQueueBridge instances - used for defining inbound (subscribe to) traffic from the foreign JMS provider +outboundQueueBridges|null|an array of OutboundQueueBridge instances - used for defining destinations that will be forwarded to the foreign JMS provider + +#### Topic Bridges + +**InboundTopicBridge** + +property name|default value|description +---|---|--- +localTopicName|null|the name of the local ActiveMQ Classic Queue +inboundTopicName|null|the foreign topic name to subscribe to +selector|null|selector to use - if any +consumerName|null|if set will create a durable consumer + +**OutboundTopicBridge** + +property name|default value|description +---|---|--- +localTopicName|null|the name of the local ActiveMQ Classic Queue +outboundTopicName|null|the foreign topic name to publish to + +#### Queue Bridges + +**InboundQueueBridge** + +property name|default value|description +---|---|--- +localQueueName|null|the name of the local ActiveMQ Classic Queue +inboundQueueName|null|the foreign queue name to receive from +selector|null|selector to use - if any + + +**OutboundQueueBridge** + +property name|default value|description +---|---|--- +localQueueName|null|the name of the local ActiveMQ Classic Queue +outboundQueueName|null|the foreign queue name to send to + +### Example XBean Configuration + +The following [example config file](http://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/org/apache/activemq/network/jms/queue-xbean.xml) shows how to use the regular [Xml Configuration](xml-configuration) to configure a JMS to JMS bridge. +```xml + + + + + + + + + + + + + + + + +``` + +### Example pure Spring Configuration + +The following example shows how to use raw Spring XML to wire together a broker - bridging to a Foreign JMS provider +```xml + + + + + + + tcp://localhost:61234 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +### Example XBean Configuration to Bridge ActiveMQ Classic to Provider With No URL Setter + +Some JMS providers, WebLogic for instance, do not expose a setter for connection properties like host and port (setBrokerUrl) on their ConnectionFactory object. In this case you need to set outboundQueueConnectionFactoryName and jndiOutboundTemplate in your activemq.xml config file. +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + weblogic.jndi.WLInitialContextFactory + t3://:7001 + + + + + + + + + + + + + +``` + +### Example pure Spring Configuration for sending messages to external ActiveMQ Classic destination through bridge + +Spring beans: +```xml + + + + + + + + + + + tcp://localhost:7000 + + + + + + + + + + tcp://localhost:7001 + + + + + + + + + + + + + + + + + + + + + + + +``` +Java code: +``` +public class BridgeTest { + + public BridgeTest() throws Exception { + + Log log = LogFactory.getLog(getClass()); + + new ClassPathXmlApplicationContext("bridge/context-bridge.xml"); + + ActiveMQConnection connection = ActiveMQConnection.makeConnection("tcp://localhost:7001"); + connection.start(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Destination destination = session.createQueue("messages.input"); + MessageProducer producer = session.createProducer(destination); + producer.send(session.createTextMessage("Test Message")); + log.debug("send message"); + session.close(); + connection.close(); + + connection = ActiveMQConnection.makeConnection("tcp://localhost:7000"); + connection.start(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + destination = session.createQueue("messages.input"); + MessageConsumer consumer = session.createConsumer(destination); + log.debug("receive message"); + Message message = consumer.receive(5000); + log.debug("Received: " + message); + session.close(); + connection.close(); + } + + public static void main(String[] args) throws Exception { + new BridgeTest(); + } + +} +``` diff --git a/hugo/content/components/classic/documentation/jms2.md b/hugo/content/components/classic/documentation/jms2.md new file mode 100644 index 0000000000..daad1b1500 --- /dev/null +++ b/hugo/content/components/classic/documentation/jms2.md @@ -0,0 +1,70 @@ +--- +title: ActiveMQ Jakarta Messaging 3.1 & JMS 2.0 Support +layout: classic-doc +--- + +### Transition Approach + +Initially, ActiveMQ clients will not support all JMS 2.0 functionality and will throw an `UnsupportedOperationException` (`RuntimeException`) for unsupported methods and features, such as those for async send with a `CompletionListener`, sending messages with a delivery delay, and using shared topic consumers. + +As features are implemented in subsequent releases, these exceptions will be replaced with fully functional methods, examples and unit tests. + +### Jakarta Messaging + +Support for JMS 2.0 also enables building upon this for transition to Jakarta Messaging 3.1 and its new `jakarta.jms` API namespace rather than the historical `javax.jms` namespace. + +- The standard for Java Enterprise features going forward +- Required for Spring 6 +- Required for Jakarta EE 9 + 10 +- JMS API Java package name-change only +- ActiveMQ package names do not change + +| Client jar | API Package | Version | Notes | +|---|---|---|---| +| activemq-client | `jakarta.jms` | 6.0.x | Partial Jakarta Messaging 3.1 support. Works with embedded broker and VM transport. | +| activemq-client | `javax.jms` | 5.18.x | Partial JMS 2.0 support. Works with embedded broker and VM transport. | +| activemq-client-jakarta | `jakarta.jms` | 5.18.1+ | Transitional module for partial, *client-only* Jakarta Messaging 3.1 support. No embedded broker / VM transport support, only remote brokers. | + +There is no functional change, this is purely a Java package naming change: +```java +import javax.jms.ConnectionFactory → import jakarta.jms.ConnectionFactory +import javax.jms.Message → import jakarta.jms.Message +``` + +To use the Jakarta transition client with ActiveMQ 5.18.x in Maven: +```xml + + org.apache.activemq + activemq-client-jakarta + ${activemq.version} + +``` +Note: With ActiveMQ 6.x the `activemq-client-jakarta` module is removed as it is no longer needed. + +### Spring Bean Usage + +Spring bean definitions do not change for Jakarta support: +```xml + +``` + +### Implementation Progress + +| JIRA | Status | Target Version | Completed Version | Feature | +|---|:---:|---|---|---| +| [AMQ-7309](https://issues.apache.org/jira/browse/AMQ-7309) | ✅ | 5.16.0 | 5.18.0 | JMS 2.0 API dependency | +| [AMQ-8322](https://issues.apache.org/jira/browse/AMQ-8322) | ✅ | 5.17.0 | 5.18.0 | `JMSContext`, `JMSConsumer`, `JMSProducer`, & `JMSRuntimeException` | +| [AMQ-8321](https://issues.apache.org/jira/browse/AMQ-8321) | ✅ | 5.18.0 | 5.18.0 | GetBody/isBodyAssignable | +| [AMQ-8325](https://issues.apache.org/jira/browse/AMQ-8325) | ✅ | 5.18.3, 6.0.0 | 5.18.3, 6.0.0 | XA Connection methods | +| [AMQ-8494](https://issues.apache.org/jira/browse/AMQ-8494) | ✅ | 5.17.1 | 5.18.0 | `CLIENT_ACKNOWLEDGEMENT` mode | +| [AMQ-8464](https://issues.apache.org/jira/browse/AMQ-8464) | ❌ | 6.4.0 | | JMSConsumer `.receiveBody(Class)` methods | +| [AMQ-8320](https://issues.apache.org/jira/browse/AMQ-8320) | ❌ | 6.3.0 | | Delivery Delay | +| [AMQ-8324](https://issues.apache.org/jira/browse/AMQ-8324) | ❌ | 6.4.0 | | JMSProducer `CompletionListener` async send | +| [AMQ-8323](https://issues.apache.org/jira/browse/AMQ-8323) | ❌ | | | Shared Topic Consumer | +| [AMQ-9451](https://issues.apache.org/jira/browse/AMQ-9451) | ❌ | 6.5.0 | | Pooled `ConnectionFactory` | + +### Feature Notes + +| JMS Object | Feature | Notes | +|---|---|---| +| `JMSProducer` | disableMessageID | ActiveMQ does not support the optional and rarely used JMS Specification feature to disable JMS message ID | diff --git a/hugo/content/components/classic/documentation/jmx.md b/hugo/content/components/classic/documentation/jmx.md new file mode 100644 index 0000000000..5f88dcc832 --- /dev/null +++ b/hugo/content/components/classic/documentation/jmx.md @@ -0,0 +1,163 @@ +--- +title: JMX +layout: classic-doc +--- + + + +JMX +--- + +Apache ActiveMQ Classic has extensive support for JMX to allow you to monitor and control the behavior of the broker via the [JMX MBeans](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/broker/jmx/package-summary.html). + +### Using JMX to monitor Apache ActiveMQ Classic + +You can enable/disable JMX support as follows... + +1. [Run a broker](run-broker) setting the broker property useJmx to true (enabled by default) i.e. + + For xbean configuration + ``` + + ... + + ``` +2. Run a JMX console + ``` + $ jconsole + ``` +3. The ActiveMQ Classic broker should appear in the list of local connections, if you are running JConsole on the same host as ActiveMQ Classic. + +**JMX remote access** + +Remote connections to JMX are not enabled by default in the activemq.xml for security reasons. Please refer to [Java Management guide](http://docs.oracle.com/javase/6/docs/technotes/guides/management/agent.html) to configure the broker for remote management. + +Using the Apache ActiveMQ Classic version on OS X it appears as follows: + +![](assets/img/activemq-jmx.png) +  + +### ActiveMQ Classic MBeans Reference + +For additional references provided below is a brief hierarchy of the mbeans and a listing of the properties, attributes, and operations of each mbeans. + +Mbean Type|Properties / ObjectName |Attributes|Operations +---|---|---|--- +Broker|**type=Broker**, **brokerName=<broker-identifier>**|BrokerId, TotalEnqueueCount, TotalDequeueCount, TotalConsumerCount, TotalMessageCount, TotalConnectionsCount, TotalConsumerCount, TotalProducerCount, MemoryLimit, MemoryPercentUsage, StoreLimit, StorePercentUsage|start, stop, terminateJVM, resetStatistics, gc +Destination|**type=Broker**, **brokerName=<name-of-broker>**, **destinationType=Queue\|Topic**, **destinationName=<name>**|Average, EnqueueTime, ConsumerCount, DequeueCount, EnqueueCount, ExpiredCount, InFlightCount, MemoryLimit, MemoryPercentUsage, Name, QueueSize (queues only)|browseMessages, gc, purge, resetStatistics +NetworkConnector|**type=Broker**, **brokerName==<name-of-broker>**, **connector=networkConnectors**, **networkConnectorName==<connector-identifier>**|Name, Duplex, DynamicOnly, BridgeTempDestinations, ConduitSubscriptions, DecreaseNetworkConsumerPriority, DispatchAsync, DynamicOnly, NetworkTTL, Password, PrefetchSize|start, stop +Connector|**type=Broker**, **brokerName=<name-of-broker>**, **connector=clientConnectors**, **ConnectorName==<connector-identifier>**|StatisticsEnabled|start, stop, resetStatistics, enableStatistics, disableStatistics, connectionCount +Connection|**type=Broker**, **brokerName=<name-of-broker>**, **connectionViewType=clientId**, **connectionName==<connection-identifier>**|DispatchQueueSize, Active, Blocked, Connected, Slow, Consumers, Producers, RemoteAddress, UserName, ClientId|start, stop, resetStatistics +PersistenceAdapter|**type=Broker**, **brokerName=<name-of-broker>**, **Service=PersistenceAdapter**, **InstanceName==<adapter-identifier>**|Name, Size, Data, Transactions| +Health|**type=Broker**, **brokerName=<name-of-broker>**, **Service=Health**|CurrentStatus|health + +Command line utilities are also available to let you monitor ActiveMQ Classic. Refer to [ActiveMQ Classic Command Line Tools Reference](activemq-classic-command-line-tools-reference) for usage information. + +JMX API is also exposed via [REST management API](rest) + +### Password Protecting the JMX Connector + +(For Java 1.5+) + +1. Make sure JMX is enabled, but tell ActiveMQ Classic **not** create its own connector so that it will use the default JVM JMX connector. + ```` + + + ... + + + + + + ... + + + ```` +2. Create access and password files + + conf/jmx.access: + ``` + # The "monitorRole" role has readonly access. + # The "controlRole" role has readwrite access. + monitorRole readonly + controlRole readwrite + ``` + conf/jmx.password: + ``` + # The "monitorRole" role has password "abc123". + # The "controlRole" role has password "abcd1234". + monitorRole abc123 + controlRole abcd1234 + ``` + (Make sure both files are not world readable - more info can be find [here](http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html#auth) to protect files) + + For more details you can see the [Monitoring Tomcat Document](http://tomcat.apache.org/tomcat-5.5-doc/monitoring.html) + +3. Modify the "activemq" startup script (in bin) to enable the Java 1.5+ JMX connector + + Find the "ACTIVEMQ_SUNJMX_START=" line and change it to the following: (note that in previous versions of ActiveMQ Classic this property was called SUNJMX in some scripts.  As of v5.12.0 all scripts use ACTIVEMQ_SUNJMX_START): + + 1. Windows + ``` + ACTIVEMQ_SUNJMX_START=-Dcom.sun.management.jmxremote.port=1616 -Dcom.sun.management.jmxremote.ssl=false \ + -Dcom.sun.management.jmxremote.password.file=%ACTIVEMQ_BASE%/conf/jmx.password \ + -Dcom.sun.management.jmxremote.access.file=%ACTIVEMQ_BASE%/conf/jmx.access + ``` + 2. Unix + ``` + ACTIVEMQ_SUNJMX_START="-Dcom.sun.management.jmxremote.port=1616 -Dcom.sun.management.jmxremote.ssl=false \ + -Dcom.sun.management.jmxremote.password.file=${ACTIVEMQ_BASE}/conf/jmx.password \ + -Dcom.sun.management.jmxremote.access.file=${ACTIVEMQ_BASE}/conf/jmx.access" + ``` + + This could be set in /etc/activemq.conf instead (if you have root access): + + 1. Windows + ``` + ACTIVEMQ_HOME=DRIVE_LETTER:/where/ActiveMQ/is/installed + ACTIVEMQ_BASE=%ACTIVEMQ_HOME% + ACTIVEMQ_SUNJMX_START=-Dcom.sun.management.jmxremote.port=1616 -Dcom.sun.management.jmxremote.ssl=false \ + -Dcom.sun.management.jmxremote.password.file=%ACTIVEMQ_BASE%/conf/jmx.password \ + -Dcom.sun.management.jmxremote.access.file=%ACTIVEMQ_BASE%/conf/jmx.access + ``` + 2. Unix + ``` + ACTIVEMQ_HOME=DRIVE_LETTER:/where/ActiveMQ/is/installed + ACTIVEMQ_BASE=${ACTIVEMQ_HOME} + ACTIVEMQ_SUNJMX_START="-Dcom.sun.management.jmxremote.port=1616 -Dcom.sun.management.jmxremote.ssl=false \ + -Dcom.sun.management.jmxremote.password.file=${ACTIVEMQ_BASE}/conf/jmx.password \ + -Dcom.sun.management.jmxremote.access.file=${ACTIVEMQ_BASE}/conf/jmx.access" + ``` +4. Start ActiveMQ Classic + +You should be able to connect to JMX on the JMX URL +``` +service:jmx:rmi:///jndi/rmi://:1616/jmxrmi +``` +And you will be forced to login. + +### Selective MBean registration + +In situations where you need to scale your broker to large number of connections, destinations and consumers it can become very expensive to keep JMX MBeans for all those objects. Instead of turning off JMX completely, starting with 5.12.0, you can selectively suppress registration of some types of MBeans and thus help your broker scale, while still having a basic view of the broker state. + +For example, the following configuration will exclude all dynamic producers, consumers, connections and advisory topics from registering their MBeans +``` + + + +``` + +#### ManagementContext Properties Reference + +Property Name|Default Value|Description +useMBeanServer|true|If true then it avoids creating a new MBean server if a MBeanServer has already been created in the JVM +jmxDomainName|org.apache.activemq|The jmx domain that all objects names will use +createMBeanServer|true|If we should create the MBeanServer is none is found. +createConnector|false|Please refer to [Java Management guide](http://docs.oracle.com/javase/6/docs/technotes/guides/management/agent.html) to configure the server for remote management and lock down the endpoint serialisation with an appropriate [jdk.serialFilter](http://openjdk.java.net/jeps/290)

    Note: if set to true:
    * lock down the endpoint serialisation with an appropriate jdk.serialFilter
    * configure rmiServerPort and connectorHost to lock down the RMI server interface binding +connectorPort|1099|The port that the JMX connector will use +connectorHost|localhost|The host that the JMX connector and RMI server (if rmiServerPort>0) will use +rmiServerPort|0|The RMI server port, handy if port usage needs to be restricted behind a firewall +connectorPath|/jmxrmi|The path that JMX connector will be registered under +findTigerMBeanServer|true|Enables/disables the searching for the Java 5 platform MBeanServer +suppressMBean||List of MBean name patters to ignore + diff --git a/hugo/content/components/classic/documentation/jndi-support.md b/hugo/content/components/classic/documentation/jndi-support.md new file mode 100644 index 0000000000..d0ffbbaa88 --- /dev/null +++ b/hugo/content/components/classic/documentation/jndi-support.md @@ -0,0 +1,219 @@ +--- +title: JNDI Support +layout: classic-doc +--- + + + +ActiveMQ Classic will work with any JNDI provider capable of storing Java objects. However it is common to require a JNDI initial context to be able to run many JMS example programs, like [Sun's JMS tutorial.](http://java.sun.com/products/jms/tutorial/1_3_1-fcs/doc/jms_tutorialTOC.html) + +So we provide a simple JNDI `InitialContextFactory` which can be used to lookup JMS connection factory objects as well as Destination objects. For example if you place this [jndi.properties](http://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/jndi.properties) file on your classpath, you can look inside the `InitialContext` and lookup `ConnectionFactory` objects and `Destinations` etc. +``` +java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory + +# use the following property to configure the default connector +java.naming.provider.url = vm://localhost + +# use the following property to specify the JNDI name the connection factory +# should appear as. +#connectionFactoryNames = connectionFactory, queueConnectionFactory, topicConnectionFactry + +# register some queues in JNDI using the form +# queue.[jndiName] = [physicalName] +queue.MyQueue = example.MyQueue + + +# register some topics in JNDI using the form +# topic.[jndiName] = [physicalName] +topic.MyTopic = example.MyTopic +``` +You can edit the `jndi.properties` file to configure the `ActiveMQConnectionFactory`'s properties such as `brokerURL` and whether or not there should be an embedded broker etc. See [how to embed a broker in a connection](how-do-i-embed-a-broker-inside-a-connection) for more details. + +### ActiveMQ Classic JNDI Tutorial + +This is a quick one page tutorial on how to setup and use JNDI to create a connection to ActiveMQ Classic. The first thing is ActiveMQ Classic does not provide a full JNDI server. This means JMS clients need to use properties files to create a JNDI `IntialContextFactory`. If you need an example properties file, you can look the source distribution [https://github.com/apache/activemq/blob/master/activemq-unit-tests/src/test/resources/jndi.properties](https://github.com/apache/activemq/blob/master/activemq-unit-tests/src/test/resources/jndi.properties). Before we proceed, here are the properties. + +Name|Value +`java.naming.factory.initial`|`org.apache.activemq.jndi.ActiveMQInitialContextFactory` +`java.naming.provider.url`|`tcp://hostname:61616` +`topic.MyTopic`|`example.MyTopic` + +Make sure to add `activemq-__.jar` and `spring-1.x.jar` to your classpath. If the libraries are not in the classpath, you will get a `ClassNotFoundException` at runtime. If you get `ClassNotFoundException`, try printing out the classpath and check it is present. You can also run ActiveMQ Classic with `-verbose` option to verify the jar was loaded correctly. + +**Sample Code** + +``` +// Create a new intial context, which loads from jndi.properties file: +javax.naming.Context ctx = new javax.naming.InitialContext(); +// Lookup the connection factory: +javax.jms.TopicConnectionFactory factory = (javax.jms.TopicConnectionFactory)ctx.lookup("ConnectionFactory"); +// Create a new TopicConnection for pub/sub messaging: +javax.jms.TopicConnection conn = factory.getTopicConnection(); +// Lookup an existing topic: +javax.jms.Topic mytopic = (javax.jms.Topic)ctx.lookup("MyTopic"); +// Create a new TopicSession for the client: +javax.jms.TopicSession session = conn.createTopicSession(false,TopicSession.AUTO_ACKNOWLEDGE); +// Create a new subscriber to receive messages: +javax.jms.TopicSubscriber subscriber = session.createSubscriber(mytopic); +``` +Notice the name of the topic in the sample is `MyTopic`. ActiveMQ Classic will read the `jndi.properties` files and creates the topics and queues in a lazy fashion. The prefix topic and queue is stripped, so the JNDI name begins after the prefix. + +Once you have the `jndi.properties` edited and ready, it needs to be accessible to your application. The easiest way is to add `jndi.properties` to a jar file. When `new InitialContext()` is called, it will scan the resources and find the file. If you get `javax.naming.NamingException`, it usually means the `jndi.properties` file is not accessible. + +You can also try to create a new initial context using either an instance of properties file or a map. For example, the approach recommended by JMS specification will work just fine. + +Example Recommended by Specification +``` +javaProperties props = new Properties(); +props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory"); +props.setProperty(Context.PROVIDER_URL, "tcp://hostname:61616"); +javax.naming.Context ctx = new InitialContext(props); +``` +If ActiveMQ Classic is embedded within an EJB container, you will need to look at the containers documentation for the correct JNDI values. + +### Dynamically Creating Destinations + +For the easiest possible configuration with JNDI based programs, there are two dynamic contexts, namely: + +* `dynamicQueues` +* `dynamicTopics` + +These allow you to lookup queues and topics using JNDI without any configuration. + +For example, if you use the following name to lookup into JNDI: +``` +dynamicQueues/FOO.BAR +``` +you will get back an `ActiveMQQueue` of the name `FOO.BAR`. This can be very handy if you can easily reconfigure the JNDI name to use to lookup something in JNDI, but don't want to have to double configure a `jndi.properties` to match. + +### Working With Embedded Brokers + +It is often useful to use an embedded broker in the same JVM as the JMS client. For this see [How do I embed a Broker inside a Connection](how-do-i-embed-a-broker-inside-a-connection). + +If you want to use an embedded broker with your JNDI provider you can just use the [VM Transport](vm-transport-reference) to connect to the broker in your URL. e.g. to create a purely in JVM broker use this URI +``` +vm://locahost +``` +If you want to customize the broker use something like this: +``` +vm:broker:(tcp://localhost:61616) +``` +More options are available in the [VM Transport Reference](vm-transport-reference) + +### Example Java Code + +Once you have configured JNDI on the classpath you can run any normal JMS application such as the following [example](http://svn.apache.org/repos/asf/incubator/activemq/trunk/activemq-unit-tests/src/test/java/org/apache/activemq/demo/SimpleProducer.java). Notice that the Java code just uses pure JMS APIs and is not in any way ActiveMQ Classic specific +``` +/** + * The SimpleQueueSender class consists only of a main method, + * which sends several messages to a queue. + * + * Run this program in conjunction with SimpleQueueReceiver. + * Specify a queue name on the command line when you run the + * program. By default, the program sends one message. Specify + * a number after the queue name to send that number of messages. + */ + +package org.apache.activemq.demo; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +/** + * A simple polymorphic JMS producer which can work with Queues or Topics which + * uses JNDI to lookup the JMS connection factory and destination. + */ +public final class SimpleProducer { + private static final Logger LOG = LoggerFactory.getLogger(SimpleProducer.class); + private SimpleProducer() {}   + + /** + * @param args the destination name to send to and optionally, the number of + * messages to send + */ + public static void main(String[] args) { + Context jndiContext; + ConnectionFactory connectionFactory; + Connection connection; + Session session; + Destination destination; + MessageProducer producer; + String destinationName; + final int numMsgs;   + + if ((args.length < 1) || (args.length > 2)) { + LOG.info("Usage: java SimpleProducer []"); System.exit(1); + }   + + destinationName = args[0]; + LOG.info("Destination name is " + destinationName); + + if (args.length == 2) { + numMsgs = (new Integer(args[1])).intValue(); + } else { + numMsgs = 1; + } + + /* + * Create a JNDI API InitialContext object + */ + try { + jndiContext = new InitialContext(); + } catch (NamingException e) { + LOG.info("Could not create JNDI API context: " + e.toString()); + System.exit(1); + } + + /* + * Look up connection factory and destination. + */ + try { + connectionFactory = (ConnectionFactory)jndiContext.lookup("ConnectionFactory"); + destination = (Destination)jndiContext.lookup(destinationName); + } catch (NamingException e) { + LOG.info("JNDI API lookup failed: " + e); + System.exit(1); + }   + + /* + * Create connection. Create session from connection; false means + * session is not transacted. Create sender and text message. Send + * messages, varying text slightly. Send end-of-messages message. + * Finally, close the connection. + */ + try { + connection = connectionFactory.createConnection(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + producer = session.createProducer(destination); + TextMessage message = session.createTextMessage();   + for (int i = 0; i < numMsgs; i++) { + message.setText("This is message " + (i + 1)); + LOG.info("Sending message: " + message.getText()); producer.send(message); + }   + + /* + * Send a non-text control message indicating end of messages. + */ + producer.send(session.createMessage()); + } catch (JMSException e) { + LOG.info("Exception occurred: " + e); + } finally { + if (connection != null) { + try { + connection.close(); + } catch (JMSException ignored) { + } + } + } + } +} +``` diff --git a/hugo/content/components/classic/documentation/journal-is-already-opened-by-this-application.md b/hugo/content/components/classic/documentation/journal-is-already-opened-by-this-application.md new file mode 100644 index 0000000000..19c0de834b --- /dev/null +++ b/hugo/content/components/classic/documentation/journal-is-already-opened-by-this-application.md @@ -0,0 +1,34 @@ +--- +title: Journal is already opened by this application +layout: classic-doc +--- + + + +### Error + +You get something like this +``` +java.io.IOException: Journal is already opened by this application. + at org.apache.activeio.journal.active.ControlFile.lock(ControlFile.java:71) + at org.apache.activeio.journal.active.LogFileManager.initialize(LogFileManager.java:120) + at org.apache.activeio.journal.active.LogFileManager.(LogFileManager.java:101) + at org.apache.activeio.journal.active.JournalImpl.(JournalImpl.java:99) + at org.apache.activemq.store.DefaultPersistenceAdapterFactory.createJournal(DefaultPersistenceAdapterFactory.java:198) + at org.apache.activemq.store.DefaultPersistenceAdapterFactory.getJournal(DefaultPersistenceAdapterFactory.java:134) +``` + +### Description + +Each broker needs to have its own directory to store its journal files etc. The error indicates that you have 2 brokers sharing the same files. + +A common cause of this exception is that you are running two brokers on one machine using the same config file pointing to the same directory. So a work around is to parameterise the directory name via Spring's property syntax - or just create another configuration file so that the second broker uses a different directory. + +Another cause of this problem is if you are using the vm://localhost style transport in a JMS client with the JMS connection starting before you have initialised your broker. If you create a vm transport connection, it will auto-create a broker if there is not one running already; so you can end up creating 2 brokers by accident. The work around is to make sure that the JMS connection factory you are using depends on the broker you are configuring (e.g. in Spring use a **depends-on** attribute on the connection factory to make it depend on the broker). This will ensure that the broker is initialized first before the connection factory. + +Be careful with broker names and URIs + +Make sure you do not use any strange characters in the names of brokers as they are converted to URIs which [do not allow things like underscores](http://java.sun.com/j2se/1.4.2/docs/api/java/net/URI.html) in them etc. + +This problem could also be caused by [a bad OS and JVM combination](the-broker-will-not-start) + diff --git a/hugo/content/components/classic/documentation/junit-reports.md b/hugo/content/components/classic/documentation/junit-reports.md new file mode 100644 index 0000000000..974af1f98e --- /dev/null +++ b/hugo/content/components/classic/documentation/junit-reports.md @@ -0,0 +1,8 @@ +--- +title: JUnit Reports +layout: classic-doc +--- + +## JUnit Reports + +The latest test reports are visible via the [Apache ActiveMQ Classic continuous integration builds](https://ci-builds.apache.org/job/ActiveMQ/). diff --git a/hugo/content/components/classic/documentation/kahadb.md b/hugo/content/components/classic/documentation/kahadb.md new file mode 100644 index 0000000000..5bc9d5e189 --- /dev/null +++ b/hugo/content/components/classic/documentation/kahadb.md @@ -0,0 +1,134 @@ +--- +title: KahaDB +layout: classic-doc +--- + +KahaDB is a file based persistence database that is local to the message broker that is using it. It has been optimized for fast persistence. It is the the default storage mechanism since **ActiveMQ Classic 5.4**. KahaDB uses less file descriptors and provides faster recovery than its predecessor, the [AMQ Message Store](amq-message-store). + +Configuration +------------- + +To use KahaDB as the broker's persistence adapter configure ActiveMQ Classic as follows (example): +``` + + + + + +``` + +### KahaDB Properties + +Property|Default|Comments +---|---|--- +`archiveCorruptedIndex`|`false`|If `true`, corrupted indexes found at startup will be archived (not deleted). +`archiveDataLogs`|`false`|If `true`, will move a message data log to the archive directory instead of deleting it. +`checkForCorruptJournalFiles`|`false`|If `true`, will check for corrupt journal files on startup and try and recover them. +`checkpointInterval`|`5000`|Time (ms) before check-pointing the journal. +`checksumJournalFiles`|`true`|Create a checksum for a journal file. The presence of a checksum is required in order for the persistence adapter to be able to detect corrupt journal files. Before **ActiveMQ Classic 5.9.0**: the default is `false`. +`cleanupInterval`|`30000`|The interval (in ms) between consecutive checks that determine which journal files, if any, are eligible for removal from the message store. An eligible journal file is one that has no outstanding references. +`compactAcksAfterNoGC`|`10`|From **ActiveMQ Classic 5.14.0**: when the acknowledgement compaction feature is enabled this value controls how many store GC cycles must be completed with no other files being cleaned up before the compaction logic is triggered to possibly compact older acknowledgements spread across journal files into a new log file.  The lower the value set the faster the compaction may occur which can impact performance if it runs to often. +`compactAcksIgnoresStoreGrowth`|`false`|From **ActiveMQ Classic 5.14.0**: when the acknowledgement compaction feature is enabled this value controls whether compaction is run when the store is still growing or if it should only occur when the store has stopped growing (either due to idle or store limits reached).  If enabled the compaction runs regardless of the store still having room or being active which can decrease overall performance but reclaim space faster.  +`concurrentStoreAndDispatchQueues`|`true`|Enable the dispatching of Queue messages to interested clients to happen concurrently with message storage. +`concurrentStoreAndDispatchTopics`|`false`|Enable the dispatching of Topic messages to interested clients to happen concurrently with message storage. **Enabling this property is not recommended.** +`directory`|`activemq-data`|The path to the directory to use to store the message store data and log files. +`directoryArchive`|`null`|Define the directory to move data logs to when they all the messages they contain have been consumed. +`enableAckCompaction`|`true`|From **ActiveMQ Classic 5.14.0**: this setting controls whether the store will perform periodic compaction of older journal log files that contain only Message acknowledgements. By compacting these older acknowledgements into new journal log files the older files can be removed freeing space and allowing the message store to continue to operate without hitting store size limits. +`enableIndexWriteAsync`|`false`|If `true`, the index is updated asynchronously. +`enableJournalDiskSyncs`|`true`|Ensure every journal write is followed by a disk sync (JMS durability requirement). This property is deprecated as of **ActiveMQ Classic** **5.14.0**. From **ActiveMQ Classic** **5.14.0**: see `journalDiskSyncStrategy`. +`ignoreMissingJournalfiles`|`false`|If `true`, reports of missing journal files are ignored. +`indexCacheSize`|`10000`|Number of index pages cached in memory. +`indexDirectory`||From **ActiveMQ Classic 5.10.0**: If set, configures where the KahaDB index files (`db.data` and `db.redo`) will be stored. If not set, the index files are stored in the directory specified by the `directory` attribute. +`indexWriteBatchSize`|`1000`|Number of indexes written in a batch. +`journalDiskSyncInterval`|`1000`|Interval (ms) for when to perform a disk sync when `journalDiskSyncStrategy=periodic`. A sync will only be performed if a write has occurred to the journal since the last disk sync or when the journal rolls over to a new journal file. +`journalDiskSyncStrategy`|`always`|From **ActiveMQ Classic 5.14.0**: this setting configures the disk sync policy. The list of available sync strategies are (in order of decreasing safety, and increasing performance): `always` Ensure every journal write is followed by a disk sync (JMS durability requirement). This is the safest option but is also the slowest because it requires a sync after every message write. This is equivalent to the deprecated property `enableJournalDiskSyncs=true`. `periodic` The disk will be synced at set intervals (if a write has occurred) instead of after every journal write which will reduce the load on the disk and should improve throughput. The disk will also be synced when rolling over to a new journal file. The default interval is 1 second. The default interval offers very good performance, whilst being safer than `never` disk syncing, as data loss is limited to a maximum of 1 second's worth. See `journalDiskSyncInterval` to change the frequency of disk syncs. `never` A sync will never be explicitly called and it will be up to the operating system to flush to disk. This is equivalent to setting the deprecated property `enableJournalDiskSyncs=false`. This is the fastest option but is the least safe as there's no guarantee as to when data is flushed to disk. Consequently message loss _can_ occur on broker failure. +`journalMaxFileLength`|`32mb`|A hint to set the maximum size of the message data logs. +`maxAsyncJobs`|`10000`|The maximum number of asynchronous messages that will be queued awaiting storage (should be the same as the number of concurrent MessageProducers). +`preallocationScope`|`entire_journal`|From **ActiveMQ Classic 5.14.0**: this setting configures how journal data files are preallocated. The default strategy preallocates the journal file on first use using the appender thread. `entire_journal_async` will use preallocate ahead of time in a separate thread. `none` disables preallocation. On SSD, using `entire_journal_async` avoids delaying writes pending preallocation on first use. **Note**: on HDD the additional thread contention for disk has a negative impact. Therefore use the default. +`preallocationStrategy`|`sparse_file`|From **ActiveMQ Classic 5.12.0**: This setting configures how the broker will try to preallocate the journal files when a new journal file is needed. `sparse_file` - sets the file length, but does not populate it with any data. `os_kernel_copy` - delegates the preallocation to the Operating System. `zeros`  - each preallocated journal file contains nothing but `0x00` throughout. +`storeOpenWireVersion`|`11`|Determines the version of OpenWire commands that are marshaled to the KahaDB journal. Before **ActiveMQ Classic 5.12.0**: the default value is `6`. Some features of the broker depend on information stored in the OpenWire commands from newer protocol revisions and these may not work correctly if the store version is set to a lower value.  KahaDB stores from broker versions greater than 5.9.0 will in many cases still be readable by the broker but will cause the broker to continue using the older store version meaning newer features may not work as intended.  For KahaDB stores that were created in versions prior to **ActiveMQ Classic 5.9.0** it will be necessary to manually set `storeOpenWireVersion="6"` in order to start a broker without error. + +> For tuning locking properties see the options listed at [Pluggable storage lockers.](pluggable-storage-lockers) + +### Slow File System Access Diagnostic Logging + +You can configure a non zero threshold in milliseconds for database updates. If database operation is slower than that threshold (for example if you set it to `500`), you may see messages like: +``` +Slow KahaDB access: cleanup took 1277 | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Classic Journal Checkpoint Worker +``` +You can configure a threshold used to log these messages by using a system property and adjust it to your disk speed so that you can easily pick up runtime anomalies. +``` +-Dorg.apache.activemq.store.kahadb.LOG_SLOW_ACCESS_TIME=1500 +``` + +Multi(m) kahaDB Persistence Adapter +=================================== + +From **ActiveMQ Classic 5.6**: it's possible to distribute destinations stores across multiple kahdb persistence adapters. When would you do this? If you have one fast producer/consumer destination and another periodic producer destination that has irregular batch consumption then disk usage can grow out of hand as unconsumed messages become distributed across multiple journal files. Having a separate journal for each ensures minimal journal usage. Also, some destination may be critical and require disk synchronization while others may not. In these cases you can use the `mKahaDB` persistence adapter and filter destinations using wildcards, just like with destination policy entries. + +### Transactions + +Transactions can span multiple journals if the destinations are distributed. This means that two phase completion is necessary, which does impose a performance (additional disk sync) penalty to record the commit outcome. This penalty is only imposed if more than one journal is involved in a transaction. + +### Configuration + +Each instance of `kahaDB` can be configured independently. If no destination is supplied to a `filteredKahaDB`, the implicit default value will match any destination, queue or topic. This is a handy catch all. If no matching persistence adapter can be found, destination creation will fail with an exception. The `filteredKahaDB` shares its wildcard matching rules with [Per Destination Policies](per-destination-policies). + +From ActiveMQ Classic 5.15, `filteredKahaDB` support a StoreUsage attribute named `usage`. This allows individual disk limits to be imposed on matching queues. +``` + + +  + + + + + + + + + + + + + + + + + + + + + + + +``` + +### Automatic Per Destination Persistence Adapter + +Set `perDestination="true"` on the catch all, i.e., when no explicit destination is set, `filteredKahaDB` entry. Each matching destination will be assigned its own `kahaDB` instance. +``` + + +  + + + + + + + + + + + + + +``` + +> Specifying both `perDestination="true"` _and_ `queue=">"` on the same `filteredKahaDB` entry has not been tested. It _may_ result in the following exception being raised: +> +> ``` +> Reason: java.io.IOException: File '/opt/java/apache-activemq-5.9.0/data/mKahaDB/lock' could not be locked as lock is already held for this jvm` +> ``` + diff --git a/hugo/content/components/classic/documentation/latency.md b/hugo/content/components/classic/documentation/latency.md new file mode 100644 index 0000000000..d80517ca1f --- /dev/null +++ b/hugo/content/components/classic/documentation/latency.md @@ -0,0 +1,11 @@ +--- +title: Latency +layout: classic-doc +--- + + + +Latency + +We typically use this term when talking about the elapsed time it takes to process a single message. When using Request-Response message topologies its often means the round trip time for a message to flow to a service and for the reply to be recieved. + diff --git a/hugo/content/components/classic/documentation/ldap-broker-discovery-mechanism.md b/hugo/content/components/classic/documentation/ldap-broker-discovery-mechanism.md new file mode 100644 index 0000000000..37d5cffc7a --- /dev/null +++ b/hugo/content/components/classic/documentation/ldap-broker-discovery-mechanism.md @@ -0,0 +1,168 @@ +--- +title: LDAP Broker Discovery Mechanism +layout: classic-doc +--- + + + +Configuring network topologies can be quite tedious when the number of brokers in the system is large. To help ease the configuration overhead for these types of situations, a broker can be configured to look up its broker connections using a LDAP v3 directory server. + +> **Note** +> +> The basic feature was added to satisfy [AMQ-358](https://issues.apache.org/activemq/browse/AMQ-358). There are known problems and limitations with this implementation. These deficiencies have been addressed in [AMQ-1587](https://issues.apache.org/activemq/browse/AMQ-1587). The features discussed on this page require the patch attached to JIRA issue [AMQ-1587](https://issues.apache.org/activemq/browse/AMQ-1587). This patch should apply cleanly to the ActiveMQ Classic 5.0.0 release or the current development trunk. + +LDAP v3 Directory Server Compliance +----------------------------------- + +The following table lists a known subset of directory servers and their compliance to work with the LDAP discovery feature. Most LDAP v3 directory servers will support this feature if they properly implement the [RFC2307](http://www.ietf.org/rfc/rfc2307.txt) schemas. In order to support the persistent search capabilities the server must implement the extension defined in [draft-ietf-ldapext-psearch-03.txt](http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-ldapext-psearch-03.txt). + +Vendor|Product|Version|[RFC2307](http://www.ietf.org/rfc/rfc2307.txt)|[draft-ietf-ldapext-psearch-03.txt](http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-ldapext-psearch-03.txt) +---|---|---|---|--- +Apache|ApacheDS|1.0.x|![(tick)](assets/img/check.png)|![(tick)](assets/img/check.png) +Microsoft|Active Directory|Windows 2000, Windows 2003|![(warning)](assets/img/warning.png)|![(error)](assets/img/error.png) +Microsoft|Active Directory|Windows 2003 R2|![(tick)](assets/img/check.png)|![(error)](assets/img/error.png) +Sun|OpenDS|0.9.x|![(tick)](assets/img/check.png)|![(tick)](assets/img/check.png) +OpenLDAP|OpenLDAP|2.3.x, 2.4.x|![(tick)](assets/img/check.png)|![(error)](assets/img/error.png) + +![(warning)](assets/img/warning.png) LDAP v3 directory server which do not support [RFC2307](http://www.ietf.org/rfc/rfc2307.txt) by default. Support can be added by manually importing them. See vendor specific setup requirements on how to do this. +![(error)](assets/img/error.png) LDAP v3 directory servers which do not support the [draft-ietf-ldapext-psearch-03.txt](http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-ldapext-psearch-03.txt). + +LDAP Network Connector Properties +--------------------------------- + +Property|Default|Required|Description +---|---|---|--- +uri|null|**Yes**|The URI of the LDAP v3 Server to connect to (i.e. ldap://host:port, failover://(ldap://host1:port,ldap://host2:port). +base|null|**Yes**|The RDN base used as the root for the search criteria. +user|null|**Yes**, if not using anonymousAuthentication|The username needed to bind to the server. +password|null|**Yes**, if not using anonymousAuthentication|The password needed to bind to the server. +anonymousAuthentication|false|**Yes**, if not using user/password|Enable if you want to bind to the server anonymously. This is recommended over using user/password properties since your login credentials will not be stored in an unencrypted XML file. +searchEventListener|false|**No**|Enable if you want the broker to stay in sync with changes made to entries matching the search criteria. +searchScope|ONELEVEL_SCOPE|**No**|Can be any of search scopes defined by javax.naming.directory.SearchControls class. OBJECT_SCOPE - search the named object defined by base. ONELEVEL_SCOPE - search one level of the base. SUBTREE_SCOPE - search entire subtree rooted at the base. +searchFilter|(&(objectClass=ipHost)(objectClass=ipService))|**No**|Can be any filter that conforms to [RFC2254](http://www.ietf.org/rfc/rfc2254.txt). If a custom one is specified the actual search filter used will be (&(&(objectClass=ipHost)(objectClass=ipService))(USER CUSTOM)) + +> **Other Properties** +> +> All of the properties defined in [Networks of Brokers](http://activemq.apache.orgFeatures/Clustering/networks-of-brokers) are also available to the ldapNetworkConnector. Any of the properties defined for a normal networkConnector will be used as connection parameters to any discovered brokers matching the search criteria. + +Example 1: Simple Network of Brokers +------------------------------------ + +### Network Configuration + +Topology|LDAP v3 Directory Structure|Entry +---|---|--- +![](assets/img/Example1-Topology.jpg)|![](assets/img/Example1-DirectoryStructure.jpg)|![](assets/img/Example1-Entry.jpg) + +### ActiveMQ Classic Configuration (activemq.xml) + +**srv-a.mydomain.com** +``` + + ... + + + + + + ... + +``` + +**srv-b.mydomain.com** +``` + + ... + + + + + + ... + +``` + +Example 2: Larger Network of Brokers +------------------------------------ + +### Network Configuration + +Topology|LDAP v3 Directory Structure +---|--- +![](assets/img/Example2-Topology.jpg)|![](assets/img/Example2-DirectoryStructure.jpg) + +### ActiveMQ Classic Configuration (activemq.xml) + +**srv-a.mydomain.com** +``` + + ... + + + + + + + ... + +``` + +**srv-b.mydomain.com** +``` + + ... + + + + + + ... + +``` + +**srv-c.mydomain.com** +``` + + ... + + + + + + ... + +``` + +**srv-d.mydomain.com** +``` + + ... + + + + + + ... + +``` diff --git a/hugo/content/components/classic/documentation/load-testing-with-camel.md b/hugo/content/components/classic/documentation/load-testing-with-camel.md new file mode 100644 index 0000000000..353e049706 --- /dev/null +++ b/hugo/content/components/classic/documentation/load-testing-with-camel.md @@ -0,0 +1,20 @@ +--- +title: Load Testing with Camel +layout: classic-doc +--- + + + +Load Testing with Camel +----------------------- + +It is preferable at the time of writing to check out the source of ActiveMQ Classic and Camel and perform local builds first. + +Then run a broker either via the **bin/activemq** script or you could be untar/unzip the **assembly/target/apache-activemq**.tar.gz* file first then run its **bin/activemq** script. + +Now to run a load test type +``` +activemq/activemq-camel-loadtest> mvn test -Dtest=LocalBrokerParallelProducerLoadTest +``` +If you want to tinker with the configuration of ActiveMQ Classic and Camel then edit the LocalBrokerParallelProducerLoadTest-context.xml file. + diff --git a/hugo/content/components/classic/documentation/log4j-warn-no-appenders-could-be-found-for-logger.md b/hugo/content/components/classic/documentation/log4j-warn-no-appenders-could-be-found-for-logger.md new file mode 100644 index 0000000000..3f4a0a99bc --- /dev/null +++ b/hugo/content/components/classic/documentation/log4j-warn-no-appenders-could-be-found-for-logger.md @@ -0,0 +1,20 @@ +--- +title: log4j-WARN No appenders could be found for logger +layout: classic-doc +--- + + + +Error +----- +``` +log4j:WARN No appenders could be found for logger +(org.activemq.transport.tcp.TcpTransportChannel). +log4j:WARN Please initialize the log4j system properly. +``` + +Solution +-------- + +You have not initialised log4j properly. Try reading the [online log4j manual](http://logging.apache.org/log4j/docs/manual.html) or by adding a log4j.properties file to your classpath (to a directory which is on the classpath to be precise). + diff --git a/hugo/content/components/classic/documentation/masterslave.md b/hugo/content/components/classic/documentation/masterslave.md new file mode 100644 index 0000000000..9190948dde --- /dev/null +++ b/hugo/content/components/classic/documentation/masterslave.md @@ -0,0 +1,19 @@ +--- +title: MasterSlave +layout: classic-doc +--- + + [Features](features) > [Clustering](clustering) > [MasterSlave](masterslave) + +Introduction to Master / Slave +------------------------------ + +The following are the different kinds of Master/Slave configurations available: + +Master Slave Type|Requirements|Pros|Cons +---|---|---|--- +[Shared File System Master Slave](shared-file-system-master-slave)|A shared file system such as a SAN|Run as many slaves as required. Automatic recovery of old masters|Requires shared file system +[JDBC Master Slave](jdbc-master-slave)|A Shared database|Run as many slaves as required. Automatic recovery of old masters|Requires a shared database. Also relatively slow as it cannot use the high performance journal + +If you are using a shared network file system such as a SAN we recommend a [Shared File System Master Slave](shared-file-system-master-slave). If you are happy to dispense with the high performance journal and are using pure JDBC as your persistence engine then you should use [JDBC Master Slave](jdbc-master-slave) instead. + diff --git a/hugo/content/components/classic/documentation/maven2-activemq-broker-plugin.md b/hugo/content/components/classic/documentation/maven2-activemq-broker-plugin.md new file mode 100644 index 0000000000..9c8edbff29 --- /dev/null +++ b/hugo/content/components/classic/documentation/maven2-activemq-broker-plugin.md @@ -0,0 +1,93 @@ +--- +title: Maven2 ActiveMQ Classic Broker Plugin +layout: classic-doc +--- + + + +ActiveMQ Classic provides a Maven2 plugin to easily startup a JMS broker. It is useful to quickly boot up a message broker in your Maven2 project for debugging or for doing integration tests. + +###  How to Use + +> Be Careful +> +> The maven plugins in ActiveMQ Classic have been renamed in version 5.8.0+ to better follow the Maven plugin naming conventions. The ActiveMQ Classic Broker plugin has changed from 'maven-activemq-plugin' to 'activemq-maven-plugin'. + +> Replace the 5.7.0 version string with the version of your choosing, eg: 5.6.0, 5.8-SNAPSHOT + +In your Maven2 project, or using a minimal pom.xml like the following: +``` + + + 4.0.0 + com.acme + run-amq + 1.0-SNAPSHOT + +``` +just type: +``` +mvn org.apache.activemq.tooling:maven-activemq-plugin:5.1:run +``` +This will download the 5.7.0 version of the plugin, and spin up a broker using a simple configuration url of the form `broker:(tcp://localhost:61616)?useJmx=false&persistent=false`. The necessary ActiveMQ Classic jars will automatically be downloaded by Maven. + +To configure log4j, provide the `-Dlog4j.configuration=[file:///](file:///)` system property on the mvn command line. + +If you require a more advanced configuration with spring support, the jetty webconsole or with embedded camel you can add the plugin in your pom.xml and provide the required optional dependencies. For the default `conf/activemq.xml`, the following dependencies are required : +``` + + + + org.apache.activemq.tooling + maven-activemq-plugin + 5.7.0 + + xbean:file:../conf/activemq.xml + false + + + javax.net.ssl.keyStorePassword + password + + + org.apache.activemq.default.directory.prefix + ./target/ + + + + + + org.springframework + spring + 2.5.5 + + + org.mortbay.jetty + jetty-xbean + 6.1.11 + + + org.apache.camel + camel-activemq + 1.1.0 + + + + + +`` + and run it using: +``` +mvn activemq:run +``` + +###  Configuration Options + +Name|Default|Description +---|---|--- +configUri|broker:(tcp://localhost:61616)?useJmx=false&persistent=false|The broker configuration URI that will be use to startup the broker. For more information, refer [here](how-do-i-embed-a-broker-inside-a-connection) +fork|false|If true, start up the broker in a separate thread, enabling maven to continue processing (Useful for integration testing). +systemProperties|none|Additional system properties that will be set. + +**Note**: By default, the broker plugin will set activemq.base, activemq.home, org.apache.activemq.default.directory.prefix, derby.system.home to ./target/. This means that all data folders will be created there, hence will easily be deleted by running mvn clean. + diff --git a/hugo/content/components/classic/documentation/mdc-logging.md b/hugo/content/components/classic/documentation/mdc-logging.md new file mode 100644 index 0000000000..6e5b79d044 --- /dev/null +++ b/hugo/content/components/classic/documentation/mdc-logging.md @@ -0,0 +1,31 @@ +--- +title: MDC Logging +layout: classic-doc +--- + + + +ActiveMQ Classic uses [slf4j](http://www.slf4j.org/) as its logging framework. This allows ActiveMQ Classic to support [MDC logging](http://www.slf4j.org/api/org/slf4j/MDC.html). For more information about about MDC logging see the [logback manual](http://logback.qos.ch/manual/mdc.html). + +Currently ActiveMQ Classic adds three keys to the diagnostic context: + +Key|Description +---|--- +`activemq.broker`|Name of the broker logging event. +`activemq.connector`|Address of the connector which is serving the request. +`activemq.destination`|Name of the target destination of a message. + +For example, if you've defined a log appender to use the following `ConversionPattern`: +``` +log4j.appender.stdout.layout.ConversionPattern=%d [%-15.15t] - %-5p %-30.30c{1} - %-10.10X{activemq.broker} %-20.20X{activemq.connector} %-20.20X{activemq.destination} - %m%n +``` +then in an environment where multiple brokers use the same log (like unit tests), the log output will take this general form: +``` +2011-03-23 13:51:04,919 [127.0.0.1:58146] - TRACE Queue - broker-3B tcp://localhost:6111 - Message ID:dejan-bosanacs-macbook-pro.... +2011-03-23 13:51:04,935 [oker-3B] Task-1] - DEBUG Queue - broker-3B tcp://localhost:6111 PROD.FUSESOURCE.3.B - PROD.FUSESOURCE.3.B toPageIn: 1, Inflight... +2011-03-23 13:51:04,763 [oker-2A] Task-1] - TRACE AbstractStoreCursor - broker-2A vm://broker-2A PROD.FUSESOURCE.3.B - QueueStorePrefetch611939300 - fillBatch +2011-03-23 13:51:04,759 [127.0.0.1:58118] - TRACE Queue - broker-3A tcp://localhost:6110 - Message ID:dejan-bosanacs-macbook-pro.l... +2011-03-23 13:51:04,937 [oker-2A] Task-1] - TRACE NetworkBridgeFilter - broker-2A vm://broker-2A PROD.FUSESOURCE.3.B - Message all ready routed once through t... +2011-03-23 13:51:04,936 [oker-3B] Task-1] - TRACE AbstractStoreCursor - broker-3B tcp://localhost:6111 PROD.FUSESOURCE.3.B - QueueStorePrefetch2047424752 - fillBatch +2011-03-23 13:51:04,941 [oker-2A] Task-2] - DEBUG DemandForwardingBridgeSupport - broker-2A - bridging (broker-2A -> broker-1B, consu... +``` diff --git a/hugo/content/components/classic/documentation/message-cursors.md b/hugo/content/components/classic/documentation/message-cursors.md new file mode 100644 index 0000000000..64531f7db7 --- /dev/null +++ b/hugo/content/components/classic/documentation/message-cursors.md @@ -0,0 +1,107 @@ +--- +title: Message Cursors +layout: classic-doc +--- + + + +Message Cursors +--------------- + +A common problem in previous versions of ActiveMQ Classic was [running out of RAM buffer](my-producer-blocks) when using non-persistent messaging. + +Beginning with ActiveMQ Classic 5.0.0, there is a new memory model that allows messages to be paged in from storage when space is available (using Store cursors for persistent messages). + +Releases prior to 5.0 kept references in memory for all the messages that could be dispatched to an active Durable Topic Consumer or a Queue. While a reference itself is not large, it does impose a limit on the maximum number of messages that can be pending delivery. + +A typical approach for messaging systems dispatching persistent messages is to pull them in batches from long term storage when a client is ready to consume them, using a cursor to maintain the next to dispatch position. This is a robust and very scalable approach, but not the most performant for cases when the consumer(s) can keep up with the producer(s) of messages. + +ActiveMQ Classic 5.0 takes a hybrid approach, allowing messages to pass from producer to consumer directly (after the messages have been persisted), but switches back to using cursors if the consumer(s) fall behind. + +When Message Consumers are both active and fast - keeping up with the Message Producer + +![](assets/img/DispatchFastConsumers.png) + +If a Consumer becomes active after messages are pending from the store for it, or it's slower than the producer, then messages are paged in to the dispatch queue from a pending cursor: + +![](assets/img/DispatchSlowConsumers.png) + +### Types of Cursor + +The default message cursor type in ActiveMQ Classic 5.0 is Store based.  It behaves as above. There are two additional types of cursor that could be used: **VM Cursor** and **File based Cursor**, described below. + +#### VM Cursor + +The VM Cursor is how ActiveMQ Classic 4.x works: references to a message are held in memory, and passed to the dispatch queue when needed. This can be very fast, but also has the downside of not being able to handle very slow consumers or consumers that have been inactive for a long time: ![](/images/VMCursor.png) + +#### File based Cursor + +The File based Cursor is dervied from the VM Cursor.  When memory in the broker reaches its limit, it can page messages to temporary files on disk. This type of cursor can be used when the message store might be relatively slow, but consumers are generally fast. By buffering to disk, it allows the message broker to handle message bursts from producers without resorting to paging in from slow storage: + +![](assets/img/FileCursor.png) + +#### Paging for Non-Persistent Messages + +The store based cursor also handles cursors for non-persistent messages, which are not stored in the message store. Non-persistent messages are passed directly to the cursor, so the store based cursor embeds a file based cursor just for these types of messages: + +![](assets/img/NonPersistentMsgs.png) + +### Configuring Cursors + +By default, Store based cursors are used, but it is possible to configure different cursors depending on the destination. + +#### Topic subscribers + +For Topics there is a dispatch queue and pending cursor for every subscriber.  It's possible to configure different policies for durable subscribers and transient subscribers - e.g: +``` + + + + + + + + + + + + + + + + + + + + +``` + +Valid Subscriber types are **_vmCursor_** and **_fileCursor._** The default is the store based cursor. + +Valid Durable Subscriber cursor types are **_storeDurableSubscriberCursor_**, **_vmDurableCursor_** and **_fileDurableSubscriberCursor._** The default is the store based cursor + +#### Queues + +For Queues there is a single dispatch Queue and pending Queue for every destination, so configuration is slightly different: +``` + + + + + + + + + + + + + + +``` +Valid Queue cursor types are **_storeCursor_**, **_vmQueueCursor_** and **_fileQueueCursor._** The default is the store based cursor + +### See Also + +* [Producer Flow Control](producer-flow-control) + diff --git a/hugo/content/components/classic/documentation/message-groups.md b/hugo/content/components/classic/documentation/message-groups.md new file mode 100644 index 0000000000..1df6545bb3 --- /dev/null +++ b/hugo/content/components/classic/documentation/message-groups.md @@ -0,0 +1,176 @@ +--- +title: Message Groups +layout: classic-doc +--- + + + +Message Groups +-------------- + +Message Groups are an enhancement to the [Exclusive Consumer](exclusive-consumer) feature. They provide: + +* Guaranteed ordering of the processing of related messages across a single queue. +* Load balancing of the processing of messages across multiple consumers. +* High availability / auto-failover to other consumers if a JVM goes down. + +So logically Message Groups are like a parallel [Exclusive Consumer](exclusive-consumer). Rather than all messages going to a single consumer, the standard JMS header `JMSXGroupID` is used to define which _message group_ the message belongs to. The Message Group feature then ensures that all messages for the _same_ message group will be sent to the _same_ JMS consumer - whilst that consumer stays alive. As soon as the consumer dies another will be chosen. + +Another way of explaining Message Groups is that it provides sticky load balancing of messages across consumers; where the `JMSXGroupID` is kinda like a HTTP session ID or cookie value and the message broker is acting like a HTTP load balancer. + +### Example Use Case + +Lets say we are doing some kind of order matching system where people are buying and selling things (stocks, shares, placing online bets, whatever). You want to have consumers who match bids and offers for different items (stocks / bets) so they want to keep in RAM for performance a sub-set of the data set. Therefore set the `JMSXGroupID` to be `MSFT`, `IBM`, `SUNW` and so forth to use the stock symbol to define the message group. (It can be any string whatsoever; maybe combining trading book, trading exchange, date and so forth - the more specific the group ID, the more concurrent you can run). Assume we are buying and selling `MSFT`, `IBM`, `SUNW` shares; the Message Groups feature guarantees that all the `MSFT` messages will be processed in order by the same consumer; ditto for `IBM` and `SUNW`. + +### How Message Groups Work + +When a message is being dispatched to a consumer, the `JMSXGroupID` is checked. If one is present then the broker checks to see if a consumer owns that message group. Since there could be a large number of message groups hash buckets are used rather than the actual `JMSXGroupID` string. + +If no consumer is associated with a message group a consumer is chosen. Said JMS `MessageConsumer` will receive all further messages with the same `JMSXGroupID` value until: + +* the consumer closes (or the client which created the consumer dies etc). +* someone closes the message group by sending a message with a negative value for `JMSXGroupSeq` (see below for more details). + +**Note**: as with message selector matching, grouping based on `JMSXGroupID` occurs before dispatch on messages in memory. With the default `maxPageSize` option, large backlogs of messages destined for one group can block receipt of messages to other groups if they don't all fit in memory. You can change the default `maxPageSize` setting for destinations as follows: +``` + + + + + + + +``` + +### Using Message Groups + +You just need to change your JMS producers to fill in the `JMSXGroupID` message header with some `String` value of your choice. + +Example: +``` +Mesasge message = session.createTextMessage("hey"); +message.setStringProperty("JMSXGroupID", "IBM\_NASDAQ\_20/4/05"); +... +producer.send(message); +``` + +### Closing a Message Group + +You generally don't need to close a message group; just keep using it. However if you really do want to close a group you can add a negative sequence number. + +Example: +``` +Mesasge message = session.createTextMessage("hey"); +message.setStringProperty("JMSXGroupID", "IBM\_NASDAQ\_20/4/05"); +message.setIntProperty("JMSXGroupSeq", -1); +... +producer.send(message); +``` +This then _closes_ the message group so if another message is sent in the future with the same message group ID it will be reassigned to a new consumer. + +### Implications + +Message Groups mean you get the power of **grid** processing of messages across a cluster of consumers with reliability, auto-failover, load balancing but you can also order the processing of messages too. So its the best of both worlds. However using the above example, what Message Groups actually do is to partition your work load across consumers using a user definable partition strategy - the `JMSXGroupID` value. + +The neat thing about this is that you can do neat things like use lots of RAM caching; keep the order for `MSFT` in RAM in the `MSFT` consumer; keep the `IBM` orders in RAM in the `IBM` consumer - since the message broker is partitioning for you, you do not have to rely on a distributed cache with inter-cache synchronization and locking to take advantage of caching. + +The great thing is - to the application developer, it looks like a simple 1 consumer world where you process messages and do your job; leaving the broker to do all the hard stuff for you + +* partitioning the traffic +* load balancing of message groups across consumers +* auto-failover of groups to different consumers as consumers come and go + +In summary; if ordering or per-message caching and synchronization are in any way important to you then we highly recommend you use message groups to partition your traffic. + +### Getting Notified of Ownership Changes of Message Groups + +ActiveMQ Classic support a boolean header called `JMSXGroupFirstForConsumer`. This header is set on the first message sent to a consumer for a particular message group. + +If the JMS connection is using `failover:` and a temporary network error occurs so that the connection disconnects from the broker and reconnects some time later, a new consumer instance will be created under the covers of the JMS client leading to the possibility of another message with this header being set for the same message group. + +Example: +``` +String groupId = message.getStringProperty("JMSXGroupId"); + +if (message.getBooleanProperty("JMSXGroupFirstForConsumer")) { + // flush cache for groupId +} +``` +To flush caches to ensure consistent state when faced with network errors. + +### Adding New Consumers + +If you have existing messages in the broker and add consumers at a later stage, it is a good idea to delay message dispatch start until all consumers are present (or at least to give enough time for them to subscribe). If you don't do that the first consumer will probably acquire all message groups and all messages will be dispatched to it. You can achieve this by using `consumersBeforeDispatchStarts` and `timeBeforeDispatchStarts` [destination policies](per-destination-policies). + +When both **consumersBeforeDispatchStarts** and **timeBeforeDispatchStarts** are set to a value greater than zero, the dispatching will start as soon as the required number of consumers are present or the timeBeforeDispatchStarts timeout expires. If only consumersBeforeDispatchStarts is set then the timeout for consumers to connect is 1 second. If all consumers disconnect then message dispatch delay will be applied again at the next consumer connection. + +Here's the example of the destination policy that delays dispatch for `200ms`: +``` + + + + + + + +``` +The following code snippet shows how to wait for two consumers (or two seconds) before dispatch starts: +``` + + + + + + + +``` +As [the appropriate test case](https://github.com/apache/activemq/blob/master/activemq-unit-tests/src/test/java/org/apache/activemq/usecases/MessageGroupDelayedTest.java) shows, adding a small time pause before dispatching or setting a minimum consumer number, ensures equal message group distribution. + +If you need to rebalance the message groups manually for any reason you can do so by executing the `removeAllMessageGroups` operation on the JMX MBean of the corresponding queue. + +### Competing demands of memory consumption, load balancing, complexity, etc. + +The default behavior called `CachedMessageGroupMap` is limited to 1024 message groups in an LRU cache may not match you expectation w.r.t message order. `CachedMessageGroupMap` has bounded memory use, but only keeps track of up to 1024 (or the maximum configured size) groups, then loses track of any groups older than the newest 1024. In this way, if there are more groups than the maximum, **ordering will be lost for the oldest groups**. + +Typically users would close groups such that the in memory set can be retained below the configured limits. Some usefull discussion at [AMQ-6851](https://issues.apache.org/jira/browse/AMQ-6851) + +In order to prevent this limitation you can use `MessageGroupHashBucket` or `SimpleMessageGroupMap`. Their are working by associating each group with a consumer. + +`SimpleMessageGroupMap` keeps track of every group but suffers from unbounded memory use. + +The following code snippet shows how to enable it : + +``` + + + + + + + + + + + + +``` + +`MessageGroupHashBucked` keeps track of every group and has bounded memory use. The following code snippet shows how to enable it : + +``` + + + + + + + + + + + +``` + +### See + +* [How do Message Groups compare to Selectors](how-do-message-groups-compare-to-selectors) diff --git a/hugo/content/components/classic/documentation/message-transformation.md b/hugo/content/components/classic/documentation/message-transformation.md new file mode 100644 index 0000000000..1d3393ad9d --- /dev/null +++ b/hugo/content/components/classic/documentation/message-transformation.md @@ -0,0 +1,33 @@ +--- +title: Message Transformation +layout: classic-doc +--- + + + +Message Transformation +---------------------- + +It is sometimes useful to transform a message inside the JMS provider. For example you may have an application that has been live for some time that uses ObjectMessage messages, but that you wish to convert to use XML payloads (to protect yourself from serialization issues). + +So ActiveMQ Classic in 4.2 onwards comes with a pluggable strategy called the [MessageTransformer](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/MessageTransformer.html) interface. This allows you to + +* enrich or transform a message before it is sent to the message bus within the JMS provider +* enrich or transform a message as it is received from the message bus but before it is dispatched to the consumer + +So this allows you to turn an ObjectMessage into a TextMessage containing XML using some kind of XML marshalling technology like [XStream](http://xstream.codehaus.org/) or [JAXB2](http://java.sun.com/webservices/jaxb/). + +For example there is the **XStreamMessageTransformer** which when it is configured on a ConnectionFactory will cause all ObjectMessage instances to be silently transformed to and from TextMessage instances on the wire. This can be very useful if you have non-Java clients wishing to communicate with your Java messages. + +### Using a MessageTransformer + +To use a MessageTransformer you can install it on one of the following classes via the **setTransformer()** method + +* [ActiveMQConnectionFactory](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/ActiveMQConnection.html) +* [ActiveMQConnection](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/ActiveMQConnection.html) +* [ActiveMQSession](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/ActiveMQSession.html) +* [ActiveMQMessageConsumer](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/ActiveMQMessageConsumer.html) +* [ActiveMQMessageProducer](http://incubator.apache.org/activemq/maven/activemq-core/apidocs/org/apache/activemq/ActiveMQMessageProducer.html) + +The transformer is inherited on child objects; so you can install a particular transformer on a connection factory and it will be inherited on all connections, sessions, producers, consumers + diff --git a/hugo/content/components/classic/documentation/mirrored-queues.md b/hugo/content/components/classic/documentation/mirrored-queues.md new file mode 100644 index 0000000000..7d3a299360 --- /dev/null +++ b/hugo/content/components/classic/documentation/mirrored-queues.md @@ -0,0 +1,44 @@ +--- +title: Mirrored Queues +layout: classic-doc +--- + + + +Mirrored Queues +--------------- + +Queues provide an excellent reliable and high performance [load balancing mechanism](how-does-a-queue-compare-to-a-topic). Each message placed on a queue can only be successfully processed by a single consumer. This is a good thing! ![(smile)](https://cwiki.apache.org/confluence/s/en_GB/5997/6f42626d00e36f53fe51440403446ca61552e2a2.1/_/images/icons/emoticons/smile.png). However sometimes you want to monitor what messages flow between the producers and consumers on a queue. + +To do this you can use [Virtual Destinations](virtual-destinations) to setup a virtual Queue which forwards the message to multiple physical queues. However enabling this for every single queue in your system can be painful. + +So to make it easy to monitor queues, we have added a feature we call _Mirrored Queues_. Mirrored Queues are kinda like a zero-configuration [Wire Tap](http://activemq.apache.org/camel/wire-tap.html) on all of your queues inside your Message Broker. + +### Example + +For example imagine we have a number of producers sending to queue **Foo.Bar** and consumers consuming from queue **Foo.Bar** and we want to monitor or view activity. + +If you enable Mirrored Queues then by default you can subscribe to the topic **VirtualTopic.Mirror.Foo.Bar** and receive all the messages that are sent to the queue **Foo.Bar**. Since its a topic as many consumers can subscribe to this topic as are required. + +If you want you can use this feature with [Virtual Topics](virtual-destinations); so that you can define a logical consumer; say called A. Then you can subscribe to the queue **Consumer.A.VirtualTopic.Mirror.Foo.Bar** to receive all the messages sent to queue **Foo.Bar** for the consumer A. You can then run multiple instances of this consumer who can then load balance among each other. + +This combination of Mirrored Queues and [Virtual Destinations](virtual-destinations) can be extremely useful for monitoring transaction flows; for example with [Business Activity Monitoring (BAM)](http://activemq.apache.org/camel/bam.html). + +### How Mirrored Queues work + +When enabled, mirrored queues causes every message sent to a queue to also be sent to a topic of a similar name; so that folks who are interested in watching message exchanges on a queue can consume from the mirrored queue topic. + +When coupled with [Virtual Topics](virtual-destinations) on this topic as described in the above example, you can actually end up creating new queues which are mirrors of a given queue dynamically at runtime! + +### Enabling Mirrored Queues + +By default Mirrored Queues is disabled; as enabling it will cause a virtual topic to be created for each queue you use. + +To enable Mirrored Queues, set the **useMirroredQueues** property on [BrokerService](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/broker/BrokerService.html) or add the following inside the element in the [Xml Configuration](xml-configuration): +``` + + + +``` +This would make a topic named "*.qmirror" for each queue on your Broker. + diff --git a/hugo/content/components/classic/documentation/mom.md b/hugo/content/components/classic/documentation/mom.md new file mode 100644 index 0000000000..4f869b884e --- /dev/null +++ b/hugo/content/components/classic/documentation/mom.md @@ -0,0 +1,11 @@ +--- +title: MOM +layout: classic-doc +--- + + + +Message Orientated Middleware. The art of building distributed systems using mostly asynchronous message passing with loosely coupled services consuming and emitting messages. So this includes JMS providers and message brokers. + +Typically MOMs can handle any specific service instance being down for some time, so that they provide loose coupling across time, space, location, platform and language. + diff --git a/hugo/content/components/classic/documentation/mqtt.md b/hugo/content/components/classic/documentation/mqtt.md new file mode 100644 index 0000000000..e57e25be62 --- /dev/null +++ b/hugo/content/components/classic/documentation/mqtt.md @@ -0,0 +1,107 @@ +--- +title: MQTT +layout: classic-doc +--- + + + +ActiveMQ Classic supports the [MQTT](http://mqtt.org/) protocol and will automatically map between JMS/NMS and MQTT clients. MQTT is a machine-to-machine (M2M) publish/subscribe messaging transport. + +Please see the [MQTT site](http://mqtt.org/) for more details + +### Supported versions + +ActiveMQ Classic supports MQTT [v3.1.1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html) and [v3.1](https://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html). + +### Enabling the ActiveMQ Classic Broker for MQTT + +Its very easy to enable ActiveMQ Classic for MQTT. Just add a connector to the broker using the MQTT URL. +``` + + + +``` +### The MQTT Wire Format + +MQTT uses a compact binary format that can be configured with the following options.  All options can be configured on a Brokers transport bind URI. + +Parameter Name|Default Value|Description +---|---|--- +maxFrameSize|268435456|(v5.12.0) Maximum frame size that can be sent. The protocol limit is 256 megabytes and his value cannot be set higher. Can help help prevent OOM DOS attacks + +All options must be prepended with `wireFormat` in order to take effect. Without this proper formatting, the option will have zero effect. + +#### Example Wire Format Configuration +``` + +``` + +### Security + +The ActiveMQ Classic MQTT Transport implementation fully supports an [ActiveMQ Classic security](security) mechanism. Also, the authorization policies will be applied when you try to access (read/write) certain destinations. + +### Enabling MQTT over NIO + +For better scalability (and performance) you might want to run the MQTT protocol over NIO transport. To do that just use `mqtt+nio` transport prefix instead of `mqtt`. For example, add the following transport configuration in your XML file +``` + +``` + +This transport use [NIO transport](configuring-transports.md) underneath and will generally use much less threads than standard connector. + +### Enabling MQTT over NIO + SSL + +The MQTT transport also supports using NIO and SSL. To enable this option, use the mqtt+nio+ssl protocol - e.g. +``` + +``` + +* For more details on using SSL with ActiveMQ Classic see the following article ([How do I use SSL](how-do-i-use-ssl)). + +### Working with Destinations with MQTT + +MQTT supports hierarchies and wildcards, though the delimiters and characters are different: - Here's the mapping: + +function|ActiveMQ Classic|MQTT +---|---|--- +separator|`.`|`/` +element|`*`|`+` +sub tree|`>`|`#` + +These values are automatically transposed between clients using JMS/NMS/Stomp and clients using MQTTT. For example - a client subscribing to "foo/#/bar" would receive messages published on a JMS Topic of foo.blah.bar. + +### Message transformations + +MQTT messages are transformed into an JMS ByteMessage. Conversely, the body of any JMS Message is converted to a byte buffer to be the payload of an MQTT message. + +### Keep Alive + +When a client connects, it will send a keep-alive duration, usually defaulting to 10s. ActiveMQ Classic will honor the keep-alive duration by setting up an Inactivity Monitor that allows a grace period of 1.5 * duration. After that grace period duration elapses a connection could be closed if there is no activity. A broker receiving a PINGREQ and sending PINGRESP is considered activity to keep the connection opened. + +If a client sends a keep-alive value of 0, ActiveMQ Classic will not set up an [Inactivity Monitor](activemq-inactivitymonitor) and connections will not be auto-shutdown due to inactivity. This however can lead to potentially leaky connections, so a default keep alive can be set on the server side (by an admin, for example) to not allow inactive connections to hang. This default keep alive would only be used if specified and if the client requests a keep-alive value of 0. The unit for the keep-alive value is milliseconds. + +To enable a default, server-side MQTT keep alive: +``` + +``` + +### Message Prefetch + +When MQTT client connects, it locally create JMS-like consumer to the broker. In older versions this consumer was created with the prefetch size of 1 (message prefetching is explained [here](what-is-the-prefetch-limit-for) in more details). Starting with 5.11.0 release, the prefetch size is adjusted to the default value for the appropriate JMS subscription. QoS=0 subscriptions have default prefetch of regular non-persistent topic subscriptions, while QoS=1 and QoS=2 are assigned prefetch size of durable subscribers or the queue subscriptions depending on the subscription strategy used (see the next section for more details). Default prefetch values are listed [here](what-is-the-prefetch-limit-for). + +To change default value of the prefetch size, you can use _activeMQSubscriptionPrefetch_ transport option, like +``` + +``` + +### Subscription Strategy + +ActiveMQ Classic is a JMS broker in its core, so there needs to be some mapping between MQTT subscriptions and JMS semantics. Subscriptions with QoS=0 (At Most Once) are directly mapped to plain JMS non-persistent topics. For reliable messaging, QoS=1 and QoS=2, by default subscriptions are transformed to JMS durable topic subscribers. This behaviour is desired in most scenarios. For some use cases, it is useful to map these subscriptions to [virtual topics](virtual-destinations). Virtual topics provide a better scalability and are generally better solution if you want to use you MQTT subscribers over network of brokers. To change subscription strategy to use virtual topic, use the following settings: +``` + +``` + +### Retained Messages + +If a message has been published with the _retain_ flag set, then the message will be 'remembered' by the topic so that if a new subscription arrives, the last retained message is sent to the subscription. Underneath, the broker uses [retained message subscription recovery policy](subscription-recovery-policy) to retain messages with _ActiveMQ.Retain_ property set. During the message conversion, MQTT messages with retain flag become JMS message with the _ActiveMQ.Retain _property set and retained by the broker. + diff --git a/hugo/content/components/classic/documentation/multicast-watch-out-for-ipv6-vs-ipv4-support-on-your-operating-system-or-distribution-or-network.md b/hugo/content/components/classic/documentation/multicast-watch-out-for-ipv6-vs-ipv4-support-on-your-operating-system-or-distribution-or-network.md new file mode 100644 index 0000000000..f5e10e093f --- /dev/null +++ b/hugo/content/components/classic/documentation/multicast-watch-out-for-ipv6-vs-ipv4-support-on-your-operating-system-or-distribution-or-network.md @@ -0,0 +1,28 @@ +--- +title: Multicast - Watch out for IPV6 vs IPV4 support on your operating system or distribution or network +layout: classic-doc +--- + + + +You may wonder why you are not receiving any message at all during multicast, maybe you have just tried everything, and even on some other OS or distributions and JDK and realize that it works in some place and not on other... you may have tried a small C program to do the same..and it worked well.. you're feeling the pressure on your neck...what could be wrong on YOUR application on THIS OS/distribution... + +As a default, on the Linux platform, if you have IPV6 support enabled in your kernel, the Java Runtime (since 1.4 version) will use IPV6 sockets to communicate. That's perfectly fine, except that your network may not be configured for IPV6. So everything will be dropped...and nothing will ever be received on the consumer side (which maybe even does not support IPV6). + +There's a solution to this problem: Force IPV4 stack to be used by the Java Runtime. This can be done using a system property: +``` + -Djava.net.preferIPv4Stack=true +``` + +Networking IPv6 User Guide + +This information and much more details can be found in the Java Documentation [Networking IPv6 User Guide](http://java.sun.com/j2se/1.5.0/docs/guide/net/ipv6_guide/) and in [Networking Properties](http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html) + +Alternatively you can disable IPV6 support on your Linux machine by adding the following line **at the end of /etc/modprobe.conf** (_as its name suggests immediately, net-pf-10 is the IPV6 networking module_) +``` +alias net-pf-10 off # disable IPV6 +``` +If you have very knowledgeable sysadmins that are used to these problems (like in a TV or Radio company for instance where they use multicast a lot), they will be able to tell you immediately if IPV6 is supported on the network (alternatively they will be able to tell you as well if multicast is supported and on which address/port you can multicast), this is a plus and will help you tremendously. + +In some more frequent cases, your sysadmin will be as lost as you are as they are not dealing with these issues very frequently. So good luck for finding out problems. You will need to have a very strict approach to eliminate uncertainties. For this you will need at least a tool like [ethereal](http://www.ethereal.com) (works on unix, linux and windows) + diff --git a/hugo/content/components/classic/documentation/multiple-consumers-on-a-queue.md b/hugo/content/components/classic/documentation/multiple-consumers-on-a-queue.md new file mode 100644 index 0000000000..34beb90fd0 --- /dev/null +++ b/hugo/content/components/classic/documentation/multiple-consumers-on-a-queue.md @@ -0,0 +1,15 @@ +--- +title: Multiple consumers on a queue +layout: classic-doc +--- + + + +If you want to consume concurrently from a queue, then you must use a different session for each consumer. + +This is because you must have a session per thread. The JMS contract is that only 1 session is used by one thread at once - which if you're using consumers means that only 1 consumer can receive messages at once if using the same session. So if you want concurrent consumption of messages, you need to use different sessions for each consumer. + +However its your call on how many connections you have. In a normal network based mode, sharing the same connection across sessions will essentially multiplex traffic across a single socket (and so reduce resource usage at the cost of more synchronization). So sometimes there's a need to use more connections, as typically using different sockets concurrently tends to be a bit faster than using a single one). + +Incidentally in the JCA specifications in J2EE 1.4, Resource Adapters will typically create 1 connection for each session, so there's a 1-1 mapping between the two. + diff --git a/hugo/content/components/classic/documentation/my-producer-blocks.md b/hugo/content/components/classic/documentation/my-producer-blocks.md new file mode 100644 index 0000000000..2eef37716d --- /dev/null +++ b/hugo/content/components/classic/documentation/my-producer-blocks.md @@ -0,0 +1,31 @@ +--- +title: My producer blocks +layout: classic-doc +--- + + + +What can I do if my producer blocks sending a message? +------------------------------------------------------ + +This relates to [Producer Flow Control](producer-flow-control). + +### Active 4.x + +In ActiveMQ Classic 4.x, all in transit messages are held in memory. If you have a slow consumer, to avoid exausting the JVM memory and getting an out of memory error, ActiveMQ Classic has a configurable limit of how many in transit messages it will hold. Once it is reached, producers will be slowed down / blocked. + +A quick fix is just to bump up the setting in your **usageManager** in your [Xml Configuration](xml-configuration). The default that ships with ActiveMQ Classic is pretty low, only 20Mb of RAM, so try setting it to something large, say 512Mb. + +An alternative approach is to set individual usageManager limits on different destinations and for producers versus consumers. + +You might also want to use the [JMX](jmx) support or [Web Console](web-console) to look at what destinations are being used and what producers & consumers you have to see whats going on. + +### Active 5.x and Later + +As of 5.x of ActiveMQ Classic there is support for [Message Cursors](message-cursors) which by default move messages out of memory and onto disk. So this problem will not be seen unless you fill up the max allocated disk space for message storage which typically is an order of magnitude larger. + +### See Also + +* [Producer Flow Control](producer-flow-control) +* [Message Cursors](message-cursors) + diff --git a/hugo/content/components/classic/documentation/networks-of-brokers.md b/hugo/content/components/classic/documentation/networks-of-brokers.md new file mode 100644 index 0000000000..040b977c92 --- /dev/null +++ b/hugo/content/components/classic/documentation/networks-of-brokers.md @@ -0,0 +1,449 @@ +--- +title: Networks of Brokers +layout: classic-doc +--- + + + +To provide massive scalability of a large messaging fabric you typically want to allow many brokers to be connected together into a network so that you can have as many clients as you wish all logically connected together - and running as many message brokers as you need based on your number of clients and network topology. + +If you are using [client/server or hub/spoke style topology](topologies) then the broker you connect to becomes a single point of failure which is another reason for wanting a network (or cluster) of brokers so that you can survive failure of any particular broker, machine or subnet. + +From 1.1 onwards of ActiveMQ Classic supports _networks of brokers_ which allows us to support [distributed queues and topics](how-do-distributed-queues-work) across a network of brokers. + +This allows a client to connect to any broker in the network - and fail over to another broker if there is a failure - providing from the clients perspective a [HA](ha) cluster of brokers. + +**N.B.** By default a network connection is one way only - the broker that establishes the connection _passes messages to_ the broker(s) its connected to. From version 5.x of ActiveMQ Classic, a network connection can be optionally enabled to be duplex, which can be useful for hub and spoke architectures, where the hub is behind a firewall etc. + +Configuring a network of brokers +-------------------------------- + +The easiest way to configure a network of brokers is via the [Xml Configuration](xml-configuration). There are two main ways to create a network of brokers + +* use a hard coded list of networkConnector elements. + +* use Discovery to detect brokers (multicast or rendezvous). + +### Example with a fixed list of URIs + +Here is an example of using the fixed list of URIs +``` + + + + + + + + + + + + + + + + + + + +``` +ActiveMQ Classic also supports other transports than tcp to be used for the network connector such as http. + +### Example using multicast discovery + +This example uses [multicast discovery](discovery#multicast) +``` + + + + + + + + + + + + + + + + + + + +``` + +Starting network connectors +--------------------------- + +By default, network connectors are initiated serially as part of the broker start up sequence. When some networks are slow, they prevent other networks from starting in a timely manner. Version 5.5 supports the broker attribute networkConnectorStartAsync="true" which will cause the broker to use an executor to start network connectors in parallel, asynchronous to a broker start. + +Static discovery +---------------- + +With `static:` discovery you can hard code the list of broker URLs. A network connector will be created for each one. +``` + + + +``` +There are some useful properties you can set on a static network connector for retries: + +property|default|description +---|---|--- +initialReconnectDelay|1000|time(ms) to wait before attempting a reconnect (if useExponentialBackOff is false) +maxReconnectDelay|30000|time(ms) to wait before attempting to re-connect +useExponentialBackOff|true|increases time between reconnect for every failure in a reconnect sequence +backOffMultiplier|2|multipler used to increase the wait time if using exponential back off + +e.g. +``` +uri="static:(tcp://host1:61616,tcp://host2:61616)?maxReconnectDelay=5000&useExponentialBackOff=false" +``` + +MasterSlave Discovery +--------------------- + +A common configuration option for a network of brokers is to establish a network bridge between a broker and an n+1 broker pair (master/slave). Typical configurations involve using the `failover:` transport, but there are a some other non-intuitive options that must be configured for it to work as desired. For this reason, ActiveMQ Classic v5.6+ has a convenience discovery agent that can be specified with the `masterslave:` transport prefix: +``` + + + +``` +The URIs are listed in order for: MASTER,SLAVE1,SLAVE2...SLAVE![(thumbs down)](https://cwiki.apache.org/confluence/s/en_GB/5997/6f42626d00e36f53fe51440403446ca61552e2a2.1/_/images/icons/emoticons/thumbs_down.png) + +The same configuration options for `static:` are available for `masterslave:` + +NetworkConnector Properties +--------------------------- + +property|default|description +---|---|--- +name|bridge|name of the network - for more than one network connector between the same two brokers - use different names +dynamicOnly|false|if true, only activate a networked durable subscription when a corresponding durable subscription reactivates, by default they are activated on startup. +decreaseNetworkConsumerPriority|true|if true, starting at priority -5, decrease the priority for dispatching to a network Queue consumer the further away it is (in network hops) from the producer. When false all network consumers use same default priority(0) as local consumers (before v5.18.0 default=false) +networkTTL|1|the number of brokers in the network that messages and subscriptions can pass through (sets both message&consumer -TTL) +messageTTL|1|(version 5.9) the number of brokers in the network that messages can pass through +consumerTTL|1|(version 5.9) the number of brokers in the network that subscriptions can pass through (keep to 1 in a mesh) +conduitSubscriptions|true|multiple consumers subscribing to the same destination are treated as one consumer by the network +excludedDestinations|empty|destinations matching this list won't be forwarded across the network (this only applies to dynamicallyIncludedDestinations) +dynamicallyIncludedDestinations|empty|destinations that match this list **will** be forwarded across the network **n.b.** an empty list means all destinations not in the exluded list will be forwarded +useVirtualDestSubs|false|if true, the network connection will listen to advisory messages for virtual destination consumers +staticallyIncludedDestinations|empty|destinations that match will always be passed across the network - even if no consumers have ever registered an interest +duplex|false|if true, a network connection will be used to both produce **_AND_** Consume messages. This is useful for hub and spoke scenarios when the hub is behind a firewall etc. +prefetchSize|1000|Sets the [prefetch size](what-is-the-prefetch-limit-for) on the network connector's consumer. It must be > 0 because network consumers do not poll for messages +suppressDuplicateQueueSubscriptions|false|(from 5.3) if true, duplicate subscriptions in the network that arise from network intermediaries will be suppressed. For example, given brokers A,B and C, networked via multicast discovery. A consumer on A will give rise to a networked consumer on B and C. In addition, C will network to B (based on the network consumer from A) and B will network to C. When true, the network bridges between C and B (being duplicates of their existing network subscriptions to A) will be suppressed. Reducing the routing choices in this way provides determinism when producers or consumers migrate across the network as the potential for dead routes (stuck messages) are eliminated. networkTTL needs to match or exceed the broker count to require this intervention. +bridgeTempDestinations|true|Whether to broadcast advisory messages for created temp destinations in the network of brokers or not. Temp destinations are typically created for request-reply messages. Broadcasting the information about temp destinations is turned on by default so that consumers of a request-reply message can be connected to another broker in the network and still send back the reply on the temporary destination specified in the JMSReplyTo header. In an application scenario where most/all messages use request-reply pattern, this will generate additional traffic on the broker network as every message typically sets a unique JMSReplyTo address (which causes a new temp destination to be created and broadcasted via an advisory message in the network of brokers). When disabling this feature such network traffic can be reduced but then producer and consumers of a request-reply message need to be connected to the same broker. Remote consumers (i.e. connected via another broker in your network) won't be able to send the reply message but instead raise a "temp destination does not exist" exception. +alwaysSyncSend|false|(version 5.6) When true, non persistent messages are sent to the remote broker using request/reply in place of a oneway. This setting treats both persistent and non-persistent messages the same. +staticBridge|false|(version 5.6) If set to true, broker will not dynamically respond to new consumers. It will only use `staticallyIncludedDestinations` to create demand subscriptions +userName|null|The username to authenticate against the remote broker +password|null|The password for the username to authenticate against the remote broker + +#### Reliability + +Networks of brokers do reliable store and forward of messages. If the source is durable, persistent messages on a queue or a durable topic subscription, a network will retain the durability guarantee. +However networks cannot add durability when the source is non durable. Non durable topic subscriptions and temporary destinations (both queues and topics) are non durable by definition. When non durable +sources are networked, in the event of a failure, inflight messages can be lost. + +#### Ordering + +Total message ordering is not preserved with networks of brokers. Total ordering [works with a single consumer](how-do-i-preserve-order-of-messages) but a networkBridge introduces a second consumer. In addition, network bridge consumers forward messages via producer.send(..), so they go from the head of the queue on the forwarding broker to the tail of the queue on the target. If single consumer moves between networked brokers, total order may be preserved if all messages always follow the consumer but this can be difficult to guarantee with large message backlogs. + +#### When to use and not use Conduit subscriptions + +ActiveMQ Classic relies on information about active consumers (subscriptions) to pass messages around the network. A broker interprets a subscription from a remote (networked) broker in the same way as it would a subscription from a local client connection and routes a copy of any relevant message to each subscription. With Topic subscriptions and with more than one remote subscription, a remote broker would interpret each message copy as valid, so when it in turns routes the messages to its own local connections, duplicates would occur. Hence default conduit behavior consolidates all matching subscription information to prevent duplicates flowing around the network. With this default behaviour, N subscriptions on a remote broker look like a single subscription to the networked broker. + +However - duplicate subscriptions is a useful feature to exploit if you are only using Queues. As the load balancing algorithm will attempt to share message load evenly, consumers across a network will equally share the message load only if the flag `conduitSubscriptions=false`. Here's an example. Suppose you have two brokers, A and B, that are connected to one another via a forwarding bridge. Connected to broker A, you have a consumer that subscribes to a queue called `Q.TEST`. Connected to broker B, you have two consumers that also subscribe to `Q.TEST`. All consumers have equal priority. Then you start a producer on broker A that writes 30 messages to `Q.TEST`. By default, (`conduitSubscriptions=true`), 15 messages will be sent to the consumer on broker A and the resulting 15 messages will be sent to the two consumers on broker B. The message load has not been equally spread across all three consumers because, by default, broker A views the two subscriptions on broker B as one. If you had set `conduitSubscriptions` to `false`, then each of the three consumers would have been given 10 messages. + +#### Duplex network connectors + +By default a network bridge forwards messages on demand in one direction over a single connection. When `duplex=true`, the same connection is used for a network bridge in the opposite directions, resulting in a bi-directional bridge. The network bridge configuration is propagated to the other broker so the duplex bridge is an exact replica or the original. + + +Given two brokers, broker A and broker B, a duplex bridge on A to B is the same as a default bridge on A to B and a default bridge on B to A. + + +Note, if you want to configure more than one duplex network bridge between two brokers, to increase throughput or to partition topics and queues, you must provide unique names for each: +``` + + + + + + + + + + + + +``` + +#### Conduit subscriptions and consumer selectors + +Conduit subscriptions ignore consumer selectors on the local broker and send all messages to the remote one. Selectors are then parsed on the remote brokers before messages are dispatched to consumers. This concept could create some problems with consuming on queues using selectors in a multi-broker network. Imagine a situation when you have a producing broker forwarding messages to two receiving brokers and each of these two brokers have a consumer with different selector. Since no selectors are evaluated on the producer broker side, you can end up with all messages going to only one of the brokers, so messages with certain property will not be consumed. If you need to support this use case, please turn off `conduitSubscription` feature. + +#### Configuration Pitfalls + +> Networks do not work as expected (they cannot dynamically respond to new consumers) if the `advisorySupport` broker property is disabled. A fully statically configured network is the only option if `advisorySupport` is disabled. Read more about it in the following section. + +### Networks of brokers and advisories + +Network of brokers relies heavily on advisory messages, as they are used under the hood to express interest in new consumers on the remote end. By default, when network connector starts it defines one consumer on the following topic `ActiveMQ.Advisory.Consumer.>` (let's ignore temporary destination for the moment). In this way, when consumer connects (or disconnects) to the remote broker, the local broker will get notified and will treat it as one more consumer it had to deal with. + +This is all fine and well in small networks and environments whit small number of destinations and consumers. But as things starts to grow a default model (listen to everything, share everything) won't scale well. That's why there are many ways you can use to filter destinations that will be shared between brokers. + +#### Dynamic networks + +Let's start with dynamically configured networks. This means that we only want to send messages to the remote broker when there's a consumer there. If we want to limit this behavior only on certain destinations we will use `dynamicallyIncludedDestinations`, like +``` + + + + + + +``` +In versions of ActiveMQ Classic prior to 5.6, the broker would still use the same advisory filter and express interest in all consumers on the remote broker. The actual filtering will be done during message dispatch. This is suboptimal solution in huge networks as it creates a lot of "advisory" traffic and load on the brokers. Starting with version 5.6, the broker will automatically create an appropriate advisory filter and express interest only in dynamically included destinations. For our example it will be "`ActiveMQ.Advisory.Consumer.Queue.include.test.foo,ActiveMQ.Advisory.Consumer.Topic.include.test.bar`". This can dramatically improve behavior of the network in complex and high-load environments. + +In older broker versions we can achieve the same thing with a slightly more complicated configuration. The actual advisory filter that controls in which consumers we are interested is defined with the `destinationFilter` connector property. Its default value is ">", which is concatenated to the `"ActiveMQ.Advisory.Consumer."` prefix. So to achieve the same thing, we would need to do the following: +``` + + + + + + +``` +Note that first destination does not have the prefix because it's already implied. It's a bit more complicated to set and maintain, but it will work. And if you're using 5.6 or newer version of the broker just including desired destinations with `dynamicallyIncludedDestinations` should suffice. + +This also explains why dynamic networks do not work if you turn off advisory support on the brokers. The brokers in this case cannot dynamically respond to new consumers. + +#### Pure static networks + +If you wish to completely protect the broker from any influence of consumers on the remote broker, or if you wish to use the brokers as a simple proxy and forward all messages to the remote side no matter if there are consumers there or not, static networks are something you should consider. +``` + + + + + +``` +The `staticBridge` parameter is available since version 5.6 and it means that the local broker will not subscribe to any advisory topics on the remote broker, meaning it is not interested in whether there are any consumers there. Additionally, you need to add a list of destinations to `staticallyIncludedDestinations`. This will have the same effect as having an additional consumer on the destinations so messages will be forwarded to the remote broker as well. As there is no `staticBridge` parameter in the earlier versions of ActiveMQ Classic, you can trick the broker by setting `destinationFilter` to listen to an unused advisory topic, like +``` + + + + + +``` +If configured like this, broker will try to listen for new consumers on `ActiveMQ.Advisory.Consumer.NO_DESTINATION`, which will never have messages so it will be protected from information on remote broker consumers. + +### Dynamic networks and Virtual Destinations (New for 5.13.0) + +As described above, a network of brokers can be configured to only send messages to a remote broker when there's a consumer on an included destination.  However, let's consider some cases of how dynamic flow occurs when [Virtual Destinations](virtual-destinations) are in use. + +#### Virtual Destination consumers and Composite Destinations + +Here is an example of two brokers networked together.  The Local Broker contains the network connector configured with a `dynamicallyIncludedDestination` and the Remote Broker is configured with a CompositeTopic: + +**Local Broker** +``` + + + + + +``` + +**Remote Broker** +``` + + + + + +``` +In this example, let's consider a single consumer on the Remote Broker on the queue `include.bar.forward`.  If a message is sent directly to the Remote Broker on the topic `include.bar`, it will be forwarded to the queue `include.bar.forward` and the consumer will receive it.  However, if a message is published to the same topic on the Local Broker, this message will not be forwarded to the Remote Broker. + +The message is not forwarded because a consumer on the `queue include.bar.forward` would not be detected as part of the `dynamicallyIncludedDestinations` list in the Local Broker.  Messages would not be forwarded to the Remote Broker unless there was a consumer on the original topic as well (in this case `include.bar`).  This can be fixed by configuring the Local Broker to listen for Virtual Destination Subscriptions.   + +First, we need to configure the Remote Broker to send advisory messages when consumers subscribe to a destination that matches a Virtual Destination.  In this case, internally a match is determined through the use of a Destination Filter that determines whether one destination forwards to another destination.  To enable this, set the property `useVirtualDestSubs` on the Remote Broker to `true`: + +**Remote Broker** +``` + + + + + + ..... + + + +``` + +Next, the network connector on the Local Broker needs to be configured to listen for the new advisory messages by setting the `useVirtualDestSubs` property to `true`: + +**Local Broker** +``` + + + + + +``` +Now, if a consumer comes subscribes to the queue `include.bar.forward` on the Remote Broker, the Local Broker will forward messages that are sent to the topic `include.bar.` + +#### Virtual Destination Consumers on Destination Creation + +Now let's consider the use case above where there is the same composite topic but no consumers on the queue. +  +**Remote Broker** +``` + + + + + +``` +There is a Composite Topic configured on the Remote Broker, and the Local Broker is networked to it.   + +Even though we have enabled `useVirtualDestSubs`, messages will not be forwarded to the Remote Broker unless a consumer subscribes to the forwarded queue.  Without a consumer, messages would be dropped as they are sent to a topic on the Local Broker (`include.bar`).  In this situation it is desirable to have messages forwarded based on the existence of a virtual destination that forwards to: + +* one or more queues; or +* topics that have durable subscriptions. + +Both of these conditions are considered as emitting demand for messages to the Local Broker, despite there being no active consumers on those destinations. + +**Remote Broker** +``` + + + + + + ..... + + + +``` +With this configuration, when the queue `include.bar.forward` is created, a Virtual Destination consumer advisory will be sent to the Local Broker so that it knows to forward messages based on the existence of the Composite Topic that forwards to a queue. + +#### Composite Destination consumers and Virtual Topics  + +The above examples show how to configure a Composite Destination but a Virtual Topic will also work.  In the example below, a consumer on a queue for a Virtual Topic on the Remote Broker will now cause demand and messages will be sent across a network from the Local Broker. + +**Local Broker** +``` + + + + + +``` + +**Remote Broker** +``` + + + + + + ..... + + + +``` + +### Example Configuration using NetworkConnector properties + +This part of an example configuration for a Broker +``` + + + + + + + + + + + + + + + + +``` +Note that at the moment `excludedDestinations` property doesn't affect `staticallyIncludedDestinations`. + +It is possible to have more than one network connector between two brokers. Each network connector uses one underlying transport connection, so you may wish to do this to increase throughput, or have a more flexible configuration. + +For example, if using distributed queues, you may wish to have equivalent weighting to queue receivers across the network, but only when the receivers are active - e.g. +``` + + + + + + + +``` + +**N.B.** You can only use [wildcards](wildcards) in the `excludedDestinations` and `dynamicallyIncludedDestinations` properties. +**N.B.** **Do not** change the name of the bridge or the name of the Broker if you are using durable topic subscribers across the network. Internally ActiveMQ Classic uses the network name and broker name to build a unique but repeatable durable subscriber name for the network. + +### Stuck Messages + +There might have multiples cause for Stuck Message, sections below aim to give advice setting that may help to fix this issue. + +#### Disable replayWhenNoConsumers (version 5.6) +There is a destination policy that allows this behavior for queues by configuring a `conditionalNetworkBridgeFilterFactory` with `replayWhenNoConsumers=true`. The `conditionalNetworkBridgeFilterFactory` provides an optional `replayDelay` based on the broker-in time. +``` + + + + + +   + + + + + +``` + +**N.B.:** When using `replayWhenNoConsumers=true` for versions < 5.9, it is necessary to also disable the cursors duplicate detection using `enableAudit=false` as the cursor could mark the replayed messages as duplicates (depending on the time window between playing and replaying these messages over the network bridge). The problem is fully explained in this [blog post](http://tmielke.blogspot.de/2012/03/i-have-messages-on-queue-but-they-dont.html). + +#### Activate decreaseNetworkConsumerPriority + +Set decreaseNetworkConsumerPriority="true" in the networkConnector to limit the number of advisory and prefer local consumers. (more information on [AMQ-7316](https://issues.apache.org/jira/browse/AMQ-7316 ) + + + + + + +#### Increase prefetchsize if you're using Message Group and Consumer Pool + +If message group is enabled, one group might block the replication of a queue (if the size of message in this group is higher than the configured prefetchsize), providing a prefetchSize sufficient to ensure that all comsumers threads can consume their attributed group. + +#### Increase TTL + +TTL setting (networkTTL, messageTTL and consumerTTL) for the Network of Brokers should be high enough to allow messages exchange between the brokers several times in case the consumer +fails back and forth several times. + + +### Throttling a network consumer + +The `conditionalNetworkBridgeFilterFactory` factory allows a rate limit to be specified for a destination, such that network consumer can be throttled. Prefetch for a network consumer is largely negated by the fact that a network consumer relays a message typically acks very quickly so even with a low prefetch and decreased priority a network consumer can starve a modestly quick local consumer. Throttling provides a remedy for this. diff --git a/hugo/content/components/classic/documentation/new-features.md b/hugo/content/components/classic/documentation/new-features.md new file mode 100644 index 0000000000..5887522957 --- /dev/null +++ b/hugo/content/components/classic/documentation/new-features.md @@ -0,0 +1,19 @@ +--- +title: New Features in ActiveMQ +layout: classic-doc +--- + +This page documents the various new features added in each major release. + +- [New Features in 6.0](new-features-in-60) +- [New Features in 5.17](new-features-in-517) +- [New Features in 5.13](new-features-in-513) +- [New Features in 5.11](new-features-in-511) +- [New Features in 5.6](new-features-in-56) +- [New Features in 5.5](new-features-in-55) +- [New Features in 5.4](new-features-in-54) +- [New Features in 5.2](new-features-in-52) +- [New Features in 5.1](new-features-in-51) +- [New Features in 5.0](new-features-in-50) +- [New Features in 4.1](new-features-in-41) +- [New Features in 4.0](changes-in-40) diff --git a/hugo/content/components/classic/documentation/no-suitable-driver.md b/hugo/content/components/classic/documentation/no-suitable-driver.md new file mode 100644 index 0000000000..5b9f6344a8 --- /dev/null +++ b/hugo/content/components/classic/documentation/no-suitable-driver.md @@ -0,0 +1,21 @@ +--- +title: No suitable driver +layout: classic-doc +--- + + + +### Symptoms + +I get an exception saying **No suitable driver** when initialising the JDBC driver. + +### Reason + +ActiveMQ Classic tries to auto-detect the JDBC driver so that it can deduce the ultimate database's SQL dialect. Some JDBC drivers are not yet auto-recognised. Here's [how to configure the language adapater class to use or to provide us with details of your driver so we can add support for it to ActiveMQ Classic](jdbc-support). + +### See + +* [JDBC Support](jdbc-support) +* [Persistence](persistence) +* [How to configure a new database](how-to-configure-a-new-database) + diff --git a/hugo/content/components/classic/documentation/noclassdeffounderror-orgspringframeworkcoreioresource.md b/hugo/content/components/classic/documentation/noclassdeffounderror-orgspringframeworkcoreioresource.md new file mode 100644 index 0000000000..53b6a95d42 --- /dev/null +++ b/hugo/content/components/classic/documentation/noclassdeffounderror-orgspringframeworkcoreioresource.md @@ -0,0 +1,20 @@ +--- +title: NoClassDefFoundError - org.springframework.core.io.Resource +layout: classic-doc +--- + + + +If you get an exception like this +``` +java.lang.NoClassDefFoundError - org/springframework/core/io/Resource +``` + +### Cause + +You were probably trying to use the [XML Configuration](xml-configuration) mechanism, which uses Spring, but without having the Spring jar on your classpath. + +### Solution + +Add the Spring jar to your classpath. + diff --git a/hugo/content/components/classic/documentation/objectmessage.md b/hugo/content/components/classic/documentation/objectmessage.md new file mode 100644 index 0000000000..6c20a2df3b --- /dev/null +++ b/hugo/content/components/classic/documentation/objectmessage.md @@ -0,0 +1,75 @@ +--- +title: ObjectMessage +layout: classic-doc +--- + + + +Although ObjectMessage usage is generally discouraged, as it introduces coupling of class paths between producers and consumers, ActiveMQ Classic supports them as part of the JMS specification. + +Security +-------- + +ObjectMessage objects depend on Java serialization of marshal/unmarshal object payload. This process is generally considered unsafe as malicious payload can exploit the host system. That's why starting with versions **5.12.2** and **5.13.0**, ActiveMQ Classic enforces users to explicitly whitelist packages that can be exchanged using ObjectMessages. + +If you need to exchange object messages, you need to add packages your applications are using. You can do that with by using `org.apache.activemq.SERIALIZABLE_PACKAGES` system property, interpreted by the broker and the activemq client library. You can add this system property to `ACTIVEMQ_OPTS` variable in `${ACTIVEMQ_HOME}/bin/env` script. + +For example: +``` +-Dorg.apache.activemq.SERIALIZABLE_PACKAGES=java.lang,javax.security,java.util,org.apache.activemq,org.fusesource.hawtbuf,com.thoughtworks.xstream.mapper,com.mycompany.myapp +``` +will add `com.mycompany.myapp` package to the list of trusted packages. Note that other packages listed here are enabled by default as they are necessary for the regular broker work. In case you want to shortcut this mechanism, you can allow all packages to be trusted by using `*` wildcard, like +``` +-Dorg.apache.activemq.SERIALIZABLE_PACKAGES=* +``` +### Clients + +On the client side, you need to have this same mechanism as malicious code can be deserialized on `ObjectMessage.getObject()` call, compromising your application's environment. You can use the same configuration mechanism on the broker and configure trusted classes using system properties. However, this is usually not convenient in the client applications, so in **5.12.2** and **5.13.1** we introduced additional configuration mechanism using `ActiveMQConnectionFactory`. There are two additional methods defined: + +* The `setTrustedPackages()` method allows you to set the list of trusted packages you want to be to unserialize, like +```java +ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); +factory.setTrustedPackages(new ArrayList(Arrays.asList("org.apache.activemq.test,org.apache.camel.test".split(",")))); +``` +* The `setTrustAllPackages()` allows you to turn off security check and trust all classes. It's useful for testing purposes. +```java +ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); +factory.setTrustAllPackages(true); +``` +You can set the same properties in Camel context like: + +```xml + + + + + org.apache.activemq.test + org.apache.camel.test + + + + + + + + + +``` + +or + +```xml + + + + + + + + + + +``` + +This configuration will override system properties if they are set. + diff --git a/hugo/content/components/classic/documentation/onmessage-method-of-messagelistener-is-never-called.md b/hugo/content/components/classic/documentation/onmessage-method-of-messagelistener-is-never-called.md new file mode 100644 index 0000000000..53795392ab --- /dev/null +++ b/hugo/content/components/classic/documentation/onmessage-method-of-messagelistener-is-never-called.md @@ -0,0 +1,9 @@ +--- +title: onMessage method of MessageListener is never called +layout: classic-doc +--- + + + +See [I am not receiving any messages, what is wrong](i-am-not-receiving-any-messages-what-is-wrong) + diff --git a/hugo/content/components/classic/documentation/openwire.md b/hugo/content/components/classic/documentation/openwire.md new file mode 100644 index 0000000000..1f326e31f6 --- /dev/null +++ b/hugo/content/components/classic/documentation/openwire.md @@ -0,0 +1,28 @@ +--- +title: OpenWire +layout: classic-doc +--- + + + +OpenWire is our cross language [Wire Protocol](wire-protocol) to allow native access to ActiveMQ Classic from a number of different languages and platforms. The Java OpenWire transport is the default transport in ActiveMQ Classic 4.x or later. For other languages see the following... + +* [NMS](components/nms/) for the C# API to Messaging and the OpenWire implementation in C# +* [CMS](components/cms) for the C++ API to Messaging and the OpenWire implementation in C++ + +**Note** that you can also use [Stomp](stomp) to access ActiveMQ Classic from many different languages as well as use [GCJ](how-do-i-access-activemq-classic-from-c) or [IKVM](http://activemq.apache.org/nms/) to access the Java code for ActiveMQ Classic from C/C++ or .Net respectively without using OpenWire. + +### How it works + +OpenWire works by code generating language specific commands and marshaling code which understands the core OpenWire protocol. Then we can write language specific extensions for the low level protocol to provide a nice and easy to use client API in different languages. + +To give you an idea, [here](https://github.com/apache/activemq/tree/main/activemq-openwire-generator/src/main/java/org/apache/activemq/openwire/tool/) are the Java classes which code generate the C#, Java, C, and CPP client code. + +Since OpenWire automates the creation of language specific [Wire Protocol](wire-protocol) implementations; then its a matter of wrapping the language specific TCP/IP socket code and wrapping the API in some easy to use functions/classes. + +### Specification + +For a detailed specification of what you will see on the wire: + +* [OpenWire Version 2 Specification](openwire-version-2-specification) + diff --git a/hugo/content/components/classic/documentation/optimized-acknowledgement.md b/hugo/content/components/classic/documentation/optimized-acknowledgement.md new file mode 100644 index 0000000000..6cf748607b --- /dev/null +++ b/hugo/content/components/classic/documentation/optimized-acknowledgement.md @@ -0,0 +1,31 @@ +--- +title: Optimized Acknowledgement +layout: classic-doc +--- + + + +Overview +-------- + +ActiveMQ Classic supports acknowledging a range of messages in a single batch operations. This option is disabled by default but can be used to improve throughput in some circumstances as it decreases load on the broker. Consider enabling it for your performance test scenario to see if it is applicable. + +### Enabling Optimized Acknowledgements using a Connection URI +``` +cf = new ActiveMQConnectionFactory("tcp://locahost:61616?jms.optimizeAcknowledge=true"); +``` + +### Enabling Optimized Acknowledgements at the ConnectionFactory Level +``` +((ActiveMQConnectionFactory)connectionFactory).setOptimizeAcknowledge(true); +``` + +### Enabling Optimized Acknowledgements at the Connection Level +``` +((ActiveMQConnection)connection).setOptimizeAcknowledge(true); +``` + +### setOptimizeAcknowledgeTimeOut (5.6) + +Since 5.4.2 there is a default timeout on a batch optimized acknowledge which ensures that acks are timely even if consumers are slow. On slow networks, the timeout can expire before the batch limit is reached so the reduced bandwith utilisation is bypassed. In version 5.6, the timeout is configurable via the optimizeAcknowledgeTimeOut attribute. Set as above via the connectiion URI or at the factory and connection level. The default value is 300ms, a value of 0 disables. + diff --git a/hugo/content/components/classic/documentation/osgi-integration.md b/hugo/content/components/classic/documentation/osgi-integration.md new file mode 100644 index 0000000000..19a67efc5f --- /dev/null +++ b/hugo/content/components/classic/documentation/osgi-integration.md @@ -0,0 +1,113 @@ +--- +title: OSGi Integration +layout: classic-doc +--- + + + +Introduction +============ + +This article will provide more details on how to use ActiveMQ Classic in [Apache Karaf](http://karaf.apache.org/), small OSGi based runtime. Apache Karaf was previously know as _ServiceMix kernel_, so informations found here are applicable to [Apache ServiceMix Enterprise Service Bus](http://servicemix.apache.org/home.html) as well. + +> Procedures described in this article were tested using Apache karaf 2.3.0 + +Installation +============ + +ActiveMQ Classic provides Karaf features which will help you integrate and use the broker in OSGi environment. For starters you need to add the features URL to Karaf. For version 5.9.0 you can do it like this: +``` +karaf@root> features:chooseurl activemq 5.9.0 +``` +After that you should see newly added features +``` +karaf@root> features:list +State Version Name Repository +\[uninstalled\] \[5.9.0 \] activemq-broker activemq-5.9.0 +\[uninstalled\] \[5.9.0 \] activemq-http activemq-5.9.0 +\[uninstalled\] \[5.9.0 \] activemq-camel activemq-5.9.0 +\[uninstalled\] \[5.9.0 \] activemq-web-console activemq-5.9.0 +``` +Installing and running the broker is as simple as installing `activemq-broker` feature, like +``` +karaf@root> features:install activemq-broker +``` +This will install and start the full broker (including the web console), just as if you started the standalone distribution. + +Broker Configuration +==================== + +Broker is configured using OSGi Config Admin mechanism and could be easily managed in [Karaf](http://karaf.apache.org/manual/latest-2.3.x/users-guideCommunity/FAQ/configuration). Configuration can be done by modifying `${KARAF_BASE}/etc/org.apache.activemq.server-default.cfg` file or respective config admin property. An example of the file looks like +``` +broker-name=amq-broker +data=${karaf.data}/${broker-name} +config=${karaf.base}/etc/activemq.xml +``` +Mandatory properties are listed in the following table + +Property Name|Property Description +---|--- +broker-name|Name of the broker +config|Location of the XML configuration file + +You can also use this file to set other properties which will replace placeholders in XML configuration file, as the `${data`} property is used in this example. + +Default XML configuration file is located in the `${KARAF_BASE}/etc/activemq.xml` by default. + +Web Console +=========== + +Web Console is installed by default and can be reached at [http://localhost:8181/activemqweb/](http://localhost:8181/activemqweb/) + +The configuration for the console is done in a similar fashion to the broker itself. Configuration is located in `${KARAF_BASE}/etc/org.apache.activemq.webconsole.cfg` and by default looks like +``` +webconsole.jms.url=tcp://localhost:61616 +webconsole.jmx.url=service:jmx:rmi:///jndi/rmi://localhost:1099/karaf-root +webconsole.jmx.user=karaf +webconsole.jmx.password=karaf +``` +**Optional:** In order to use the ActiveMQ Classic console with a broker configured with authentication, it is necessary to configure the username/password for JMS connection as well. +``` +webconsole.jms.user=system +webconsole.jms.password=manager +``` + +Commands +======== + +After these simple steps you have all necessary libraries installed in the container. Also, now you have specific commands on your disposal that you can use to manage your broker: +``` +browse Display selected messages in a specified destination +bstat Displays useful broker statistics +list Lists all available brokers in the specified JMX context +purge Delete selected destination's messages that matches the message selector +query Display selected broker component's attributes and statistics +dstat Performs a predefined query that displays useful tabular statistics regarding the specified destination type  +``` + +> Help on commands +> +> To obtain some detailed help on a given command, you can run: +> +> ``` +> activemq:[command] --help +> ``` + +Broker querying +--------------- + +Several commands are available to query the broker. To address local brokers, you need to use the `--jmxlocal` parameter. + +The following command displays available brokers: +``` +karaf@root> activemq:list --jmxlocal +BrokerName = mybroker +``` +To have more detailed informations, run: +``` +karaf@root> activemq:query --jmxlocal +``` +It will display informations about the connectors, list of queues, etc... + +You can also browse or purge queues using the `activemq:browse` and `activemq:purge` commands. + diff --git a/hugo/content/components/classic/documentation/overview.md b/hugo/content/components/classic/documentation/overview.md new file mode 100644 index 0000000000..30e7a134ea --- /dev/null +++ b/hugo/content/components/classic/documentation/overview.md @@ -0,0 +1,7 @@ +--- +title: Overview +layout: classic-doc +--- + +- [Download](../../download/) +- [Download Archives](download-archives) diff --git a/hugo/content/components/classic/documentation/per-destination-policies.md b/hugo/content/components/classic/documentation/per-destination-policies.md new file mode 100644 index 0000000000..33536c3b35 --- /dev/null +++ b/hugo/content/components/classic/documentation/per-destination-policies.md @@ -0,0 +1,127 @@ +--- +title: Per Destination Policies +layout: classic-doc +--- + + [Features](features) > [Destination Features](destination-features) > [Per Destination Policies](per-destination-policies) + +Multiple different policies can be applied per destination (queue or topic), or using wildcard notation to apply to a hierarchy of queues or topics, making it possible, therefore, to configure how different regions of the JMS destination space are handled. + +The following properties can be applied to either topics and/or queues: + +Common Property|Default|Description +---|---|--- +`advisoryForConsumed`|`false`|Send an advisory message when a message is consumed by a client. +`advisoryForDelivery`|`false`|Send an advisory message when a message is sent to a client. +`advisoryForFastProducers`|`false`|Send an advisory message if a producer is deemed fast. +`advisoryForSlowConsumers`|`false`|Send an advisory message if a consumer is deemed slow. +`advisoryWhenFull`|`false`|Send an advisory message when a limit (memory, store, temp disk) is full. +`enableAudit`|`true`|When `true` the broker will track duplicate messages. Duplicates can happen for non-persistent messages during failover. +`gcInactiveDestinations`|`false`|Garbage collect inactive destinations. +`inactiveTimoutBeforeGC`|`5000`|The timeout (in ms) after which a destination is considered inactive. +`includeBodyForAdvisory`|`false`|Includes the body of the original message that triggered the advisory as part of the `dataStructure` field in the advisory message (where applicable). Normally the message body is cleared. +`maxBrowsePageSize`|`400`|The maximum number of messages to page in from the store at one time for a browser. +`maxDestinations`|`-1`|(v5.12) If `>= 0`, sets the maximum number of destinations that can be created. This parameter is intended to limit the number of hierarchical destinations that can be created under a wildcard destination. +`maxPageSize`|`200`|The maximum number of messages to page in from the store at one time. Increase this value to improve performance for queue destination's that contain grouped messages that are consumed by multiple concurrent consumers. +`memoryLimit`|`n/a`|The memory limit (in bytes) of the destination's cursor. This memory limit is subordinate to the system level memory limit, as specified by the [`/`](producer-flow-control) attribute. There is no default for this value; it simply acts as a child to the overall broker memory until the broker memory is exhausted. **Note**: when this limit is specified the destination's `cursorMemoryHighWaterMark` will be applied against it and not the `/>` memory limit. +`minimumMessageSize`|`1024`|For non-serialized messages (embedded broker) - the assumed size of the message used for memory usage calculation. Serialized messages use the serialized size as the basis for the memory calculation. +`prioritizedMessages`|`false`|Persist message priority information. +`producerFlowControl`|`true`|If `true` the broker will throttle (flow-control) the producer. Throttling is achieved either by withholding the producer's ACK or by raising a `javax.jms.ResourceAllocationException` (that's propagated back to the client) when local resources, e.g., memory and/or storage, have been exhausted. If `false` excess messages will be written to the message store to prevent memory exhaustion. However, when the message store reaches capacity the producer will be throttled until resources are freed. +`slowConsumerStrategy`|`null`|Sets the strategy for handling slow consumers. See [AbortSlowConsumerStrategy.](https://github.com/apache/activemq/blob/master/activemq-broker/src/main/java/org/apache/activemq/broker/region/policy/AbortSlowConsumerStrategy.java) +`storeUsageHighWaterMark`|`100`|The percentage (%) threshold of the `/` store limit which when exceeded causes a producer send to block. +`useCache`|`true`|If `true` persistent messages are cached for fast retrieval from store. +`usePrefetchExtension` |`true`|The prefetch extension is used when a message is delivered but not ACK'ed, such that the broker can dispatch another message, e.g., `prefetch == 0`, the idea being that there will always be prefetch number of messages pending. It also allows a transaction batch to exceed the prefetch value. +`sendDuplicateFromStoreToDLQ` |`false`|(v5.17.0) If `true`, will send a copy of message to DLQ when duplicateFromStore condition is detected. Before v5.17.0, the default behavior was `true` +`sendFailIfNoSpace`|`false`|(v5.16.0) If `true`, will cause a send to fail with a `javax.jms.ResourceAllocationException` when the destination has reached is resource limits (memory or storage) +`sendFailIfNoSpaceAfterTimeout`|`0`|(v5.16.0) If `> 0`, will cause a send to fail with a `javax.jms.ResourceAllocationException` when the destination resource limits (memory or storage) remain exhausted for the configured duration in milliseconds + +The following properties can be applied _only_ to a queue: + +Queue Only Property|Default|Description +---|---|--- +`allConsumersExclusiveByDefault`|`false`|When `true` all consumers will be exclusive. See [Exclusive Consumers](exclusive-consumer) +`cursorMemoryHighWaterMark`|`70`|The percentage (%) threshold applied either to the `/` or the destination's `memoryLimit` (when defined) which when exceeded will cause the destination's cursor to either block or write to disk. +`consumersBeforeDispatchStarts`|`0`|When the first consumer connects, wait for specified number of consumers before message dispatching starts. +`expireMessagesPeriod`|`30000`|The period (in ms) of checks for message expiry on queued messages. A value of `0` will disable expiration checking. +`lazyDispatch`|`false`|Only page in from store the number of messages that can be dispatched at time. +`maxExpirePageSize`|`400`|The maximum number of messages to page in when periodically expiring messages. Messages are paged in according to this setting if the number of messages in memory pending dispatch is less than this value, and there are messages in the store to page in. Messages are expired during this paging step as they are brought into memory from the store. Once the paging process is completed, messages are expired from the list of those that are in memory and pending dispatch, then from the list of those that are in memory but not yet targeted at a subscription. +`optimizedDispatch`|`false`|Don't use a separate thread for dispatching from a Queue. +`persistJMSRedelivered`|`false`|(v 5.10) If true, before a persistent message is dispatched by the broker for the first time, the message is rewritten to reflect the possible delivery. This ensures the message `JMSRedelivered` header is a reliable indication of possible duplicate delivery. +`queuePrefetch`|`n/a`|Sets the prefetch for consumers that are using the default value. +`strictOrderDispatch`|`false`|If `true` queue will not round robin consumers, but it'll use a single one until its prefetch buffer is full. +`timeBeforeDispatchStarts`|`0`|When the first consumer connects, wait for specified time (in ms) before message dispatching starts. +`useConsumerPriority`|`true`|Use the priority of a consumer when dispatching messages from a Queue. + +The following properties can be applied _only_ to a topic: + +Topic Only Property|Default|Description +---|---|--- +`advisoryForDiscardingMessages`|`false`|Send an advisory when a message is discarded from a non durable subscription. +`cursorMemoryHighWaterMark`|`70`|The percentage (%) threshold applied to the `/` which when exceeded will cause the destination's cursor to either block or write to disk. +`alwaysRetroactive` |`false`|Makes all subscribers retroactive negating the need to modify the clients to enable this feature. +`durableTopicPrefetch`|`n/a`|Sets the prefetch for durable topic consumers that are using the default value. +`expireMessagesPeriod` |`30000`|The interval (in ms) between message expiration checks on inactive durable subscribers. **Note**: set to `0` to disable message expiration checking. +`topicPrefetch`|`n/a`|Sets the prefetch for topic consumers that are using the default value. + +The following are examples of different policies that can be customized on a per destination basis: + +* [Dispatch Policies](dispatch-policies) + +An example from the demos [https://git-wip-us.apache.org/repos/asf?p=activemq.git;a=blob;f=assembly/src/release/examples/conf/activemq-demo.xml;hb=HEAD](https://git-wip-us.apache.org/repos/asf?p=activemq.git;a=blob;f=assembly/src/release/examples/conf/activemq-demo.xml;hb=HEAD):  + +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` diff --git a/hugo/content/components/classic/documentation/persistence.md b/hugo/content/components/classic/documentation/persistence.md new file mode 100644 index 0000000000..368b26c7a9 --- /dev/null +++ b/hugo/content/components/classic/documentation/persistence.md @@ -0,0 +1,155 @@ +--- +title: Persistence +layout: classic-doc +--- + + +ActiveMQ Classic V5.14.2 / V5.17.0 +------------- + +ActiveMQ Classic 5.14.2 was the first release after the deprecation announcement of LevelDB. The implementation was removed in 5.17.0. +We once again recommend you use [KahaDB](kahadb). + +ActiveMQ Classic V5.9 +------------- + +In ActiveMQ Classic 5.9, the [Replicated LevelDB Store](replicated-leveldb-store) was introduced. It handles using [Apache ZooKeeper](http://zookeeper.apache.org/) to pick a master from a set of broker nodes configured to replicate single LevelDB Store. Then synchronizes all slave LevelDB Stores with the master keeps them up to date by replicating all updates to the master. It may have become the preferred [Master Slave](masterslave) configuration going forward. + +ActiveMQ Classic V5.8 +------------- + +In ActiveMQ Classic 5.8, the [LevelDB Store](leveldb-store) was introduced. The LevelDB Store is a file based persistence database. It has been optimized to provide even faster persistence than KahaDB. Although not yet the default message store, we expect this store implementation become the default in future releases. + +ActiveMQ Classic V5.3 +------------- + +From 5.3 onwards - we recommend you use [KahaDB](kahadb) - which offers improved scalability and recoverability over the [AMQ Message Store](amq-message-store). +The [AMQ Message Store](amq-message-store) which although faster than [KahaDB](kahadb) - does not scales as well as [KahaDB](kahadb) and recovery times take longer. + +ActiveMQ Classic V4 +----------- + +For long term persistence we recommend using JDBC coupled with our high performance journal. You can use just JDBC if you wish but its quite slow. + +Our out of the box default configuration uses [Apache Derby](http://incubator.apache.org/derby/) as the default database, which is easy to embed - but we support all the [major SQL databases](jdbc-support) \- just reconfigure your JDBC configuration in the [Xml Configuration](xml-configuration). + +High performance journal - ActiveMQ Classic 4.x +--------------------------------------- + +To achieve high performance of durable messaging in ActiveMQ Classic V4.x we strongly recommend you use our high performance journal - which is enabled by default. This works rather like a database; messages (and transcation commits/rollbacks and message acknowledgements) are written to the journal as fast as is humanly possible - then at intervals we checkpoint the journal to the long term persistence storage (in this case JDBC). + +Its common when using queues for example that messages are consumed fairly shortly after being published; so you could publish 10,000 messages and only have a few messages outstanding - so when we checkpoint to the JDBC database, we often have only a small amount of messages to actually write to JDBC. Even if we have to write all the messages to the JDBC, we still get performance gains with the journal, since we can use a large transaction batch to insert the messages into the JDBC database to boost performance on the JDBC side. + +Our journal is based on lots of the great work in the [Howl](http://howl.objectweb.org/) project; we keep close ties to the Howl community. However since ActiveMQ Classic has to handle arbitarily large message sizes, we've had to make our journal handle any size of message and so we don't use the fixed size record model that Howl uses. + +Configuring persistence +----------------------- + +For full explict control over configuration check out the [Xml Configuration](xml-configuration). However a quick way to set which persistence adapter to use is to set the following system property to be the class name of the PersistenceAdapter implementation. + +activemq.persistenceAdapter + +When running the broker from the command line, we look for the activemq.xml on the classpath unless you specify one to use. e.g. +**AMQ 4.x** +``` +activemq xbean:file:myconfig.xml +``` +**AMQ 3.x** +``` +activemq myconfig.xml +``` +or just +**AMQ3.x/AMQ4.x** +``` +activemq +``` +Here is a sample XML configuration which shows how to configure the journal and the JDBC persistence. + +AMQ 5.x + +```xml + + + + + + + + + + + + + + + + + + +``` + +For more details see the [Initial Configuration](initial-configuration) guide. + +JDBC Persistence without Journaling +----------------------------------- + +To enable JDBC persistence of JMS messages without journaling, we need to change the message broker's default persistence configuration from +**AMQ 4.x** +```xml + + + +``` +to +```xml + + + +``` +**For AMQ 3.x** +```xml + + + + + +``` +to +```xml + + + +``` +Make sure to send durable messages so that it will be persisted in the database server while waiting to be consumed by clients. More information on configuration JDBC persistence at [JDBC Support](jdbc-support) + +[Kaha Persistence](kaha-persistence) + +Disaster Recovery options +------------------------- + +For people with high [DR](dr) requirements we have various options for providing a [Replicated Message Store](replicated-message-store) to allow full failover in times of major data centre failure. + +Disabling Persistence +--------------------- + +If you don't want persistence at all you can disable it easily via the [Xml Configuration](xml-configuration). e.g. +```xml + +``` +This will make the broker use the [](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/store/memory/MemoryPersistenceAdapter.html) +For an example of using a configuration URI see [How To Unit Test JMS Code](how-to-unit-test-jms-code) + diff --git a/hugo/content/components/classic/documentation/pluggable-storage-lockers.md b/hugo/content/components/classic/documentation/pluggable-storage-lockers.md new file mode 100644 index 0000000000..c3b72e35c0 --- /dev/null +++ b/hugo/content/components/classic/documentation/pluggable-storage-lockers.md @@ -0,0 +1,131 @@ +--- +title: Pluggable storage lockers +layout: classic-doc +--- + + [Features](features) > [Persistence](persistence) > [Pluggable storage lockers](pluggable-storage-lockers) + +As of the 5.7.0 release of ActiveMQ Classic the choice of storage locking mechanism, as used by a persistence adapter, has been made pluggable. This feature is only meaningful to brokers configured in a shared storage master/slave topology. Prior to release 5.7.0 the storage locking mechanism (and thus master election) was dictated by the choice of persistence adapter. With the KahaDB persistence adapter, for example, the storage locking mechanism was based on a shared file lock. Similarly, the JDBC persistence adapter used a database backed storage lock. + +Now that the choice of storage locker is divorced from that of the persistence adapter one can mix and match combinations of the two. Storage locker pluggability is made possible by the [Locker](https://fisheye6.atlassian.com/browse/activemq/trunk/activemq-broker/src/main/java/org/apache/activemq/broker/Locker.java?hb=true) interface that all pluggable lockers must implement. This interface makes it easy to implement a custom storage locker that meets local requirements. + +Every persistence adapter, however, has its own default locker which works as before. + +Lockers +------- + +Every locker must implement the [Locker](https://fisheye6.atlassian.com/browse/activemq/trunk/activemq-broker/src/main/java/org/apache/activemq/broker/Locker.java?hb=true) interface. The locker interface has the following properties: + +Property Name|Default Value|Description +---|---|--- +`lockAcquireSleepInterval`|`10000`|The polling interval (in milliseconds) between lock acquire attempts. +`failIfLocked`|`false`|Should the broker start fail if the lock is not immediately available. When `true` slave brokers will not start. + +Persistence Adapters +-------------------- + +Every persistence adapter (or any other broker service that wishes to use locks) must implement the [Lockable](https://fisheye6.atlassian.com/browse/activemq/trunk/activemq-broker/src/main/java/org/apache/activemq/broker/Lockable.java?r=1383400) interface. This interface has the following properties: + + +Property Name|Default Value|Description +---|---|--- +`useLock`|`true`|Should the persistence adapter use the configured locker. Intended primarily for use during development to temporarily disable the use of the locker without having to remove its configuration. +`lockKeepAlivePeriod`|`0`|The duration (in milliseconds) to keep the lock alive, when greater than `0`. + +Existing Lockers +---------------- + +### Shared File Locker + +The Shared File Locker is the default locker for the KahaDB persistence adapter. It locks a file to ensure that only the broker holding the lock (the master) is granted access to the message store. + +#### Example: +``` + + + + + + + +``` + +The `lockKeepAlivePeriod` attribute is not applicable to versions of ActiveMQ Classic older than 5.9.0. + +> Consequences of lockKeepAlivePeriod = 0 +> +> For this locker `lockKeepAlivePeriod` should be greater than `0`.This period is the frequency with which the master broker makes lock keep alive calls. +> +> When `lockKeepAlivePeriod = 0` slave brokers are still unable to obtain the file lock. However, if some third party modifies the lock file (either modification or deletion) the master broker will not detect the change. Therefore a slave broker's next attempt (per its configured `lockAcquireSleepInterval`) to obtain the file lock will succeed. When this happens there will be two master brokers in the cluster. _This situation will result in message store corruption_! +> +> When `lockKeepAlivePeriod` is greater than `0`, the master broker will make a lock keep alive call every `lockKeepAlivePeriod` milliseconds. Therefore the master broker will detect any lock file changes when it makes its next keep alive call. Upon detecting said change the master broker will demote itself to a slave broker. + +> Note that as of ActiveMQ Classic 5.9.0 the KahaDB persistence adapter can also use the Lease Database Locker (see below). + +### Database Locker + +The Database Locker is the default locker for the JDBC persistence adapter. It locks a database table in a transaction to ensure that only single resource is used. + +#### Example: +``` + + + + + + + +``` + +The Database Locker uses its `keepAlive` method to ensure the broker still holds the lock. You can set the keep alive period using the `lockKeepAlivePeriod` property. The default period is 30000 ms. If a broker fails to acquire the lock on the database, it will retry every `lockAcquireSleepInterval` milliseconds. + +This locker opens a JDBC transaction against a database table (`activemq_lock`) that lasts as long as the broker remains alive. This locks the entire table and prevents another broker from accessing the store. In most cases this will be a fairly long running JDBC transaction which occupies resources on the database over time. + +A problem with this locker can arise when the master broker crashes or loses its connection to the database causing the lock to remain in the database until the database responds to the half closed socket connection via a TCP timeout. The database lock expiry requirement can prevent the slave from starting some time. In addition, if the database supports failover, and the connection is dropped in the event of a replica failover, that JDBC transaction will be rolled back. The broker sees this as a failure. Both master and slave brokes will again compete for a lock. + +### Lease Database Locker + +The Lease Database Locker was created to solve the shortcomings of the Database Locker. The Lease Database Locker does not open a long running JDBC transaction. Instead it lets the master broker acquire a lock that's valid for a fixed (usually short) duration after which it expires. To retain the lock the master broker must periodically extend the lock's lease before it expires. Simultaneously the slave broker checks periodically to see if the lease has expired. If, for whatever reason, the master broker fails to update its lease on the lock the slave will take ownership of the lock becoming the new master in the process. The leased lock can survive a DB replica failover. + +#### Example: +``` + + + + + + + +``` + +In order for this mechanism to work correctly, each broker in a master/slave(s) cluster must have a unique value for the `brokerName` attribute as defined on the `` tag. Alternatively, use unique values for the `leaseHolderId` attribute on the `` tag as this value is used to create a lease lock definition. + +The lease based lock is acquired by blocking at startup. It is then retained for a period whose duration (in ms) is given by the `lockKeepAlivePeriod` attribute. To retain the lock the master broker periodically extends its lease by `lockAcquireSleepInterval` milliseconds each time. In theory, therefore, the master broker is always (`lockAcquireSleepInterval - lockKeepAlivePeriod`) ahead of the slave broker with regard to the lease. It is imperative that `lockAcquireSleepInterval > lockKeepAlivePeriod`, to ensure the lease is always current. As of ActiveMQ Classic 5.9.0 a warning message is logged if this condition is not met. + +In the simplest case, the clocks between master and slave must be in sync for this solution to work properly. If the clocks cannot be in sync, the locker can use the system time from the database CURRENT TIME and adjust the timeouts in accordance with their local variance from the DB system time. If `maxAllowableDiffFromDBTime` is greater than zero the local periods will be adjusted by any delta that exceeds `maxAllowableDiffFromDBTime`. + +> It is important to know if the default rules your JDBC driver uses for converting `TIME` values are JDBC compliant. If you're using MySQL, for example, the driver's JDBC URL should contain `useJDBCCompliantTimezoneShift=true` to ensure that `TIME` value conversion is JDBC compliant. If not the locker could report a large time difference when it compares the retrieved lease expiration time against the current system time. Consult your JDBC driver's documentation for more details. + +As of ActiveMQ Classic 5.9.0 the lease database locker can be used in conjunction with the KahaDB persistence adapter. However, this particular combination requires that the lease database locker element contains a `` child element. In the example below the `lockTableName` is also configured, although doing so is not mandatory. +``` + + + + + + + entries: --> + + + + + + +``` +> To see the complete list of attributes and SQL statements that can be overridden see the [Statements](https://fisheye6.atlassian.com/browse/activemq/trunk/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/Statements.java?hb=true) class. + +When the KahaDB persistence adapter is configured to use the `lease-database-locker` you must configure the broker to use your own IO exception handler as neither the `DefaultIOExceptionHandler` nor the `JDBCIOExceptionHandler` will work correctly with this combination. See [Configurable IOException Handlers](configurable-ioexception-handling) for details on how to write a handler. + +> As of ActiveMQ Classic 5.11, however, the `JDBCIOExceptionHandler` has been deprecated. It has been replaced by the `org.apache.activemq.util.LeaseLockerIOExceptionHandler` that will work with any persistence adapter that supports pluggable storage lockers, regardless if one is configured. + diff --git a/hugo/content/components/classic/documentation/producer-flow-control.md b/hugo/content/components/classic/documentation/producer-flow-control.md new file mode 100644 index 0000000000..065f98ff95 --- /dev/null +++ b/hugo/content/components/classic/documentation/producer-flow-control.md @@ -0,0 +1,116 @@ +--- +title: Producer Flow Control +layout: classic-doc +--- + + + +Producer Flow Control +--------------------- + +In ActiveMQ Classic 4.x flow control was implemented using TCP flow control. The underlying network connection of throttled consumers was suspended to enforce flow control limits. This strategy is very efficient but can lead to deadlocks if there are multiple producers and consumers sharing the same connection. + +As of ActiveMQ Classic 5.0, we can now individually flow control each producer on a shared connection without having to suspend the entire connection. By 'flow control' we mean that if the broker detects that the memory limit for the destination, or the temp- or file-store limits for the broker, have been exceeded, then the flow of messages can be slowed down. The producer will be either blocked until resources are available _or_ will receive a JMSException: this behaviour is configurable and described in the section below on ``. + +It's worth noting that the default `` settings will cause the producer to _block_ when the `memoryLimit` or `` limits are reached: this blocking behaviour is sometimes misinterpreted as a 'hung producer', when in fact the producer is simply diligently waiting until space is available. + +* Messages that are sent synchronously will automatically use per producer flow control; this applies generally to persistent messages which are sent synchronously _unless_ you enable the `useAsyncSend` flag. + +* Producers that use [Async Sends](async-sends) \- generally speaking, producers of non-persistent messages - don't bother waiting for any acknowledgement from the broker; so, if a memory limit has been exceeded, you will _not_ get notfied. If you do want to be aware of broker limits being exceeded, you will need to configure the ProducerWindowSize connection option so that even async messages are flow controlled per producer. +``` +ActiveMQConnectionFactory connctionFactory = connctionFactory.setProducerWindowSize(1024000); +``` +The ProducerWindowSize is the maximum number of bytes of data that a producer will transmit to a broker before waiting for acknowledgment messages from the broker that it has accepted the previously sent messages. + +Alternatively, if you're sending non-persisted messages (which are by default sent async), and want to be informed if the queue or topic's memory limit has been breached, then you can simply configure the connection factory to 'alwaysSyncSend'. While this is going to be slower, it will ensure that your message producer is informed immediately of memory issues. + +If you like, you can disable flow control for specific JMS queues and topics on the broker by setting the `producerFlowControl` flag to false on the appropriate destination policy in the Broker configuration - e.g. +``` + + + + + + + +``` +see [Broker Configuration](xml-configuration). + +Note that, since the introduction of the new file cursor in ActiveMQ Classic 5.x, non-persisted messages are shunted into the temporary file store to reduce the amount of memory used for non-persistent messaging. As a result, you may find that a queue's memoryLimit is never reached, as the cursor doesn't use very much memory. If you really do want to keep all your non-persistent messages in memory, and stop producers when the limit is reached, you should configure the ``. +``` + + + + + +``` +The fragment above will ensure that all non-persistent queue messages are kept in memory, with each queue having a limit of 1Mb. + +### How Producer Flow Control works + +If you are sending a persistent message (so that a response of the [OpenWire](openwire) Message is expected then the broker will send the producer a [ProducerAck](http://activemq.apache.org/maven/5.9.0/apidocs/index.html) message. This informs the producer that the previous sending window has been processed, so that it can now send another window. Its kinda like consumer acks but in reverse. + +#### Advantage + +So a nice producer might wait for a producer ack before sending more data, to avoid flooding the broker (and forcing the broker to block the entire connection if a slow consumer occurs). To see how this works in source code, check out the [ActiveMQMessageProducer](http://activemq.apache.org/maven/5.9.0/apidocs/index.html) code. + +Though a client can ignore the producer ACKs altogether and the broker should just stall the transport if it has to for slow consumer handling; though this does mean it'll stall the entire connection. + +### Configure Client-Side Exceptions + +An alternative to the indefinite blocking of the `send()` operation when no space is free on the broker is to instead configure that an exception to be thrown on the client-side. By configuring the `sendFailIfNoSpace` property to `true`, the broker will cause the `send()` operation to fail with a `javax.jms.ResourceAllocationException`, which will propagate to the client. Below is an example of this configuration: +``` + + + + + + + +``` +The advantage of this property is that the client can catch the `javax.jms.ResourceAllocationException`, wait a bit and retry the `send()` operation instead of just hanging indefinitely. + +Starting in version 5.3.1 the `sendFailIfNoSpaceAfterTimeout` property has been added. This property causes the `send()` operation to fail with an exception on the client-side, but only after waiting the given amount of time. If space on the broker is still not freed after the configured amount of time, only then does the `send()` operation fail with an exception to the client-side. Below is an example: +``` + + + + + + + +``` +The timeout is defined in milliseconds so the example above waits for three seconds before failing the `send()` operation with an exception to the client-side. The advantage of this property is that it will block for the configured amount of time instead of failing immediately or blocking indefinitely. This property offers not only an improvement on the broker-side, but also an improvement for the client so it can catch the exception, wait a bit and retry the `send()` operation. + +Starting in version 5.16.0 the `sendFailIfNoSpace` and `sendFailIfNoSpaceAfterTimeout` can be configured on a per destination basis via [destination policies](per-destination-policies). + +Disabling Flow Control +---------------------- + +A common requirement is to disable flow control so that message dispatching continues until all available disk is used up by pending messages (whether persistent or non persistent messaging is configured). To do this enable [Message Cursors](message-cursors). + +System usage +------------ + +You can also slow down producers via some attributes on the `` element. Take a look at the following example: +``` + + + + + + + + + + + + + +``` +You can set limits of memory for `NON_PERSISTENT` messages, disk storage for `PERSITENT` messages and total usage for temporary messages, the broker will use before it slowdown producers. _Using the default settings shown above, the broker will block the `send()` call until some messages are consumed and space becomes available on the broker._ The default values are shown above, you will probably need to increase these values for your environment. + +**PercentUsage** + +Both StoreUsage and TempUsage support a percentLimit attribute where the limit is determined as a percentage of the total available. From version 5.15.x there is an additional related total attribute that can be used to explicitly set the total available such that the file system is not queried. This is useful in the case that only part of a disk partition is available to the broker or where the underlying file store reports > Long.MAX_VALUE available capacity (e.g: EFS) which will overflow the long return value of java.io.File#getTotalSpace. Note that when a total is specified, that actual data available will not be validated agains the file system, just the store usage relative to that absolute total. + diff --git a/hugo/content/components/classic/documentation/protocols.md b/hugo/content/components/classic/documentation/protocols.md new file mode 100644 index 0000000000..907bb12301 --- /dev/null +++ b/hugo/content/components/classic/documentation/protocols.md @@ -0,0 +1,20 @@ +--- +title: Protocols +layout: classic-doc +--- + + + +Apache ActiveMQ Classic is a message broker which supports multiple wire level protocols for maximum interoperability. + +* [AMQP](amqp) +* [AUTO](auto) +* [MQTT](mqtt) +* [OpenWire](openwire) +* [REST](rest) +* [RSS and Atom](rss-and-atom) +* [Stomp](stomp) +* [WSIF](wsif) +* [WS Notification](ws-notification) +* [XMPP](xmpp) + diff --git a/hugo/content/components/classic/documentation/pure-master-slave.md b/hugo/content/components/classic/documentation/pure-master-slave.md new file mode 100644 index 0000000000..b9d6c9eac2 --- /dev/null +++ b/hugo/content/components/classic/documentation/pure-master-slave.md @@ -0,0 +1,91 @@ +--- +title: Pure Master Slave +layout: classic-doc +--- + + +> **Warning** +> +> The LevelDB store has been removed from production. +> This page only serves as an archival page for previous releases. +> Use [shared storage master/slave](masterslave) instead. + + +### Pure Master Slave + +> This feature has been deprecated and will be removed in version 5.8 +> +> This feature will be removed in 5.8 as it has not evolved to be production ready. You are advised to use [shared storage master/slave](masterslave) or the [Replicated LevelDB Store](replicated-leveldb-store). See [AMQ-4165](https://issues.apache.org/jira/browse/AMQ-4165) + +A Pure Master Slave configuration provides a basic shared nothing, fully replicated topology which does not depend on a shared file system or shared database. + +### How Pure Master Slave works + +* A slave of a master broker consumes all message states from the master - messages, acknowledgments and transactional states. + Whilst a Slave is actively connected to the Master - it does not allow or start any network or transport connectors, it's sole purpose is to duplicate the state of the master. + +* The master broker will only respond to a client when a message exchange has been successfully passed to the slave. For example, a commit + in a clients transaction will not complete until the master and the slave have processed the commit. + +* In the event the master fails (e.g. hardware failure) the slave has optionally two modes of operation + 1. starts all it's network and transport connectors - allowing clients connected to the master to resume on the slave. + 2. or can be configured to close down. In this mode, the slave is simply used to duplicate state for the master. + +* clients should use a failover transport for connecting to the master broker first and then the slave. e.g. using a URL such as +``` +failover://(tcp://masterhost:61616,tcp://slavehost:61616)?randomize=false +``` +The **randomize** property just disables randomness so that the transport will always try the master first, then the slave if it can't connect to that. Note that the slave does not accept connections until it becomes the master + +### Limitations of Pure Master Slave + +* Only one slave can be connected to the Master +* A failed master cannot be re-introduced without shutting down the the slave broker (no automatic failback) +* There is no automatic synchronization between brokers. This is a manual process. + +### Recovering a Pure Master Slave topology + +This is a manual process - once a master has failed, the only sure way to ensure that the toplogy is synchronized again is manually: + +* shutdown the slave broker (The clients do not need to be shutdown - they will wait until the topology is re-established if they are failover clients +* copy the data directory from the slave over the data directory of the master broker +* re-start the master and the slave + +### Configuring Pure Master Slave + +You should not configure a connection between the master and a slave. The connection is automatically established with the slave's configuration. If you explicitly configure a network connection, you may encounter race conditions when the master broker is under heavy load. + +A master broker doesn't need any special configuration - it's a normal broker until a slave broker attaches itself. +To identify a broker as a slave - there is just one property to set (see below) as this [example shows](http://svn.apache.org/repos/asf/activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/broker/ft/slave2.xml) - so configuration is nice and easy: +``` + + + + + + + + + +``` +Broker Property|default|Description +---|---|--- +masterConnectorURI|null|URI to the master broker e.g. `tcp://masterhost:62001` +shutdownOnMasterFailure|false|if true, the slave will shut down if the master fails otherwise the slave will take over as being the new master. The slave ensures that there is a separate copy of each message and acknowledgement on another machine which can protect against catastrophic hardware failure. If the master fails you might want the slave to shut down as well as you may always want to duplicate messages to 2 physical locations to prevent message loss on catastrophic data centre or hardware failure. If you would rather the system keep on running after a master failure then leave this flag as false. +waitForSlave|false|version 5.2+, if true, a master will wait till a slave has attached before completing its startup sequence +shutdownOnSlaveFailure|false|version 5.2+, if true, a master will shutdown if the slave connection is lost, ensuring that the master will not become out of sync with the slave. + +### Configuring the authentication of the Slave + +In ActiveMQ Classic 4.1 or later you can use a `` element as an alternative XML configuration mechanism as shown in the following [example](http://svn.apache.org/repos/asf/activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/broker/ft/slave2.xml) to configure the user and password that the slave will use to connect to the master +``` + + + + + + + + + +``` diff --git a/hugo/content/components/classic/documentation/qos.md b/hugo/content/components/classic/documentation/qos.md new file mode 100644 index 0000000000..516a4682cf --- /dev/null +++ b/hugo/content/components/classic/documentation/qos.md @@ -0,0 +1,15 @@ +--- +title: QoS +layout: classic-doc +--- + + + +QoS is a MOM abbreviation of the term _Quality of Service_. There are many different kinds of messaging with different qualities of service such as + +* topics versus queues +* durable messaging versus _reliable_ (some buffering takes place but if a consumer is down long enough the messages are discarded) +* message timeout + +etc. + diff --git a/hugo/content/components/classic/documentation/redelivery-policy.md b/hugo/content/components/classic/documentation/redelivery-policy.md new file mode 100644 index 0000000000..cd0e4a08c6 --- /dev/null +++ b/hugo/content/components/classic/documentation/redelivery-policy.md @@ -0,0 +1,51 @@ +--- +title: Redelivery Policy +layout: classic-doc +--- + + + +Redelivery Policy +----------------- + +Detail on when messages are redelivered to a client can be found in the [Message Redelivery and DLQ Handling](message-redelivery-and-dlq-handling) section. You can configure the [RedeliveryPolicy](http://svn.apache.org/viewvc/activemq/trunk/activemq-client/src/main/java/org/apache/activemq/RedeliveryPolicy.java?view=markup) on your [ActiveMQConnectionFactory](http://svn.apache.org/viewvc/activemq/trunk/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java?view=markup) or [ActiveMQConnection](http://svn.apache.org/viewvc/activemq/trunk/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnection.java?view=markup) to customize exactly how you want the redelivery to work. + +You can use Java code, Spring or the [Connection Configuration URI](connection-configuration-uri) to customize this. + +### Available Properties + +Property|Default Value|Description +---|---|--- +`backOffMultiplier`|`5`|The back-off multiplier. +`collisionAvoidanceFactor`|`0.15`|The percentage of range of collision avoidance if enabled. +`initialRedeliveryDelay`|`1000L`|The initial redelivery delay in milliseconds. +`maximumRedeliveries`|`6`|Sets the maximum number of times a message will be redelivered before it is considered a **poisoned pill** and returned to the broker so it can go to a Dead Letter Queue. Set to `-1` for unlimited redeliveries. +`maximumRedeliveryDelay`|`-1`|Sets the maximum delivery delay that will be applied if the `useExponentialBackOff` option is set. (use value `-1` to define that no maximum be applied) (v5.5). +`redeliveryDelay`|`1000L`|The delivery delay if `initialRedeliveryDelay=0` (v5.4). +`useCollisionAvoidance`|`false`|Should the redelivery policy use collision avoidance. +`useExponentialBackOff`|`false`|Should exponential back-off be used, i.e., to exponentially increase the timeout. + +RedeliveryPolicy per Destination +-------------------------------- + +As of ActiveMQ Classic v5.7.0 you can now configure a [RedeliveryPolicy](http://svn.apache.org/viewvc/activemq/trunk/activemq-client/src/main/java/org/apache/activemq/RedeliveryPolicy.java?view=markup) on a per-destination bases. The `ActiveMQConnection` factory class now exposes a [RedeliveryPolicyMap](http://svn.apache.org/viewvc/activemq/trunk/activemq-client/src/main/java/org/apache/activemq/broker/region/policy/RedeliveryPolicyMap.java?view=markup) property that allows to assign a RedeliveryPolicy using named destinations or using destination wildcards. The code snipped below shows how to configure a different [RedeliveryPolicy](http://svn.apache.org/viewvc/activemq/trunk/activemq-client/src/main/java/org/apache/activemq/RedeliveryPolicy.java?view=markup) for Topics and Queues. +``` +ActiveMQConnection connection ... // Create a connection + +RedeliveryPolicy queuePolicy = new RedeliveryPolicy(); +queuePolicy.setInitialRedeliveryDelay(0); +queuePolicy.setRedeliveryDelay(1000); +queuePolicy.setUseExponentialBackOff(false); +queuePolicy.setMaximumRedeliveries(2); + +RedeliveryPolicy topicPolicy = new RedeliveryPolicy(); +topicPolicy.setInitialRedeliveryDelay(0); +topicPolicy.setRedeliveryDelay(1000); +topicPolicy.setUseExponentialBackOff(false); +topicPolicy.setMaximumRedeliveries(3); + +// Receive a message with the JMS API +RedeliveryPolicyMap map = connection.getRedeliveryPolicyMap(); +map.put(new ActiveMQTopic(">"), topicPolicy); +map.put(new ActiveMQQueue(">"), queuePolicy); +``` \ No newline at end of file diff --git a/hugo/content/components/classic/documentation/release-guide.md b/hugo/content/components/classic/documentation/release-guide.md new file mode 100644 index 0000000000..bbe5f22393 --- /dev/null +++ b/hugo/content/components/classic/documentation/release-guide.md @@ -0,0 +1,201 @@ +--- +title: Release Guide +layout: classic-doc +--- + + + +How to create and announce an ActiveMQ Classic release. This release is based on [General guide for releasing Maven-based project at Apache](http://maven.apache.org/developers/release/apache-release.html) , so be sure to check it out before continuing and meet all prerequisites. + +Maven 2 Setup +------------- + +Before you deploy anything to the maven repository using Maven 2, you should configure your ~/.m2/settings.xml file +so that the file permissions of the deployed artifacts are group writeable. If you do not do this, other developers will not able to overwrite your SNAPSHOT releases with newer versions. +``` + + ... + + + + apache.snapshots.https + dejanb + + + + apache.website + dejanb + 664 + 775 + + + + apache.releases.https + dejanb + + + + stagingSite + dejanb + 664 + 775 + + + + ... + +``` +It is also essential that you configure your umask to 2 on people.apache.org for non-interactive login. If your shell is tcsh you can edit .cshrc to include + +umask 2 + +Other shell initialization files may interfere with this setting but if this is the only umask setting it appears to work. Instructions for other shells would be welcome. + +### Additional local configuration for using release and staging plugins. + +To effectively use the release and staging plugins you need some information about where the staging will happen and signing information for gpg. Your ~/.m2/settings.xml should contain a profile like this: +``` + + + + apache-release + + secretPhrase + + + + ... + +``` + +Creating the ActiveMQ Classic Release +----------------------------- + +The release plugin will prompt for a release version, tag and next release version. Use a three digit release version of the form: 5.x.x and for the tag use a string of the form: activemq-5.x.x. The next version string should use the two digit from: 5.x-SNAPSHOT as this can be consistent for future SNAPSHOT releases. + +1. Verify the to-be-released version identifier exists in the [META-INF/spring.schemas](https://git-wip-us.apache.org/repos/asf?p=activemq.git;a=blob;f=activemq-spring/src/main/resources/META-INF/spring.schemas;hb=HEAD) mappings file AND [activemq-osgi/src/main/resources/META-INF/spring.schemas](https://git-wip-us.apache.org/repos/asf?p=activemq.git;a=blob;f=activemq-osgi/src/main/resources/META-INF/spring.schemas;hb=HEAD) file, if not add it and commit. It should contain: + ``` + http://activemq.apache.org/schema/core/activemq-core-${pom.version}.xsd=activemq.xsd + ``` +2. Verify headers with [rat](http://incubator.apache.org/rat/apache-rat-plugin/usage.html) + ``` + mvn -e apache-rat:check + grep -e ' !?????' target/rat.txt -- will show any files without licenses + ``` +3. Do a release dry run to check for problems + ``` + mvn release:prepare -DdryRun=true + ``` + Check that you are happy with the results. The poms for the proposed tags will be in pom.xml.tag. When you like the results, clean up: + ``` + mvn release:clean + ``` +4. Prepare the release + ``` + mvn release:prepare + ``` + This will create the tag in git and leave various stuff around locally to direct the perform phase. + +5. Make a local copy of the release configuration in case something goes wrong + ``` + cd .. + cp -r activemq-release activemq-release-prepared + cd activemq-release + ``` +6. Perform the release to the staging repo + ``` + mvn release:perform + ``` + This uses both the activemq release profile which directs building source jars, javadoc jars, and signing everything, and also the settings release profile that says where to + put stuff and how to sign it. + +7. Close the staging repository + Quote from the [Maven release guide for Apache projects](http://maven.apache.org/developers/release/apache-release.html) + + > Login to [https://repository.apache.org](https://repository.apache.org) using your Apache LDAP credentials. Click on "Staging". Then click on "maven" in the list of repositories. In the panel below you should see an open repository that is linked to your username and ip. Right click on this repository and select "Close". This will close the repository from future deployments and make it available for others to view. If you are staging multiple releases together, skip this step until you have staged everything. Enter the name and version of the artifact being released in the "Description" field and then click "Close". This will make it easier to identify it later. + + See the image in the original guide for more info. +8. Verify staged artifacts + Quote from the [original guide](http://maven.apache.org/developers/release/apache-release.html) + + > If you click on your repository, a tree view will appear below. You can then browse the contents to ensure the artifacts are as you expect them. Pay particular attention to the existence of *.asc (signature) files. If the you don't like the content of the repository, right click your repository and choose "Drop". You can then rollback your release and repeat the process. + > Note the repository URL, you will need this in your vote email. + +9. Build the site from the tag that release:perform checked out into target/checkout in the previous step. + Note that the -Prelease profile is needed to specify the profile in settings.xml that configures the staging location. + ``` + cd target/checkout + mvn site -Prelease + ``` +10. Populate the Javadocs site in svn + ``` + svn co https://svn.apache.org/repos/infra/websites/production/activemq/content + cd content/maven + mkdir + #copy over apidocs folder that was created by the site plugin to /apidocs + svn add + svn rm apidocs + ln -s /apidocs apidocs + svn add apidocs + # and commit once it looks good. + ``` +11. Stage the official release artifacts in the SVN dist dev area for folks to test and vote on, using the helper script already in the repo: + ``` + svn co https://dist.apache.org/repos/dist/dev/activemq/activemq/ + cd activemq + ./prepare-release.sh + # Example: ./prepare-release.sh https://repository.apache.org/content/repositories/orgapacheactivemq-1149 5.15.1 + svn add + ``` + and commit once it looks good. + +12. Call a vote on the dev list, listing the great new features of the release. + +After the vote passes +--------------------- + +1. Promote the release (i.e. release the staging repository): login to[https://repository.apache.org](https://repository.apache.org/), navigate to the staging repository and click the "release" button.  +2. Copy the staged release files from the SVN dist dev folder to the SVN dist release folder: [https://dist.apache.org/repos/dist/release/activemq/](https://dist.apache.org/repos/dist/release/activemq/) + ``` + svn cp -m "add files for activemq-" https://dist.apache.org/repos/dist/dev/activemq/activemq/ https://dist.apache.org/repos/dist/release/activemq/ + # Example: svn cp -m "add files for activemq-5.15.1" https://dist.apache.org/repos/dist/dev/activemq/activemq/5.15.1 https://dist.apache.org/repos/dist/release/activemq/5.15.1 + ``` +3. Populate the schema site in svn + ``` + svn co https://svn.apache.org/repos/infra/websites/production/activemq/content + cd content/schema/core + curl --remote-name-all https://repository.apache.org/content/repositories/releases/org/apache/activemq/activemq-spring//activemq-spring-{-schema.html,.xsd}{.asc,.asc.md5,.asc.sha1,.sha1,.md5,} + for i in activemq-spring-5.9.0*; do mv -- "$i" "${i//spring/core}"; done; + svn add activemq-core-5.9.0* + svn rm activemq-core.xsd + ln -s activemq-core-5.9.0.xsd activemq-core.xsd + svn add activemq-core.xsd + # and commit once it looks good. + ``` +4. Continue with the Announcing section below +5. Created a in progress wiki page for the next release +6. Remove any releases from the dist site that are no longer supported and update the wiki page for that release to point to the archives for downloads. + +Announcing the ActiveMQ Classic Release +------------------------------- + +1. Perform a release in JIRA and create a new release version in JIRA. + 1. Move unresolved issues to the next release first, in a bulk (do not send email) update + 2. You might also want to search for resolved/closed issues with no fix version just in case +2. Create a download page for the realease by adding a file in `src/_releases/` and name the file with its version converted to an integer - for example the file for 5.16.1 should be name `activemq-5016001-release.md`. The Front Matter must include `version`, `release_notes`, `release_date`, and `title`. For example, this might be an expected content based on the 5.16.1 release: + ``` + --- + version: 5.16.1 + release_notes: https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12311210&version=12347027 + release_date: Jan 20, 2021 + title: ActiveMQ Classic 5.16.1 Release + --- + Apache ActiveMQ Classic {{ page.version }} was released on {{ page.release_date }}. It fully supports JDK 9+ at runtime and includes several resolved [issues]({{ page.release_notes }}) and bug fixes. + ``` +3. If necessary, update the current versions by editing the `5x` list in `src/_data/current_releases.yml`. The latest patch release published in `src/_releases/` for the major.minor versions in the list will automatically be included on the [download page](https://activemq.apache.org/components/classic/download/). +4. Update the [Xml Reference](xml-reference) page with a link to the HTML and XSD +7. Update [QuickLinks](quicklinks) and [JavaDocs](docs) pages +8. Mail the [dev](mailto:dev@activemq.apache.org) & [user](mailto:user@activemq.apache.org) lists +9. [Post](http://cwiki.apache.org/confluence/pages/viewrecentblogposts.action?key=ACTIVEMQ) a news entry on the WIKI +10. tweet +11. Have a beer! diff --git a/hugo/content/components/classic/documentation/release-plans.md b/hugo/content/components/classic/documentation/release-plans.md new file mode 100644 index 0000000000..8cb2aceba4 --- /dev/null +++ b/hugo/content/components/classic/documentation/release-plans.md @@ -0,0 +1,16 @@ +--- +title: Release Plans +layout: classic-doc +--- + + + +### Information + +* [Release Info](release-info) +* [How you can help release](how-you-can-help-release) + +### Release Plans + +* [4.0 RC 1 Guide](40-rc-1-guide) + diff --git a/hugo/content/components/classic/documentation/replicated-message-store.md b/hugo/content/components/classic/documentation/replicated-message-store.md new file mode 100644 index 0000000000..ebed4aea07 --- /dev/null +++ b/hugo/content/components/classic/documentation/replicated-message-store.md @@ -0,0 +1,35 @@ +--- +title: Replicated Message Store +layout: classic-doc +--- + + + +If messages are stored on the hard drive of a broker or inside a single database; then you have a single point of failure with respect to the message persistence. If you lose the entire machine, disk or database, you have lost messages. + +For some high end users, messages should never be lost as they could have a large impact on the business. These kinds of users often require some kind of [DR](dr) stategy to support message replication so that they can loose an entire data centre and still not loose a message. + +There are various solutions to the problem of reducing chance of message loss. + +### Use RAID disks + +If you're using RAID disks striped sufficiently, you could just restart the machine - or move the disk to a new machine and restart the broker. This could be sufficient if you're a small business but if you've stringent [DR](dr) requirements then if you loose a datacentre the RAID option is not a solution. + +### SAN or shared network drive + +If you use one of the file based persistence mechanisms such as the default high performance journal and Apache Derby, you could write to a SAN or shared network drive and in times of failure, start up a new broker using the files from the failed broker. + +Also 4.1 allows you to start many brokers reading from the same shared file system to support high availability via the [Shared File System Master Slave](shared-file-system-master-slave) feature. + +### Master/Slave + +An alternative is to use the [MasterSlave](masterslave) feature to pair brokers together so that all messages are replicated to both brokers, the master and slave to ensure that there are two physical copies of the message so that catastrophic hardware failures (such as loss of an entire data centre) can be handled. + +### Clustered JDBC databases + +Various databases like Oracle and MySQL support clustered databases; so we can use these databases with the JDBC MessageStore to get a clustered message store. Note if this option is used then the high performance journal must be disabled (which severely affects performance) + +#### Use C-JDBC + +If you don't have or can't afford a clustered database then you could use [C-JDBC](http://c-jdbc.objectweb.org/) to replicate state across a number of physical datbases to avoid single point of failure and provide a [DR](dr) solution. As noted above using a replicated JDBC approach is very slow as it requires us to disable the high performance journal. + diff --git a/hugo/content/components/classic/documentation/resource-adapter-does-not-seem-to-pool-connections.md b/hugo/content/components/classic/documentation/resource-adapter-does-not-seem-to-pool-connections.md new file mode 100644 index 0000000000..6dc7e0f7c4 --- /dev/null +++ b/hugo/content/components/classic/documentation/resource-adapter-does-not-seem-to-pool-connections.md @@ -0,0 +1,16 @@ +--- +title: Resource Adapter does not seem to pool connections +layout: classic-doc +--- + + + +It may seem like the resource adapter when used in an app server like geronimo or jboss is not pooling connections. Looking the the ActiveMQ Classic broker logs, it will show multiple message for each use of a pooled conntion simlilar to: +``` +16:43:07 INFO Adding new client: ID:localhost-58375-1120682586690-1:0 on transport: TcpTransportChannel: Socket\[addr=/127.0.0.1,port=58376,localport=61616\] +16:43:08 INFO Removing client: ID:localhost-58375-1120682586690-1:0 on transport: TcpTransportChannel: Socket\[addr=/127.0.0.1,port=58376,localport=61616\] +``` +At first glance it may seem like a new connection is being established.. but if you look at the logs is more detail, you will noticed that the client connection id's are being reused since the connections are being pooled. This behavior is a side-effect of the connection being reset to a 'cleaned up' state. It allows the next client to use the connection as if it has just been created. + +So these messages are normal, and YES, your jms connections are being pooled! + diff --git a/hugo/content/components/classic/documentation/resource-adapter.md b/hugo/content/components/classic/documentation/resource-adapter.md new file mode 100644 index 0000000000..238db00c5f --- /dev/null +++ b/hugo/content/components/classic/documentation/resource-adapter.md @@ -0,0 +1,56 @@ +--- +title: Resource Adapter +layout: classic-doc +--- + + + +Introduction +------------ + +ActiveMQ Classic includes a Java Connector Architecture (JCA) 1.5 Resource Adapter. JCA 1.5 defines the contract between an J2EE application server and external resources such as databases and messaging middleware. It allows the application server to efficiently pool connections, control transactions and manage security. The Resource Adapter allows ActiveMQ Classic to be used from any J2EE 1.4 application server. We have tested that the Resource Adapter works in the following J2EE 1.4 containers + +* [TomEE](http://tomee.apache.org/tomcat-jms) 1 +* Geronimo 1 +* GlassFish +* JBoss 4 +* WebLogic 9 +* WebSphere 6 + +Features +-------- + +* Inbound connection delivers messages to MDBs via XA or local transactions. +* Outbound connections support standard container pooling or can reuse the inbound connection/session to avoid XA. +* JTA support: Can be enlisted in XA and local transactions. +* XA transaction recovery via XAResource.recover() supported. +* When used outside a JTA transaction, session transaction settings retain normal JMS semantics so that it be used by your web-app tier. +* Can configure and start up embedded broker. +* Can connect to external ActiveMQ Classic broker or embedded broker. +* Inbound message delivery supports fine grain control of concurrency and prefetching. +* Batching so that multiple messages can be delivered within the same transaction for optimal performances. + +Downloading the RAR +------------------- + +The RAR is available via [maven central](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22activemq-rar%22) + +Deployment Guides + +* [TomEE](tomee) +* [Geronimo](geronimo) +* [Integrating Apache ActiveMQ Classic with Glassfish](integrating-apache-activemq-classic-with-glassfish) +* [JBoss Integration](jboss-integration) + +The use of an Embedded Broker +----------------------------- + +The ActiveMQ Classic Resource Adapter can connect to a remote broker using any of the available transports, or it can start up an embedded broker. As described in the [Resource Adapter Properties](resource-adapter-properties), you can enable an embedded broker using the **BrokerXmlConfig** property. + +Configuration Reference +----------------------- + +* [Resource Adapter Properties](resource-adapter-properties) +* [Connection Factory Properties](connection-factory-properties) +* [Activation Spec Properties](activation-spec-properties) + diff --git a/hugo/content/components/classic/documentation/rest.md b/hugo/content/components/classic/documentation/rest.md new file mode 100644 index 0000000000..0540bfe0a7 --- /dev/null +++ b/hugo/content/components/classic/documentation/rest.md @@ -0,0 +1,269 @@ +--- +title: REST +layout: classic-doc +--- + + +ActiveMQ Classic implements a RESTful API to messaging which allows any web capable device to publish or consume messages using a regular HTTP POST or GET. + +If you are interested in messaging directly from web browsers you might wanna check out our [Ajax](ajax) or [WebSockets](websockets) support or try [running the REST examples](web-samples) + +Mapping of REST to JMS +---------------------- + +To publish a message use a HTTP POST. To consume a message use HTTP DELETE or GET. + +ActiveMQ Classic has a Servlet that takes care of the integration between HTTP and the ActiveMQ Classic dispatcher. + +NOTE: The example below requires servlet mapping on the URL. For posting without the servlet mapping, see examples further down. + +You can map a URI to the servlet and then use the relative part of the URI as the topic or queue name. e.g. you could HTTP POST to +``` +http://www.acme.com/orders/input +``` +which would publish the contents of the HTTP POST to the orders.input queue on JMS.  + +Similarly you could perform a HTTP DELETE GET on the above URL to read from the same queue. In this case we will map the MessageServlet from ActiveMQ Classic to the URI +``` +http://www.acme.com/queue +``` +and configure it to accept the URI as a queue destination. We can do similar things to support topic destinations too. + +We can use the HTTP session to denote a unique publisher or consumer. + +Note that strict REST requires that GET be a read only operation; so strictly speaking we should not use GET to allow folks to consume messages. Though we allow this as it simplifies HTTP/DHTML/Ajax integration somewhat. + +For a more cleaner mapping of a simple transfer protocol to different languages, you might wish to take a look at [Stomp](stomp). + +Default configuration +--------------------- + +Until version 5.8, REST API was part of the [Web Samples](web-samples) and was mapped to [http://localhost:8161/demo/message](http://localhost:8161/demo/message) url. From 5.8 onwards, the API is available by default at [http://localhost:8161/api/message](http://localhost:8161/api/message) url. Also, starting with 5.8, web server is secured by default (see [Web Console](web-console) for more information), so have that in mind when trying to use it. Examples below will assume new api location and secured web server. + +### Producing + +You can produce by sending a POST request to the server, like +``` +curl -u admin:admin -d "body=message" http://localhost:8161/api/message/TEST?type=queue +``` +NOTE: If no type parameter is specified, the default is to create a  topic. To change the default to queue, initialize  the servlet  with an init param in the `webapps/demo/WEB-INF/web.xml` + +As shown below: +``` + + MessageServlet + org.apache.activemq.web.MessageServlet + 1 + + topic + false + + +``` + +#### Alternate Producing Syntax + +An alternative syntax for posting is supported, using the destination URL-encoded parameter; here are some examples:  +``` +# Send to queue orders.input: +curl -XPOST -d "body=message" http://admin:admin@localhost:8161/api/message?destination=queue://orders.input + +# Send to topic orders.input: +curl -XPOST -d "body=message" http://admin:admin@localhost:8161/api/message?destination=topic://orders.input +``` + +#### Message size limit + +By default, the size of the message is limited to `100,000` characters to prevent running potentially out of memory. This value can be modified by setting the init parameter `maxMessageSize` to the value of your choice. Setting the value to `-1` disables the limitation. + +To change the value, modify the file `webapps/api/WEB-INF/web.xml` as shown below: +``` + + MessageServlet + org.apache.activemq.web.MessageServlet + 1 + true + + + maxMessageSize + -1 + + +``` + +### Timeouts + +When reading from a queue we might not have any messages. We can use a timeout query parameter to indicate how long we are prepared to wait for a message to arrive. This allows us to poll or block until a message arrives. + +Couple this with HTTP 1.1 keep-alive sockets and pipeline processing we can have efficient access to JMS over HTTP. + +Obviously if your client is Java then using ActiveMQ Classic's JMS API is the fastest and most efficient way to work with the message broker; however, if you are not using Java or prefer the simplicity of HTTP then it should be fairly efficient, especially if your HTTP client supports keep-alive sockets and pipeline processing. + +#### Consuming + +When consuming messages using the REST API, you have to keep session alive between GET requests, or you'll create a separate consumer for every request and due to prefetch limit your succeeding call will hang. + +For example, you can use `wget` to consume messages, like this: +``` +wget --user admin --password admin --save-cookies cookies.txt --load-cookies cookies.txt --keep-session-cookies http://localhost:8161/api/message/TEST1?type=queue +``` +Also, if you plan to have multiple consumer using REST, it's advisable to set prefetch size to 1 so all consumers have an equal chance of getting the message. You can do that by passing a special parameter to the `MessageServlet` +``` + + MessageServlet + org.apache.activemq.web.MessageServlet + 1 + + destinationOptions + consumer.prefetchSize=1 + + +``` +in the `webapps/demo/WEB-INF/web.xml` + +#### Alternate Consuming Syntax + +As with producing, an alternative syntax for consuming messages is also supported, using the destination URL-encoded parameter; here are some examples:  +``` +# Send to queue orders.input: +curl -XGET http://admin:admin@localhost:8161/api/message?destination=queue://orders.input + +# Send to topic orders.input: +curl -XGET http://admin:admin@localhost:8161/api/message?destination=topic://orders.input +``` + +#### Consuming without sessions + +Since 5.2.0 you can use `clientId` parameter to avoid storing actual JMS consumer in the request session. When using this approach, you don't need to keep sessions alive between requests, you just need to use the same `clientId` every time. +``` +wget --user admin --password admin http://localhost:8161/api/message/test?type=queue&clientId=consumerA +``` +Every such call will use the same JMS consumer and deliver messages send to it by the broker. + +In 5.4.1 it's also possible to unsubscribe the client. It's done by sending a POST call with `clientId` and `action=unsubscribe` parameters to the server, like +``` +http://localhost:8161/demo/message/test?clientId=consumerA&action=unsubscribe +``` + +### Consuming with selectors + +As of ActiveMQ Classic 5.4.0, you can use selectors when consuming using REST protocol. To do that, just specify the appropriate header with selector. To define a selector for the consumer, you have to provide it in an appropriate HTTP header. By default selector header name is `selector`, so the following example +``` +wget --user admin --password admin --save-cookies cookies.txt --load-cookies cookies.txt --keep-session-cookies --header="selector: test=2" http://localhost:8161/api/message/test?type=queue +``` +should consume only messages that have `test` property set to `2`. + +You can change the name of the selector header using the `org.apache.activemq.selectorName` Servlet context property in `WEB-INF/web.xml`, such as +``` + + org.apache.activemq.selectorName + activemq-selector + +``` +For more info, take a look at [RestTest](http://fisheye6.atlassian.com/browse/activemq/trunk/activemq-web-demo/src/test/java/org/apache/activemq/web/RestTest.java?r=HEAD) + +### Consuming with One Shot Consumers + +One shot consumption allows a REST call to receive a single message and then immediately close the associated consumer. + +All of the examples so far lead to the servlet creating and holding on to consumers of the destination across multiple HTTP requests. Without care, these consumers could easily lead to confusion as messages are dispatched to them but then sit unused because the consuming HTTP session, or clientId, fails to connect to continue requesting the messages. One way around that problem is the use of one-shot consumers.  Simple add the `?oneShot=true` option and the consumer is removed once the consumption completes; as follows: +``` +curl -XGET http://admin:admin@localhost:8161/api/message?destination=queue://orders.input&oneShot=true +``` +Note that interrupting the call while the consumer is waiting for a message, the consumer may remain until the server times out the HTTP request, or until a message finally arrives. + +### Content Types + +By default messages are sent to the consumers with `text/xml` content type. Your REST-based application may expect JSON response instead of XML one. In that case, you can configure the servlet to send responses back by adding something like this +``` + + MessageServlet + org.apache.activemq.web.MessageServlet + 1 + + defaultContentType + application/json + + +``` +to your `WEB-INF/web.xml`. + +A default content type can also be overridden using request headers. Specifying `xml=true` or `json=true` URL parameter you'll get a response with the desired content type. +``` +wget --user admin --password admin http://localhost:8161/api/message/TEST?type=queue\\&clientId=A\\&json=true +``` + +### Security + +Since 5.7.0 release REST API can connect to the secured brokers. The API uses basic authentication header format to get username and password information. + +For example, with curl you can do something like +``` +curl -u system:manager -d "body=message" http://localhost:8161/demo/message/TEST?type=queue +``` +Also, you might want to enable `ssl` for your connections. To do that, just uncomment SecureConnector in `conf/jetty.xml` +``` + + + + + +``` + +Rest Management +--------------- + +Starting with version 5.8 we provide a REST management API for the broker. Using [Jolokia](http://www.jolokia.org/) JMX-HTTP bridge it's possible to access all broker metrics (like memory usage) and execute management operations (like purging queues) using REST API. By default the management API is exposed at [http://localhost:8161/api/jolokia/](http://localhost:8161/api/jolokia/) URL. So you can for example get basic broker data with +``` +wget --user admin --password admin --header "Origin: http://localhost" --auth-no-challenge http://localhost:8161/api/jolokia/read/org.apache.activemq:type=Broker,brokerName=localhost +``` +or to be more specific, total consumer count with +``` +wget --user admin --password admin --header "Origin: http://localhost" --auth-no-challenge http://localhost:8161/api/jolokia/read/org.apache.activemq:type=Broker,brokerName=localhost/TotalConsumerCount +``` +By default, ActiveMQ Classic uses the [following](https://github.com/apache/activemq/blob/master/assembly/src/release/webapps/api/WEB-INF/classes/jolokia-access.xml) Jolokia security policy: +``` + + + + + + + + + + + com.sun.management:type=DiagnosticCommand + * + * + + + com.sun.management:type=HotSpotDiagnostic + * + * + + + + +``` +A custom Jolokia security policy can be configured by editing 'webapps/api/WEB-INF/web.xml' and specifying the 'policyLocation' parameter under the 'jolokia-agent' servlet. + +For more information on Jolokia security, please refer to the [security section](https://jolokia.org/reference/html/security.html) of its reference manual. An API like this makes it easy to script monitoring and management operations against the broker, see also [How can I monitor ActiveMQ Classic](how-can-i-monitor-activemq-classic)? + +Gotcha's and other trivia +------------------------- + +1. Missing "body" parameter + +In the curl POST examples above, the use of "body=..." is critical. If this is not specified in front of the message body contents, the web servlet will attempt to read the body from the request (rather than from the -d parameter), and this will result in the following exception: +``` +java.lang.IllegalStateException: STREAMED +at org.eclipse.jetty.server.Request.getReader(Request.java:898) +at org.apache.activemq.web.MessageServletSupport.getPostedMessageBody(MessageServletSupport.java:347) +at org.apache.activemq.web.MessageServlet.doPost(MessageServlet.java:126) +... +``` +However, one option in this case would be to specify the content type explicitly: +``` +curl -u admin:admin -d "hello world $(date)" -H "Content-Type: text/plain" -XPOST http://localhost:8161/api/message?destination=queue://abc.def +``` diff --git a/hugo/content/components/classic/documentation/retroactive-consumer.md b/hugo/content/components/classic/documentation/retroactive-consumer.md new file mode 100644 index 0000000000..6cb19e1f45 --- /dev/null +++ b/hugo/content/components/classic/documentation/retroactive-consumer.md @@ -0,0 +1,31 @@ +--- +title: Retroactive Consumer +layout: classic-doc +--- + + + +Background +---------- + +A retroactive consumer is just a regular JMS **Topic** consumer who indicates that at the start of a subscription every attempt should be used to go back in time and send any old messages (or the last message sent on that topic) that the consumer may have missed. + +See the [Subscription Recovery Policy](subscription-recovery-policy) for more detail. + +### Example + +You mark a Consumer as being retroactive as follows: +``` +topic = new ActiveMQTopic("TEST.Topic?consumer.retroactive=true"); +consumer = session.createConsumer(topic); +``` + +Limitations +----------- + +Retroactive consumer will not consistently work when used across a network of brokers. + +In the case of topics, when we connect broker A to broker B, broker B will send broker A all the subscriptions that it has received. Since Broker A replicates messages to each subscription, and we want to avoid receiving duplicates at broker B, we can't send broker A more than 1 subscription for the same topic. So our network bridges keep track of the subscriptions sent across and only send the first subscription to a topic. Subsequent subscriptions increment the reference count of the subscription, but the subscription is not actually sent. + +This in essence is the problem. If the first subscription to a topic is not retroactive, it is sent B to A, and the B broker will not get the retroactive messages. Then subsequent subscriptions could be (retroactive), but it will not cause retroactive message to sent from broker A to broker B since the subsequent subscription will not be sent to broker A. + diff --git a/hugo/content/components/classic/documentation/sandbox.md b/hugo/content/components/classic/documentation/sandbox.md new file mode 100644 index 0000000000..d82d44a197 --- /dev/null +++ b/hugo/content/components/classic/documentation/sandbox.md @@ -0,0 +1,7 @@ +--- +title: Sandbox +layout: classic-doc +--- + + + diff --git a/hugo/content/components/classic/documentation/security.md b/hugo/content/components/classic/documentation/security.md new file mode 100644 index 0000000000..d0be685ee3 --- /dev/null +++ b/hugo/content/components/classic/documentation/security.md @@ -0,0 +1,440 @@ +--- +title: Security +layout: classic-doc +--- + + +ActiveMQ Classic 4.x and greater provides pluggable security through various different providers. + +The most common providers are + +* [JAAS](http://java.sun.com/products/jaas/) for authentication +* a default authorization mechanism using a simple XML configuration file. + +### Authentication + +The default [JAAS](http://java.sun.com/products/jaas/) plugin relies on the standard JAAS mechanism for authentication. Refer to the [documentation](http://java.sun.com/products/jaas/reference/docs/index.html) for more detail. + +Typically you configure JAAS using a config file like [this one](http://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/login.config) and set the **java.security.auth.login.config** system property to point to it. If no system property is specified then by default the ActiveMQ Classic JAAS plugin will look for **login.config** on the classpath and use that. + +#### Authentication Example + +Here is an example [login.config](http://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/login.config) which then points to these files + +* [users.properties](http://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/org/apache/activemq/security/users.properties) +* [groups.properties](http://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/org/apache/activemq/security/groups.properties) + +**Note:** Until version 5.11.1, these property files got reloaded on every authentication request by default. So updates to users, password and groups were loaded immediately. From 5.12 onward they only get reloaded if reload=true is set in your LoginModule configuration, e.g. +``` +activemq { org.apache.activemq.jaas.PropertiesLoginModule required org.apache.activemq.jaas.properties.user="users.properties" org.apache.activemq.jaas.properties.group="groups.properties" reload=true; }; +``` +If `reload=true` is not set, these property files get loaded on broker startup only!! See AMQ-5876 for details. + +#### Simple Authentication Plugin + +If you have modest authentication requirements (or just want to quickly set up your testing environment) you can use SimpleAuthenticationPlugin. With this plugin you can define users and groups directly in the broker's XML configuration. Take a look at the following snippet for example: + +``` + + + + + + + +``` + +Users and groups defined in this way can be later used with the appropriate authorization plugin. + +##### Anonymous access + +From version 5.4.0 onwards, you can configure simple authentication plugin to allow anonymous access to the broker. + +``` + +``` + +To allow anonymous access to the broker, use `anonymousAccessAllowed` attribute and set it to `true` as shown above. Now, when the client connects without username and password provided, a default username (`anonymous`) and group (`anonymous`) will be assigned to its security context. You can use this username and password to authorize client's access to appropriate broker resources (see the next section). You can also change username and group that will be assigned to _anonymous_ users by using `anonymousUser` and `anonymousGroup` attributes. + +### Authorization + +In ActiveMQ Classic we use a number of operations which you can associate with user roles and either individual queues or topics or you can use wildcards to attach to hierarchies of topics and queues. + +Operation|Description +---|--- +read|You can browse and consume from the destination +write|You can send messages to the destination +admin|You can lazily create the destination if it does not yet exist. This allows you fine grained control over which new destinations can be dynamically created in what part of the queue/topic hierarchy + +Queues/Topics can specified using the ActiveMQ Classic [Wildcards](wildcards) syntax. + +#### Authorization Example + +The following [example](http://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/org/apache/activemq/security/jaas-broker.xml) shows these 2 plugins in operation. Though note its very easy to write your own plugin. **Note** that full access rights should generally be given to the ActiveMQ.Advisory destinations because by default an ActiveMQConnection uses destination advisories to get early knowledge of temp destination creation and deletion. In addition, dynamic network connectors use advisories to determine consumer demand. +If necessary, the use of advisories in this manner can be disabled via the _watchTopicAdvisories_ boolean attribute of ActiveMQConnectionFactory and for a networkConnector, via the network connector _staticBridge_(5.6) boolean attribute. + +### Broker-to-Broker Authentication and Authorization + +If you have enabled authentication for a particular message broker, then other brokers that wish to connect to that broker must provide the proper authentication credentials via their element. For example, suppose that we have a network of brokers with the following configuration: + +* The network of brokers comprises two brokers (BrokerA and BrokerB) +* Authentication for BrokerA has been enabled via the example `` element. +* Authentication for BrokerB has not been enabled. +* BrokerA only listens for connections. In other words, BrokerA has a `` element, but no `` elements. + +In order for BrokerB to connect to BrokerA, the corresponding element in BrokerB's XML configuration file must be set up as follows. + +``` + + + +``` + +Note how BrokerB's `` element must provide the proper credentials in order to connect to BrokerA. If authorization has been enabled on BrokerA, then the userName assigned to the `` element must also have the proper authorization credentials. Messages cannot be forwarded from BrokerB to BrokerA if BrokerA has authorization enabled and BrokerB's corresponding `` element's userName has not been given the proper authorization credentials. + +Also, if BrokerA is given a `` element so that it can initiate a connection to BrokerB, then that `` must be given a userName/password combination that is defined in the `` element; this is required even though BrokerB does not have authentication services enabled. + +### Controlling Access To Temporary Destinations + +To control access to temporary destinations, you will need to add a `` element to the `authorizationMap`. Through this element, you control access to all temporary destinations. If this element is not present, read, write, and admin privileges for temporary destinations will be granted to all. In the example below, read, write, and admin privileges for temporary destinations are only granted to those clients that have been assigned to the 'admin' group. + +``` + + .. + + .. + + + + + + + + + + + + + + .. + + .. + +``` + +### LDAP Authentication Using the JAAS Plugin + +New module + +A new/better ldap authorization module is available since 5.6. See [Cached LDAP Authorization Module](cached-ldap-authorization-module) for more info. + +1. Configure the JAAS LDAPLoginModule and the LDAPAuthorizationMap in activemq.xml: + + ``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ``` + +2. Configure the JAAS login.config (I haven't de-duplicated the config yet): + ``` + LdapConfiguration { + org.apache.activemq.jaas.LDAPLoginModule required + initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory + connectionURL="ldap://ldap.acme.com:389" + connectionUsername="cn=mqbroker,ou=Services,dc=acme,dc=com" + connectionPassword=password connectionProtocol=s + authentication=simple + userBase="ou=User,ou=ActiveMQ,ou=systems,dc=acme,dc=com" + userRoleName=dummyUserRoleName + userSearchMatching="(uid={0})" + userSearchSubtree=false + roleBase="ou=Group,ou=ActiveMQ,ou=systems,dc=acme,dc=com" + roleName=cn + roleSearchMatching="(member:=uid={1})" + roleSearchSubtree=true + ; + }; + ``` +3. Import the following LDIF file into the LDAP server: + ``` + version: 1 + # + # Sample LDIF for ActiveMQ LDAP authentication and authorisation + # Passwords are defaulted to "password" - it is your responsibility to change them! + # + # Sets up: + # 1. Bind user + # 2. A sample queue with admin,read,write permission assignments + # 3. ActiveMQ Classic advisory topics + # 4. Two groups - admin and webapp + # 5. Two users - admin and webapp + # 6. Role assignments - admin->admin, webapp->webapp + # + # (c) Robin Bramley 2008 # Provided as is without any warranty of any kind + # + dn: dc=acme,dc=com + dc: acme + objectClass: domain + objectClass: top + + dn: ou=Services,dc=acme,dc=com + ou: Services + objectClass: organizationalUnit + objectClass: top + + dn: cn=mqbroker,ou=Services,dc=acme,dc=com + cn: mqbroker + objectClass: organizationalRole + objectClass: top + objectClass: simpleSecurityObject + userPassword: {SSHA}j0NpveEO0YD5rgI5kY8OxSRiN5KQ/kE4 + description: Bind user for MQ broker + + dn: ou=systems,dc=acme,dc=com + ou: systems + objectClass: organizationalUnit + objectClass: top + + dn: ou=ActiveMQ,ou=systems,dc=acme,dc=com + objectClass: organizationalUnit + objectClass: top + ou: ActiveMQ + + dn: ou=Destination,ou=ActiveMQ,ou=systems,dc=acme,dc=com + objectClass: organizationalUnit + objectClass: top + ou: Destination + + dn: ou=Queue,ou=Destination,ou=ActiveMQ,ou=systems,dc=acme,dc=com + objectClass: organizationalUnit + objectClass: top + ou: Queue + + dn: cn=com.acme.myfirstrealqueue,ou=Queue,ou=Destination,ou=ActiveMQ,ou=syst ems,dc=acme,dc=com + cn: com.acme.myfirstrealqueue + description: A queue + objectClass: applicationProcess + objectClass: top + + dn: cn=admin,cn=com.acme.myfirstrealqueue,ou=Queue,ou=Destination,ou=ActiveM Q,ou=systems,dc=acme,dc=com + cn: admin + description: Admin privilege group, members are roles + member: cn=admin + member: cn=webapp + objectClass: groupOfNames + objectClass: top + + dn: cn=read,cn=com.acme.myfirstrealqueue,ou=Queue,ou=Destination,ou=ActiveMQ ,ou=systems,dc=acme,dc=com + cn: read member: cn=webapp + objectClass: groupOfNames + objectClass: top + + dn: cn=write,cn=com.acme.myfirstrealqueue,ou=Queue,ou=Destination,ou=ActiveM Q,ou=systems,dc=acme,dc=com + cn: write + objectClass: groupOfNames + objectClass: top member: cn=webapp + + dn: ou=Topic,ou=Destination,ou=ActiveMQ,ou=systems,dc=acme,dc=co m + objectClass: organizationalUnit + objectClass: top + ou: Topic + + dn: cn=ActiveMQ.Advisory.Consumer,ou=Topic,ou=Destination,ou=ActiveMQ,ou=sys tems,dc=acme,dc=com + cn: ActiveMQ.Advisory.Consumer + objectClass: applicationProcess + objectClass: top description: Advisory topic about consumers + + dn: cn=read,cn=ActiveMQ.Advisory.Consumer,ou=Topic,ou=Destination,ou=ActiveM Q,ou=systems,dc=acme,dc=com + cn: read member: cn=webapp + objectClass: groupOfNames + objectClass: top + + dn: cn=ActiveMQ.Advisory.TempQueue,ou=Topic,ou=Destination,ou=ActiveMQ,ou=sy stems,dc=acme,dc=com + cn: ActiveMQ.Advisory.TempQueue + description: Advisory topic about temporary queues + objectClass: applicationProcess + objectClass: top + + dn: cn=read,cn=ActiveMQ.Advisory.TempQueue,ou=Topic,ou=Destination,ou=Active MQ,ou=systems,dc=acme,dc=com + cn: read member: cn=webapp + objectClass: groupOfNames + objectClass: top + + dn: cn=ActiveMQ.Advisory.TempTopic,ou=Topic,ou=Destination,ou=ActiveMQ,ou=sy stems,dc=acme,dc=com + cn: ActiveMQ.Advisory.TempTopic + objectClass: applicationProcess + objectClass: top + description: Advisory topic about temporary topics + + dn: cn=read,cn=ActiveMQ.Advisory.TempTopic,ou=Topic,ou=Destination,ou=Active MQ,ou=systems,dc=acme,dc=com + cn: read + member: cn=webapp + objectClass: groupOfNames + objectClass: top + + dn: ou=Group,ou=ActiveMQ,ou=systems,dc=acme,dc=com + objectClass: organizationalUnit + objectClass: top + ou: Group + + dn: cn=admin,ou=Group,ou=ActiveMQ,ou=systems,dc=acme,dc=com + cn: admin + member: uid=admin + objectClass: groupOfNames + objectClass: top + + dn: cn=webapp,ou=Group,ou=ActiveMQ,ou=systems,dc=acme,dc=com + cn: webapp + member: uid=webapp + objectClass: groupOfNames + objectClass: top + + dn: ou=User,ou=ActiveMQ,ou=systems,dc=acme,dc=com + objectClass: organizationalUnit + objectClass: top + ou: User + + dn: uid=admin,ou=User,ou=ActiveMQ,ou=systems,dc=acme,dc=com + uid: admin + userPassword: {SSHA}j0NpveEO0YD5rgI5kY8OxSRiN5KQ/kE4 + objectClass: account + objectClass: simpleSecurityObject + objectClass: top + + dn: uid=webapp,ou=User,ou=ActiveMQ,ou=systems,dc=acme,dc=com + uid: webapp + userPassword: {SSHA}j0NpveEO0YD5rgI5kY8OxSRiN5KQ/kE4 + objectClass: account + objectClass: simpleSecurityObject + objectClass: top + ``` +4. Start up ActiveMQ Classic + +5. Test it out + +### Security and ActiveMQ Classic Components + +Along with the message broker, you can optionally execute several additional "components", such as Camel and/or the Web console. These components establish connections with the broker; therefore, if you have secured your broker (i.e., enabled authentication), you will have to configure these components in order to have them provide the required security credentials (username, password) when they connect to the broker. + +#### Camel + +You may have the following Camel context defined in your broker's XML configuration file. + +``` + + + org.foo.bar + + + + + +``` + +The above configuration is not set up to work within a secure environment. + +If the application is running in an OSGi container, add the following line before the CamelContext definition: + +``` + +``` + +This allows any pre-configured instance of the ActiveMQComponent deployed in the container to take precedence on the default ActiveMQComponent. + +That is, with the above configuration, Camel will establish a connection with ActiveMQ Classic, but will not provide a username and password. Therefore, when ActiveMQ Classic security is enabled, the above configuration results in a security exception. The exception will be thrown multiple times, because Camel will continue to retry the connection. If you're not using Camel, comment out the above XML code. If you are using Camel, add the following bean definition to your broker's XML configuration: + +``` + + + + + + + + + + +``` + +With the above bean definition, Camel will pass the specified security credentials when it connects to the broker. + +If the broker is running in an OSGi container, add the following line after the ActiveMQComponent bean definition: + +``` + +``` + +#### Web Console + +If you want to use the Web Console with a secured broker, you have to change `connectionFactory` bean in your `webapps/admin/WEB-INF/webconsole-embeded.xml` to something like this: + +``` + + + + + +``` + +#### Default Credentials + +Starting with version 5.3, all of the above configuration details are included in the default ActiveMQ Classic configuration. Also, there is a central place where you can set credentials that these components will use to connect to the broker. Just set your desired username and password in the `conf/credentials.properties` file, which by default looks like this: +``` +activemq.username=system activemq.password=manager +``` + +#### Encrypted Passwords + +As of version 5.4.1 you can also use [Encrypted passwords](encrypted-passwords) with your broker + +### Message level Authorization + +It's also possible to authorize each single message using some content based authorization policy of your choosing. In comparison to the other security options described before, Message level Authorization requires a bit more than just some configuration. You have to start with creating a new maven project and add the [activemq-all](https://mvnrepository.com/artifact/org.apache.activemq/activemq-all) maven dependency (in the same version as your activemq installation) to the pom.xml of your new project. +In the next step you have to create a new Java class and let it implement the org.apache.activemq.security.MessageAuthorizationPolicy interface. After that, simply add a method with signature: +``` +public boolean isAllowedToConsume(ConnectionContext context, Message message){...} +``` +to the new Java class. For usage of your own Message level Authorization policy, the Java class has to be packaged as jar and added to the /lib folder of ActiveMQ Classic to make it available. In the last step, it has to be configured on the broker directly by using the * messageAuthorizationPolicy* property or add it to the XML as follows + +``` + + .. + + + + .. + +``` + +Implementing your own custom Security Plugin +-------------------------------------------- + +All of the various security implementations are implemented as [Interceptors](interceptors) so its very easy to add your own custom implementation. Its probably easier to start with one of the [simple implementations](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/security/package-summary.html) though if you are using JAAS you could derive from the [JAAS implementation](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/jaas/package-summary.html). diff --git a/hugo/content/components/classic/documentation/seda.md b/hugo/content/components/classic/documentation/seda.md new file mode 100644 index 0000000000..e5fb0c58f7 --- /dev/null +++ b/hugo/content/components/classic/documentation/seda.md @@ -0,0 +1,9 @@ +--- +title: SEDA +layout: classic-doc +--- + + + +[Staged Event Driven Architecture](https://en.wikipedia.org/wiki/Staged_event-driven_architecture) is a design pattern for building high performance and scalable distributed systems. + diff --git a/hugo/content/components/classic/documentation/selectors.md b/hugo/content/components/classic/documentation/selectors.md new file mode 100644 index 0000000000..f5140dc5b2 --- /dev/null +++ b/hugo/content/components/classic/documentation/selectors.md @@ -0,0 +1,41 @@ +--- +title: Selectors +layout: classic-doc +--- + + + +JMS Selectors +------------- + +Selectors are a way of attaching a filter to a subscription to perform content based routing. Selectors are defined using SQL 92 syntax and typically apply to message headers; whether the standard properties available on a JMS message or custom headers you can add via the JMS code. + +Here is an example +``` +JMSType = 'car' AND color = 'blue' AND weight > 2500 +``` +For more documentation on the detail of selectors see the reference on [javax.jmx.Message](http://java.sun.com/j2ee/1.4/docs/api/javax/jms/Message.html). +ActiveMQ Classic supports some JMS defined properties, as well as some ActiveMQ Classic ones - see [message properies](activemq-classic-message-properties) \- that the selector can use. + +### Using XPath to filter messages + +Apache ActiveMQ Classic also supports XPath based selectors when working with messages containing XML bodies. To use an XPath selector use the following syntax +``` +XPATH '//title\[@lang=''eng''\]' +``` + +**Xalan dependency** + +XPath support requires [Xalan](http://xalan.apache.org/index.html) which is not part of the distribution. The Xalan jars needs to be manually added to lib directory or pulled into your app via maven +``` + + xalan + xalan + 2.6.0 + +``` + +### String Property Conversions / Selecting Against STOMP messages + +The JMS spec states that a String property should not get converted to a numeric when used in a selector. So for example, if a message has the 'age' property set to String '21' then the following selector should not match it: 'age > 18'. Since ActiveMQ Classic support STOMP client which can only send messages with string properties, that restriction is a bit limiting. If you want your JMS selectors to auto-convert String properties the the appropriate number type, just prefix the the selector with 'convert\_string\_expressions:'. If you changed selector in the previous example to be 'convert\_string\_expressions:age > 18', then it would match the message. + diff --git a/hugo/content/components/classic/documentation/shared-file-system-master-slave.md b/hugo/content/components/classic/documentation/shared-file-system-master-slave.md new file mode 100644 index 0000000000..568c4812ef --- /dev/null +++ b/hugo/content/components/classic/documentation/shared-file-system-master-slave.md @@ -0,0 +1,89 @@ +--- +title: Shared File System Master Slave +layout: classic-doc +--- + +[Features](features) > [Clustering](clustering) > [MasterSlave](masterslave) > [Shared File System Master Slave](shared-file-system-master-slave) + +Shared File System Master Slave +------------------------------- + +If you have a SAN or shared file system it can be used to provide _high availability_ such that if a broker is killed, another broker can take over immediately. + +> Ensure your shared file locks work +> +> Note that the requirements of this failover system are a distributed file system like a SAN for which exclusive file locks work reliably. If you do not have such a thing available then consider using [MasterSlave](masterslave) instead which implements something similar but working on commodity hardware using local file systems which ActiveMQ Classic does the replication. +> +> > **OCFS2 Warning** +> > +> > Was testing using OCFS2 and both brokers thought they had the master lock - this is because "OCFS2 only supports locking with 'fcntl' and not 'lockf and flock', therefore mutex file locking from Java isn't supported." +> > +> > From [http://sources.redhat.com/cluster/faq.html#gfs_vs_ocfs2](http://sources.redhat.com/cluster/faq.html#gfs_vs_ocfs2) : +> > OCFS2: No cluster-aware flock or POSIX locks +> > GFS: fully supports Cluster-wide flocks and POSIX locks and is supported. +> > See this JIRA for more discussion: [https://issues.apache.org/jira/browse/AMQ-4378](https://issues.apache.org/jira/browse/AMQ-4378) +> +> > **NFSv3 Warning** +> > +> > In the event of an abnormal NFSv3 client termination (i.e., the ActiveMQ Classic master broker), the NFSv3 server will not timeout the lock that is held by that client. This effectively renders the ActiveMQ Classic data directory inaccessible because the ActiveMQ Classic slave broker can't acquire the lock and therefore cannot start up. The only solution to this predicament with NFSv3 is to reboot all ActiveMQ Classic instances to reset everything. +> > +> > Use of NFSv4 is another solution because its design includes timeouts for locks. When using NFSv4 and the client holding the lock experiences an abnormal termination, by design, the lock is released after 30 seconds, allowing another client to grab the lock. For more information about this, see [this blog entry](http://blogs.netapp.com/eislers_nfs_blog/2008/07/part-i-since-nf.html). + +Basically you can run as many brokers as you wish from the same shared file system directory. The first broker to grab the exclusive lock on the file is the master broker. If that broker dies and releases the lock then another broker takes over. The slave brokers sit in a loop trying to grab the lock from the master broker. + +The following example shows how to configure a broker for Shared File System Master Slave where **/sharedFileSystem** is some directory on a shared file system. It is just a case of configuring a file based store to use a shared directory. +``` + + + +``` +or: +``` + + + +``` +or: +``` + + + +``` +### Startup + +On startup one master grabs an exclusive lock on the broker file directory - all other brokers are slaves and pause waiting for the exclusive lock. + +![](assets/img/Startup.png) + +Clients should be using the [Failover Transport](failover-transport-reference) to connect to the available brokers. e.g. using a URL something like the following +``` +failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616) +``` +Only the master broker starts up its transport connectors and so the clients can only connect to the master. + +### Master failure + +If the master looses the exclusive lock then it immediately shuts down. If a master shuts down or fails, one of the other slaves will grab the lock and so the topology switches to the following diagram + +![](assets/img/MasterFailed.png) + +One of the other slaves immediately grabs the exclusive lock on the file system to them commences becoming the master, starting all of its transport connectors. + +Clients loose connection to the stopped master and then the failover transport tries to connect to the available brokers - of which the only one available is the new master. + +### Master restart + +At any time you can restart other brokers which join the cluster and start as slaves waiting to become a master if the master is shutdown or a failure occurs. So the following topology is created after a restart of an old master... + +![](assets/img/MasterRestarted.png) + +### Scheduler Support + +ActiveMQ Classic maintains information about schedules independent to the settings in the persistence adapter. With a shared file-system it is therefore important to tell ActiveMQ Classic expressly where to store scheduler information. To do this, set the `dataDirectory` attribute on the `broker`, for example: +``` + +``` diff --git a/hugo/content/components/classic/documentation/should-i-deploy-enterprise-integration-patterns-in-the-broker-or-another-application.md b/hugo/content/components/classic/documentation/should-i-deploy-enterprise-integration-patterns-in-the-broker-or-another-application.md new file mode 100644 index 0000000000..243c4bb286 --- /dev/null +++ b/hugo/content/components/classic/documentation/should-i-deploy-enterprise-integration-patterns-in-the-broker-or-another-application.md @@ -0,0 +1,26 @@ +--- +title: Should I deploy Enterprise Integration Patterns in the broker or another application +layout: classic-doc +--- + + + +Should I deploy Enterprise Integration Patterns in the broker or another application +------------------------------------------------------------------------------------ + +Whether you deploy the [Enterprise Integration Patterns](enterprise-integration-patterns) inside the ActiveMQ Classic Broker or in a separate application depends on your requirements. + +### Advantages of deploying EIP inside the broker + +* Its a single JVM so less moving parts and you're less likely to forget to deploy something +* if you are doing things like polling resources such as files, databases and bridging them to queues or topics then its usually more efficient to host in the broker; as there's less contention and there's no network communication between the EIP rules and the message broker as its all in the same JVM (so you can use the [VM Transport](vm-transport-reference) to avoid network overhead. + +### Advantages of deploying EIP inside a separate application + +* its easier to deploy loads of JVMs containing the EIP routing rules to get better load balancing +* you can easily change your routing rules then stop/restart applications without having to restart your broker. Having said that since ActiveMQ Classic supports [auto reconnection](how-can-i-support-auto-reconnection) its not such a big deal to bounce the Broker now and again to refresh routing rules. Note that at some point [Camel will support auto-reload of routing rules on the fly without having to stop and reload the JVM](https://issues.apache.org/activemq/browse/CAMEL-234) so one day this won't be such a big benefit. + +### See Also + +* [Should I deploy the broker inside my JVM or AppServer](should-i-deploy-the-broker-inside-my-jvm-or-appserver) + diff --git a/hugo/content/components/classic/documentation/should-i-deploy-the-broker-inside-my-jvm-or-appserver.md b/hugo/content/components/classic/documentation/should-i-deploy-the-broker-inside-my-jvm-or-appserver.md new file mode 100644 index 0000000000..a35846746b --- /dev/null +++ b/hugo/content/components/classic/documentation/should-i-deploy-the-broker-inside-my-jvm-or-appserver.md @@ -0,0 +1,28 @@ +--- +title: Should I deploy the broker inside my JVM or AppServer +layout: classic-doc +--- + + + +You can deploy the ActiveMQ Classic Broker inside your JVM or Application Server. Whether you do or not has pros and cons depending on how many JVMs you have and what your backup & recovery policy is. + +### Advantages of embedding the broker + +* embedding a broker means you can use the VM transport which avoids the use of sockets and serialization. Instead ActiveMQ Classic can pass around messages by value. + * the slight exception to this is ObjectMessage; the JMS specification says you must serialize the body of the ObjectMessage whenever you send it. However you can [disable this feature](how-should-i-use-the-vm-transport) if you want really high performance when using VM transport +* its only 1 single deployment unit/JVM rather than 2 coupled processes. + +### Disadvantages of embedding the broker + +If you have lots of JVMs (say 100s of them) and have very stringent requirements; you don't ever want to loose a message and so you want to backup and manage the persistent ActiveMQ Classic database (and/or files) very carefully. + +Having an embdded broker inside each JVM could result in large number of sets of files to manage. So it may be simpler to separate the two out, so that your 100s of JVMs talk to a relatively small cluster of brokers (say 2-10 of them) so that you can avoid worrying about persistent state in each JVM and just focus on backing up and managing the files/databases used by the brokers. + +Also its typically easier to run and manage ActiveMQ Classic brokers when they are separate; you can have some ClassLoader issues when trying to embed ActiveMQ Classic inside an application server. e.g. you can sometimes get [ClassPath Errors](javalangnosuchmethoderror) + +### See + +* [How do I embed a Broker inside a Connection](how-do-i-embed-a-broker-inside-a-connection) +* [Run Broker](run-broker) + diff --git a/hugo/content/components/classic/documentation/should-i-run-activemq-classic-on-windows-in-a-directory-with-spaces.md b/hugo/content/components/classic/documentation/should-i-run-activemq-classic-on-windows-in-a-directory-with-spaces.md new file mode 100644 index 0000000000..481f384c2a --- /dev/null +++ b/hugo/content/components/classic/documentation/should-i-run-activemq-classic-on-windows-in-a-directory-with-spaces.md @@ -0,0 +1,14 @@ +--- +title: Should I run ActiveMQ Classic on Windows in a directory with spaces? +layout: classic-doc +--- + + + +Should I run ActiveMQ Classic on Windows in a directory with spaces? +-------------------------------------------------------------------- + +No. + +Its not a good idea to install and run application in paths on Windows which have spaces. + diff --git a/hugo/content/components/classic/documentation/should-i-use-transactions.md b/hugo/content/components/classic/documentation/should-i-use-transactions.md new file mode 100644 index 0000000000..b186f79eae --- /dev/null +++ b/hugo/content/components/classic/documentation/should-i-use-transactions.md @@ -0,0 +1,28 @@ +--- +title: Should I use transactions +layout: classic-doc +--- + + + +There are four main approaches as to a client can consume messages. They are: + +1. Auto-acknowledgement +2. Explicit acknowledgement via `Message.acknowledge()` +3. JMS Transactions +4. XA + +For a discussion on XA see: [Should I use XA](should-i-use-xa) + +The main difference between 1 & 2 and 3 & 4 is the latter allow messages to be rolled back and redelivered if an error occurs whilst processing. There is no JMS 'unacknowledge'. So for this reason JMS transactions should be preferred to message acknowledgements in most use cases. + +It's a common misconception that transactions are inherently slow. In reality there's little difference in performance, from the broker's perspective, between the use of a JMS transaction and invoking `Message.acknowledge()`. However, a performance penalty is incurred when the delivery mode is set to  persistent. This causes the broker to block until the commit is synchronized to disk. This is similar to how `Message.acknowledge()` blocks when using a non-transactional JMS session. + +Transaction support is also available for non-persistent delivery mode. + +Batched Transactions Are The Fastest Way To Process Messages! + +It's worth noting that the fastest way to consume persistent messages is to use a JMS transaction combined with message batching, e.g., have the commit boundary encompass multiple messages, not just one. This applies to both producers and consumers and to clients that are both. + +When using transactions a batch of 1000 messages, say, can be sent in a single atomic step. The message transmission is asynchronous and therefore very fast. The producer need only perform one commit every batch in order to minimize the latency that would otherwise be incurred with disk syncing. + diff --git a/hugo/content/components/classic/documentation/should-i-use-xa.md b/hugo/content/components/classic/documentation/should-i-use-xa.md new file mode 100644 index 0000000000..340e263e5f --- /dev/null +++ b/hugo/content/components/classic/documentation/should-i-use-xa.md @@ -0,0 +1,51 @@ +--- +title: Should I use XA +layout: classic-doc +--- + + + +Should I use XA transactions (two phase commit?) +------------------------------------------------ + +A common use of JMS is to consume messages from a queue or topic, process them using a database or EJB, then acknowledge / commit the message. + +If you are using more than one resource; e.g. reading a JMS message and writing to a database, you really should use XA - its purpose is to provide atomic transactions for multiple transactional resources. For example there is a small window from when you complete updating the database and your changes are committed up to the point at which you commit/acknowledge the message; if there is a network/hardware/process failure inside that window, the message will be redelivered and you may end up processing duplicates. + +The problem with XA is it can be a bit slow; as the XA protocol requires multiple syncs to disk to ensure it can always recover properly under every possible failure scenario. This adds significant cost (in terms of latency, performance, resources and complexity). Also quite a few EJB servers and databases don't actually properly support XA! ![(smile)](https://cwiki.apache.org/confluence/s/en_GB/5997/6f42626d00e36f53fe51440403446ca61552e2a2.1/_/images/icons/emoticons/smile.png) + +Be Careful + +ActiveMQ Classic does not currently support XA Transaction suspend / resume semantics. + +### An alternative to XA + +So a good optimisation is to use regular JMS transactions - with no XA - and just perform some duplicate message detection in your code to check you have not already processed the message. + +For example you can use an [Idempotent Consumer](http://activemq.apache.org/camel/idempotent-consumer.html) from the [Enterprise Integration Patterns](enterprise-integration-patterns) to solve this scenario. + +Or in pseudocode you could use something like the following... +``` +onMessage +try { + if I have not processed this message successfully before { + do some stuff in the database / with EJBs etc + jdbc.commit() (unless auto-commit is enabled on the JDBC) + } + jms.commit() +} catch (Exception e) { + jms.rollback() +} +``` +This leads to **much** better performance since you are not performing many slow syncs to disk (per transaction!) for the XA protocol. The only downside with this approach is it means you have to use some application specific logic to detect if you've processed the message before or not. However its quite common that you'll have some way of detecting this. e.g. if the message contains a purchase order and version; have you stored that purchase order and version in the database yet? + +So provided the message has some kind of ID and version, you can often detect duplicates yourself and so not require to pay the performance cost of XA + +It may also be worth reading [Should I use transactions](should-i-use-transactions). + +### Further optimisation + +Performing duplicate detection can add a performance overhead. e.g. doing a database query to see if you've processed the purchase order before etc. Most of the time things will work; its only in rare circumstances (ilke if a server crashes mid-way processing some messages) that messages get redelivered. + +So you can use the [Message.getJMSRedelivered()](http://java.sun.com/j2ee/1.4/docs/api/javax/jms/Message.html#getJMSRedelivered()) method to detect if a message has been redelivered and only if its been redelivered then perform the duplicate detection check. + diff --git a/hugo/content/components/classic/documentation/slow-consumer-handling.md b/hugo/content/components/classic/documentation/slow-consumer-handling.md new file mode 100644 index 0000000000..07ff2f8f9a --- /dev/null +++ b/hugo/content/components/classic/documentation/slow-consumer-handling.md @@ -0,0 +1,140 @@ +--- +title: Slow Consumer Handling +layout: classic-doc +--- + + + +[Slow Consumers](Design Documents/slow-consumers) can cause problems on non-durable topics since they can force the broker to keep old messages in RAM which once it fills up, forces the broker to slow down producers, causing the fast consumers to be slowed down. One option we could implement in the future is spooling to disk - but then spooling to disk could slow down the fast consumers too. + +Currently we have a strategy that lets you configure the maximum number of matched messages the broker will keep around for a consumer in addition to its prefetch buffer. Once this maximum is reached, as new messages come in, older messages are discarded. This allows you to keep the RAM for current messages and keep sending messages to a slow consumer but to discard old messages. + +Pending Message Limit Strategy +------------------------------ + +You can configure the `PendingMessageLimitStrategy` implementation class on the destination map so that different regions of your topic namespace can have different strategies for dealing with slow consumers. For example you may want to use this strategy for prices which are very high volume but for orders and trades which are lower volume you might not wish to discard old messages. + +The strategy calculates the maximum number of pending messages to be kept in RAM for a consumer (above its prefetch size). A value of zero means keep no messages around other than the prefetch amount. A value greater than zero will keep up to that amount of messages around, discarding the older messages as new messages come in. A value of `-1` disables the discarding of messages. + +There are currently two different implementations of the strategy: + +* `ConstantPendingMessageLimitStrategy` +* `PrefetchRatePendingMessageLimitStrategy` + +### ConstantPendingMessageLimitStrategy + +This strategy uses a constant limit for all consumers (above their prefetch size). + +Example: + +``` + +``` + +### PrefetchRatePendingMessageLimitStrategy + +This strategy calculates the maximum number of pending messages using a multiplier of the consumers prefetch size. So you could for example keep around 2.5 times the prefetch count for each consumer. + +``` + +``` + +### Using the Prefetch Policy to Configure the Limit + +The JMS Client has a [prefetch policy](what-is-the-prefetch-limit-for) you can use to configure the various prefetch limits for persistent and non persistent queues and topics. The prefetch policy also allows you to specify the `maximumPendingMessageLimit` on a per connection/consumer basis. One minor difference with configuring this value; to simplify operation with non-JMS clients such as with [OpenWire](openwire) the value of zero is ignored; so the lowest value you can configure is `1`. + +### Configuring the Eviction Policy + +We have a `MessageEvictionStrategy` which is used to decide which message should be evicted on a slow consumer. The default implementation is: + +``` + +``` + +However, you can write your own to use some application specific way of choosing messages for eviction. For example, if you are sending market data price updates you may wish to find an older price value, which might not be the oldest message. + +Example: + +``` + + +``` +where `propertyName` is the JMS message property that specifies the price. + +Another option could be to use the oldest message with the lowest priority message. Therefore if you have some high priority messages, evict the lower priority messages first even if they are newer. + +``` + +``` + +Example +------- + +The following example shows an ActiveMQ Classic broker configuration file. Notice that for topics in the `PRICES.>` wildcard range the `pendingMessageLimitStrategy` property is set to only keep around `10` messages for each consumer above their prefetch buffer size. + +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +Usage Tips +---------- + +It is advisable that if you know a particular consumer is going to be slow then set its prefetch size to something smaller than the fast consumers! + +For example, if you know a particular server is quite slow and you have very high message rates _and_ you have some very fast consumers then you might want to enable this feature and set the prefetch on the slow servers to be a _little_ lower than on the fast servers. + +### Monitoring the Status of Slow Consumers + +You can also use a [JMX](jmx) Console to view the statistics of the active subscriptions. This allows you to view the following statistics on a `TopicSubscriptionViewMBean`: + +Statistic|Definition +---|--- +`discarded`|The count of how many messages have been discarded during the lifetime of the subscription due to it being a slow consumer +`matched`|The current number of messages matched and to be dispatched to the subscription as soon as some capacity is available in the prefetch buffer. So a non-zero value implies that the prefetch buffer is full for this subscription + diff --git a/hugo/content/components/classic/documentation/slow-networks-drop-large-messages.md b/hugo/content/components/classic/documentation/slow-networks-drop-large-messages.md new file mode 100644 index 0000000000..4727e18c72 --- /dev/null +++ b/hugo/content/components/classic/documentation/slow-networks-drop-large-messages.md @@ -0,0 +1,48 @@ +--- +title: Slow networks drop large messages +layout: classic-doc +--- + + + +Note + +This article only applies to older versions of ActiveMQ Classic, i.e. 5.3 and 5.4.0. From 5.4.2 onwards this issue has been adressed in the bugs [AMQ-2511](https://issues.apache.org/jira/browse/AMQ-2511) and [AMQ-2088](https://issues.apache.org/jira/browse/AMQ-2088). + +You may experience problems sending large messages using networks across slow links. + +The symptoms are usually that the network connection will be dropped and continuously re-established. + +This problem arises because the ActiveMQ Classic message broker continuously checks for activity on a socket, and whilst building a large message in the TCP socket buffer, the [inactivity](activemq-inactivitymonitor) monitor will time out - see [Configuring Wire Formats](configuring-wire-formats) and the [TCP Transport Reference](tcp-transport-reference). +The [inactivity monitor](activemq-inactivitymonitor) uses an activity flag that is only updated after a message is received (in case the connection is not idle). +The monitor then clears the activity flag, waits the timeout amount and peeks at the activity flag. If it's still cleared, then we assume the connection was inactive. When the connection is NOT in use, a keep alive message is sent. But in case the connection is in use because of a larger message being sent/received, no keep alive will be sent and the activity flag will not be updated. That can lead to inactivity timeouts. +Ideally the activity flag would get cleared every time a few bytes arrive from the network... but right now it is only cleared when an entire message is assembled. + +You can either set the wireFormat.maxInactivityDuration property to a high value - or disable it (set it to zero) to work around this issue. + +e.g. configure your network connection like this: + + + + + + + + + + + + + + + + + + + + + +### See also + +[ActiveMQ Classic InactivityMonitor](activemq-inactivitymonitor) + diff --git a/hugo/content/components/classic/documentation/source-xref.md b/hugo/content/components/classic/documentation/source-xref.md new file mode 100644 index 0000000000..7adc67656d --- /dev/null +++ b/hugo/content/components/classic/documentation/source-xref.md @@ -0,0 +1,10 @@ +--- +title: Source XRef +layout: classic-doc +--- + +## Source XRef + +- [ActiveMQ Classic Core](http://activemq.apache.org/maven/activemq-core/xref/) +- [ActiveMQ Classic Resource Adapter](http://activemq.apache.org/maven/activemq-ra/xref/) +- [ActiveMQ Classic Web](http://activemq.apache.org/maven/activemq-web/xref/) diff --git a/hugo/content/components/classic/documentation/source.md b/hugo/content/components/classic/documentation/source.md new file mode 100644 index 0000000000..4e92fafa2d --- /dev/null +++ b/hugo/content/components/classic/documentation/source.md @@ -0,0 +1,56 @@ +--- +title: Source +layout: classic-doc +--- + +ActiveMQ Classic source code +============================ + +Web Browsing of the git Repo +---------------------------- + +To browse via the web: + +[https://git-wip-us.apache.org/repos/asf?p=activemq.git](https://git-wip-us.apache.org/repos/asf?p=activemq.git) + +Checking out from the git Repo +------------------------------ + +git clone [https://git-wip-us.apache.org/repos/asf/activemq.git](https://git-wip-us.apache.org/repos/asf/activemq.git) + +Only project developers can commit to the git repo via this method. SSH must be installed on your client machine. Enter your site password when prompted. + +Building the code +----------------- + +To then build the code, see [Building](building). + +ActiveMQ Artemis +================ + +Web Browsing of the ASF git Repo +-------------------------------- + +To browse via the web: + +[https://git-wip-us.apache.org/repos/asf?p=activemq-artemis.git](https://git-wip-us.apache.org/repos/asf?p=activemq-artemis.git) + +Browsing the Github Repo  +------------------------- + +[https://github.com/apache/activemq-artemis](https://github.com/apache/activemq-artemis) + +Checking out from the Github Repo +--------------------------------- + +git clone [https://github.com/apache/activemq-artemis](https://github.com/apache/activemq-artemis) + +**Committers:** Please follow the instructions for properly configuring the [Instructions for Core Contributors/Hacking Guide](https://github.com/apache/activemq-artemis/blob/master/docs/hacking-guide/enSUMMARY) + +**Contributors:** Please create a [pull request](https://github.com/apache/activemq-artemis) to contribute changes to the source code.  + +Building the code +----------------- + +To then build the code, take a look at [Building the distribution](https://github.com/apache/activemq-artemis/blob/master/docs/hacking-guide/enDevelopers/Developers/building) + diff --git a/hugo/content/components/classic/documentation/spring-support.md b/hugo/content/components/classic/documentation/spring-support.md new file mode 100644 index 0000000000..2ee7c13b9a --- /dev/null +++ b/hugo/content/components/classic/documentation/spring-support.md @@ -0,0 +1,113 @@ +--- +title: Spring Support +layout: classic-doc +--- + + + +We fully support Spring for configuration of the JMS client side as well as for configuring the JMS Message Broker. +There is a great [article](https://medium.com/@bdarfler/efficient-lightweight-jms-with-spring-and-activemq-51ff6a135946) on using Spring with ActiveMQ Classic - I'd recommend reading it first. + +Configuring the JMS client +-------------------------- + +To configure an ActiveMQ Classic JMS client in Spring it is just a simple matter of configuring an instance of ActiveMQConnectionFactory within a standard Spring XML configuration file like any other bean. There are [several examples and test cases](https://github.com/apache/activemq/tree/main/activemq-unit-tests/src/test/java/org/apache/activemq/spring/) available and [this one](https://github.com/apache/activemq/tree/main/activemq-unit-tests/src/test/resources/org/apache/activemq/xbean/spring.xml) shows how to construct an ActiveMQConnectionFactory in Spring which is then passed into a Spring JmsTemplate for use by some POJOs. + +e.g. the following fragment of XML shows us creating a JMS connection factory for ActiveMQ Classic connecting to a remote broker on a specific host name and port. +``` + + + tcp://localhost:61616 + + +``` +The following shows how to use Zeroconf to discover the available brokers to connect to. +``` + + + zeroconf://_activemq.broker.development. + + +``` +From 1.1 of ActiveMQ Classic onwards you can also use JNDI to configure ActiveMQ Classic within Spring. [This example](http://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/spring-jndi.xml) shows how to configure Spring using ActiveMQ Classic's [JNDI Support](jndi-support). + +### Using Spring + +If you are using the new [XML Schema-based configuration](http://static.springframework.org/spring/docs/2.0.x/reference/xsd-config.html) of Spring 2.0 you can embed the ActiveMQ Classic broker XML inside any regular Spring.xml file without requiring the above factory bean. e.g. here is an example of a regular Spring XML file in Spring 2.0 which also configures a broker. + +``` + + + + + + + + + + +``` +This allows you to configure JMS artifacts like destinations and connection factories together with the entire broker. + +Working with Spring's JmsTemplate +--------------------------------- + +Spring supports a handy abstraction, JmsTemplate, which allows you to hide some of the lower level JMS details when sending messages etc. + +Please be aware that there are a number of [JmsTemplate Gotchas](jmstemplate-gotchas) to be careful of. + +One thing to bear in mind with JmsTemplate is that by default it will create a new connection, session, producer for each message sent - then close them all down again. This is very inefficient! It is done like this to work in EJB containers which tend to use a special ConnectionFactory which does pooling. + +If you are not using a JCA container to manage your JMS connections, we recommend you use our pooling JMS connection provider, (org.apache.activemq.pool.PooledConnectionFactory) from the `activemq-pool` library, which will pool the JMS resources to work efficiently with Spring's JmsTemplate or with EJBs. + +e.g. + +``` + + + + + + tcp://localhost:61616 + + + + + + + + + + + +``` +The `PooledConnectionFactory` supports the pooling of Connection, Session and MessageProducer instances so it can be used with tools like [Camel](http://camel.apache.org/activemq.html) and Spring's [JmsTemplate and MessagListenerContainer](spring-support) . Connections, sessions and producers are returned to a pool after use so that they can be reused later without having to undergo the cost of creating them again. + +Note: while the `PooledConnectionFactory` does allow the creation of a collection of active consumers, it does not 'pool' consumers. Pooling makes sense for connections, sessions and producers, which can be seldom-used resources, are expensive to create and can remain idle a minimal cost. Consumers, on the other hand, are usually just created at startup and left going, handling incoming messages as they come. When a consumer is complete, it's preferred to shut down it down rather than leave it idle and return it to a pool for later reuse: this is because, even if the consumer is idle, ActiveMQ Classic will keep delivering messages to the consumer's prefetch buffer, where they'll get held up until the consumer is active again. + +If you are creating a collection of consumers (for example, for multi-threaded message consumption), you should consider keeping a low prefetch value (e.g. 10 or 20), to ensure that all messages don't end up going to just one of the consumers. + +We do also have a pooling JMS ConnectionFactory for use inside a JCA / MDB container (org.apache.activemq.ra.InboundConnectionProxyFactory), when using our JCA Resource Adapter which will reuse the same JMS connection/session which is being used for inbound messages. + +Consuming JMS from inside Spring +-------------------------------- + +Spring's [MessagListenerContainer](http://static.springsource.org/spring/docs/2.5.x/reference/FAQ/jms.md#jms.mdp) should be used for message consumption. This provides all the power of MDBs - efficient JMS consumption and pooling of the message listeners - but without requiring a full EJB container. + +You can use the `activemq-pool` `org.apache.activemq.pool.PooledConnectionFactory` for efficient pooling of the connections and sessions for your collection of consumers, or you can use the Spring JMS `org.springframework.jms.connection.CachingConnectionFactory` to achieve the same effect. + +More Information +---------------- + +Also check out the following blogs for information about using Spring JMS with ActiveMQ Classic: + +* [Synchronous Request Response with ActiveMQ Classic and Spring](http://codedependents.com/2010/03/04/synchronous-request-response-with-activemq-and-spring/) +* [Using Spring to Send JMS Messages](http://bsnyderblog.blogspot.com/2010/02/using-spring-jmstemplate-to-send-jms) +* [Using Spring to Receive JMS Messages](http://bsnyderblog.blogspot.com/2010/02/using-spring-to-receive-jms-messages.html) +* [Tuning JMS Message Consumption In Spring](http://bsnyderblog.blogspot.com/2010/05/tuning-jms-message-consumption-in.html) + diff --git a/hugo/content/components/classic/documentation/stomp.md b/hugo/content/components/classic/documentation/stomp.md new file mode 100644 index 0000000000..662726f78f --- /dev/null +++ b/hugo/content/components/classic/documentation/stomp.md @@ -0,0 +1,282 @@ +--- +title: Stomp +layout: classic-doc +--- + + +ActiveMQ Classic supports the [Stomp](http://stomp.github.com/) protocol and the Stomp - JMS mapping. This makes it easy to write a client in pure [Ruby](#), [Perl](#), [Python](#) or [PHP](#) for working with ActiveMQ Classic. + +Please see the [Stomp site](http://stomp.github.io/) for more details + +Spec Compliance + +ActiveMQ Classic v5.6 implements the Stomp v1.1 spec except for allowing spaces at the beginning or end of message header keys, they are preserved in the header values however. In future releases this will not be the case, clients should be updated and user code checked to ensure that spaces in the headers are there intentionally and not as a accident or a client "feature". + +### Enabling the ActiveMQ Classic Broker for Stomp + +To enable STOMP protocol support in the broker add a transport connector definition whose URI scheme is `stomp`. + +Example: +``` + + + +``` +To see a full example, try [this XML](http://svn.apache.org/repos/asf/activemq/trunk/assembly/src/release/example/conf/activemq.xml). If you save that XML as `foo.xml` then you can run stomp via the command line as +``` +activemq xbean:foo.xml +``` +For more help see [Run Broker](run-broker). + +### The Stomp Wire Format + +Stomp uses a text based wire format that can be configured with the following options.  All options can be configured on a Brokers transport bind URI. + +Parameter Name|Default Value|Description +---|---| +`maxDataLength`|`104857600`|Maximum size of the message body (content) that can be sent. +`maxFrameSize`|`MAX_LONG`|**From ActiveMQ Classic 5.12.0**: maximum frame size that can be sent. A Stomp frame includes a command, optional headers, and an optional body. Can help help prevent OOM DOS attacks + +Example: +``` + +``` + +> **Use the Correct Prefix!** +> +> Wire format options must have the prefix `wireFormat.` to take effect, e.g., ``wireFormat.`maxDataLength`=100000``. Options missing this prefix will be ignored. + +### Security + +**From ActiveMQ Classic 5.1**: Stomp fully supports [ActiveMQ Classic's security](security) mechanism. This means that the `CONNECT` command will return an `ERROR` STOMP frame on unsuccessful authentication. Also, the authorization policies will be applied when you try to access (read/write) certain destinations. If you use synchronous operations (by using [receipts](http://stomp.github.com/stomp-specification-1.1.html#RECEIPT)), you can expect an `ERROR` frame in case of unauthorized access attempt. In other case, operations will be discarded but the client will not be informed of errors. This applies to all errors that can occur broker-side. + +> **SSL** +> +> For additional security, you can use Stomp over SSL as described in the following section. + +### Enabling Stomp over NIO + +**From ActiveMQ Classic 5.3**: for better scalability and performance the Stomp protocol can be configured to be run over the NIO transport. The [NIO transport](configuring-transports.md) will use far fewer threads than the corresponding TCP connector. This can help when support for a [large number of queues](how-do-i-configure-10s-of-1000s-of-queues-in-a-single-broker) is required. To use NIO change the URI scheme of the transport connector to `stomp+nio`. + +Example: +``` + +``` + +### Enabling Stomp over SSL + +To configure ActiveMQ Classic to use Stomp over an SSL connection change the URI scheme to `stomp+ssl`. + +Example: +``` + +``` +For more details on using SSL with ActiveMQ Classic see the following article ([How do I use SSL](http://activemq.apache.org/how-do-i-use-ssl)). An example of using Stomp over SSL on the client side can be found in the [PHP Stomp client example](http://stomp.fusesource.org/documentation/php/book.html#SSL). + +### Heart-Beat Grace Period + +The STOMP protocol (version 1.1 or greater) [defines the concept of heart beats](http://stomp.github.io/stomp-specification-1.2.html#Heart-beating) as a method by which a client and broker can determine the health of the underlying TCP connection between them. ActiveMQ Classic supports STOMP heart beating provided the client is using version 1.1 (or greater) of the protocol. + +**Before ActiveMQ Classic 5.9.0**: enforcement of the 'read' heart-beat timeout (that is, a heart-beat sent from the client to the broker) was strict. In other words, the broker was intolerant of late arriving read heart-beats from the client. This resulted in the broker concluding that the client was no longer present causing it to close its side of the client's connection when the client failed to honor it's configured heart-beat settings. + +**From ActiveMQ Classic 5.9.0**: the timeout enforcement for read heart-beats is now configurable via a new transport option `transport.hbGracePeriodMultiplier`: +``` + + + +``` +This multiplier is used to calculate the effective read heart-beat timeout the broker will enforce for each client's connection. The multiplier is applied to the read-timeout interval the client specifies in its `CONNECT` frame: +``` + * == +``` +For backward compatibility, if the grace period multiplier is not configured the default enforcement mode remains strict, e.g., `transport.hbGracePeriodMultiplier=1.0`. Attempts to configure the grace period multiplier to a value less than, or equal to `1.0` will be silently ignored. + +STOMP clients that wish to be tolerant of late arriving heart-beats from the broker must implement their own solution for doing so. + +* Please check the [STOMP specification](http://stomp.github.io/stomp-specification-1.2.html#Heart-beating) for the details on heart-beating + +* The JIRA that implemented this: [ActiveMQ Classic 5.x does not support the notion of a grace-period for heart beats as supported by the STOMP protocol](https://issues.apache.org/jira/browse/AMQ-4674) + + +### Working with Destinations with Stomp + +Note that the prefix in stomp `/queue/` or `/topic/` is removed from the string before passing it to ActiveMQ Classic as a JMS destination. Also note that the default separator in MOM systems is `.` (dot). Whilst `FOO.BAR` is the normal syntax to identify a queue type destination the Stomp equivalent is `/queue/FOO.BAR` + +> **Be careful about starting destinations with `/`** +> +> If in Stomp world you use `/queue/foo/bar` then in a JMS world the queue would be called `foo/bar` not `/foo/bar`. + +> **Persistent Messaging in STOMP** +> +> STOMP messages are non-persistent by default. To use persistent messaging add the following STOMP header to all `SEND` requests: `persistent:true`. This default is the opposite of that for JMS messages. + +### Working with JMS Text/Bytes Messages and Stomp + +Stomp is a very simple protocol - that's part of the beauty of it! As such, it does not have knowledge of JMS messages such as `TextMessage`'s or `BytesMessage`'s. The protocol does however support a `content-length` header. To provide more robust interaction between STOMP and JMS clients, ActiveMQ Classic keys off of the inclusion of this header to determine what message type to create when sending from Stomp to JMS. The logic is simple: + +Inclusion of content-length header|Resulting Message +---|--- +yes|`BytesMessage` +no|`TextMessage` + +This same logic can be followed when going from JMS to Stomp, as well. A Stomp client could be written to key off of the inclusion of the `content-length` header to determine what type of message structure to provide to the user. + +### Message Transformations + +The `transformation` message header on `SEND` and `SUBSCRIBE` messages could be used to instruct ActiveMQ Classic to transform messages from text to the format of your desire. Currently, ActiveMQ Classic comes with a transformer that can transform XML/JSON text to Java objects, but you can add your own transformers as well. + +Here's a quick example of how to use built-in transformer (taken from test cases) +``` +private String xmlObject = "\n" + + " Dejan\n" + + " Belgrade\n" + + ""; + +public void testTransformationReceiveXMLObject() throws Exception { + + MessageProducer producer = session.createProducer(new ActiveMQQueue("USERS." + getQueueName())); + ObjectMessage message = session.createObjectMessage(new SamplePojo("Dejan", "Belgrade")); + producer.send(message); + + String frame = "CONNECT\n" + "login: system\n" + "passcode: manager\n\n" + Stomp.NULL; + stompConnection.sendFrame(frame); + + frame = stompConnection.receiveFrame(); + assertTrue(frame.startsWith("CONNECTED")); + + frame = "SUBSCRIBE\n" + "destination:/queue/USERS." + getQueueName() + "\n" + "ack:auto" + "\n" + "transformation:jms-object-xml\n\n" + Stomp.NULL; + stompConnection.sendFrame(frame); + + frame = stompConnection.receiveFrame(); + + assertTrue(frame.trim().endsWith(xmlObject)); + + frame = "DISCONNECT\n" + "\n\n" + Stomp.NULL; + stompConnection.sendFrame(frame); +} +``` + +> **Dependencies** +> +> ActiveMQ Classic uses [XStream](http://xstream.codehaus.org) for its transformation needs. Since it's the optional dependency you have to add it to broker's classpath by putting the appropriate JAR into the `lib/` folder. Additionally, if you plan to use JSON transformations you have to add [Jettison](http://jettison.codehaus.org/) JSON parser to the classpath. + +In order to create your own transformer, you have to do the following: + +1. Build your transformer by implementing a [FrameTranslator](http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/transport/stomp/FrameTranslator.html) interface + +2. Associate it with the appropriate header value by creating a file named as a value you want to use in the `META-INF/services/org/apache/activemq/transport/frametranslator/` folder of your JAR which will contain the value `class=_fully qualified classname of your transformer_` + + +For example the built-in transformer contains the following value: +``` +class=org.apache.activemq.transport.stomp.XStreamFrameTranslator +``` +in the `META-INF/services/org/apache/activemq/transport/frametranslator/jms-xml` file. + +### Debugging + +In case you want to debug Stomp communication between broker and clients you should configure the Stomp connector with the `trace` parameter, like this: +``` + + + +``` +This will instruct the broker to trace all packets it sends and receives. + +Furthermore, you have to enable tracing for the appropriate log. You can achieve that by adding the following to your `conf/log4j.properties` +``` +log4j.logger.org.apache.activemq.transport.stomp=TRACE +``` +Finally, you will probably want to keep these messages in the separate file instead of polluting the standard broker's log. You can achieve that with the following log4j configuration: +``` +log4j.appender.stomp=org.apache.log4j.RollingFileAppender +log4j.appender.stomp.file=${activemq.base}/data/stomp.log +log4j.appender.stomp.maxFileSize=1024KB +log4j.appender.stomp.maxBackupIndex=5 +log4j.appender.stomp.append=true +log4j.appender.stomp.layout=org.apache.log4j.PatternLayout +log4j.appender.stomp.layout.ConversionPattern=%d \[%-15.15t\] %-5p %-30.30c{1} - %m%n + +log4j.logger.org.apache.activemq.transport.stomp=TRACE, stomp +log4j.additivity.org.apache.activemq.transport.stomp=false + +# Enable these two lines and disable the above two if you want the frame IO ONLY (e.g., no heart beat messages, inactivity monitor etc). +#log4j.logger.org.apache.activemq.transport.stomp.StompIO=TRACE, stomp +#log4j.additivity.org.apache.activemq.transport.stomp.StompIO=false +``` +After this, all your Stomp packets will be logged to the `data/stomp.log` + +### Java API + +**From ActiveMQ Classic 5.2**: there is a simple Java Stomp API distributed with ActiveMQ Classic. Note that this API is provided purely for testing purposes and you should always consider using standard JMS API from Java instead of this one. The following code snippet provides a simple example of using this API: +``` +StompConnection connection = new StompConnection(); +connection.open("localhost", 61613); + +connection.connect("system", "manager"); +StompFrame connect = connection.receive(); + +if(!connect.getAction().equals(Stomp.Responses.CONNECTED)) { + throw new Exception ("Not connected"); +} + +connection.begin("tx1"); +connection.send("/queue/test", "message1", "tx1", null); +connection.send("/queue/test", "message2", "tx1", null); +connection.commit("tx1"); + +connection.subscribe("/queue/test", Subscribe.AckModeValues.CLIENT); + +connection.begin("tx2"); + +StompFrame message = connection.receive(); +System.out.println(message.getBody()); +connection.ack(message, "tx2"); + +message = connection.receive(); +System.out.println(message.getBody()); +connection.ack(message, "tx2"); + +connection.commit("tx2"); + +connection.disconnect(); +``` +This example is part of the standard ActiveMQ Classic distribution. You can run it from the `./example` folder with: +``` +ant stomp +``` + +### Stomp Extensions for JMS Message Semantics + +Note that STOMP is designed to be as simple as possible - so any scripting language/platform can message any other with minimal effort. STOMP allows pluggable headers on each request such as sending & receiving messages. ActiveMQ Classic has several extensions to the Stomp protocol, so that JMS semantics can be supported by Stomp clients. An OpenWire JMS producer can send messages to a Stomp consumer, and a Stomp producer can send messages to an OpenWire JMS consumer. And Stomp to Stomp configurations, can use the richer JMS message control. + +STOMP supports the following standard JMS properties on `SENT` messages: + +STOMP Header|JMS Header|Description +---|---|--- +`correlation-id`|`JMSCorrelationID`|Good consumers will add this header to any responses they send. +`expires`|`JMSExpiration`|Expiration time of the message. +`JMSXGroupID`|`JMSXGroupID`|Specifies the [Message Groups.](message-groups) +`JMSXGroupSeq`|`JMSXGroupSeq`|Optional header that specifies the sequence number in the [Message Groups.](message-groups) +`persistent`|`JMSDeliveryMode`|Whether or not the message is persistent. +`priority`|`JMSPriority`|Priority on the message. +`reply-to`|`JMSReplyTo`|Destination you should send replies to. +`type`|`JMSType`|Type of the message. + +### ActiveMQ Classic Extensions to STOMP + +You can add custom headers to STOMP commands to configure the ActiveMQ Classic protocol. Here are some examples: + +Verb|Header|Type|Description +---|---|--- +`CONNECT`|`client-id`|`string`|Specifies the JMS clientID which is used in combination with the `activemq.subcriptionName` to denote a durable subscriber. +`SUBSCRIBE`|`activemq.dispatchAsync`|`boolean`|Should messages be dispatched synchronously or asynchronously from the producer thread for non-durable topics in the broker? For fast consumers set this to `false`. For slow consumers set it to `true` so that dispatching will not block fast consumers. +`SUBSCRIBE`|`activemq.exclusive`|`boolean`|I would like to be an [Exclusive Consumer](exclusive-consumer) on the queue. +`SUBSCRIBE`|`activemq.maximumPendingMessageLimit`|`int`|For [Slow Consumer Handling](slow-consumer-handling) on non-durable topics by dropping old messages - we can set a maximum-pending limit, such that once a slow consumer backs up to this high water mark we begin to discard old messages. +`SUBSCRIBE`|`activemq.noLocal`|`boolean`|Specifies whether or not locally sent messages should be ignored for subscriptions. Set to `true` to filter out locally sent messages. +`SUBSCRIBE`|`activemq.prefetchSize`|`int`|Specifies the maximum number of pending messages that will be dispatched to the client. Once this maximum is reached no more messages are dispatched until the client acknowledges a message. Set to a low value > **1** for fair distribution of messages across consumers when processing messages can be slow. **Note**: if your STOMP client is implemented using a dynamic scripting language like Ruby, say, then this parameter **_must_** be set to `1` as there is no notion of a client-side message size to be sized. STOMP does not support a value of `0`. +`SUBSCRIBE`|`activemq.priority`|`byte`|Sets the priority of the consumer so that dispatching can be weighted in priority order. +`SUBSCRIBE`|`activemq.retroactive`|`boolean`|For non-durable topics make this subscription [retroactive](retroactive-consumer). +`SUBSCRIBE`|`activemq.subscriptionName`|`string`|For durable topic subscriptions you must specify the same `activemq.client-id` on the connection and `activemq.subcriptionName` on the subscribe prior to v5.7.0. **Note**: the spelling `subcriptionName` NOT `subscriptionName`. This is not intuitive, but it is how it is implemented in ActiveMQ Classic 4.x. For the 5.0 release of ActiveMQ Classic, both `subcriptionName` and `subscriptionName` will be supported (`subcriptionName` was removed as of v5.6.0). +`SUBSCRIBE`|`selector`|`string`|Specifies a JMS Selector using SQL 92 syntax as specified in the JMS 1.1 specification. This allows a filter to be applied to each message as part of the subscription. + diff --git a/hugo/content/components/classic/documentation/subscription-recovery-policy.md b/hugo/content/components/classic/documentation/subscription-recovery-policy.md new file mode 100644 index 0000000000..3a1835211c --- /dev/null +++ b/hugo/content/components/classic/documentation/subscription-recovery-policy.md @@ -0,0 +1,37 @@ +--- +title: Subscription Recovery Policy +layout: classic-doc +--- + + + +The subscription recovery policy allows you to go back in time when you subscribe to a topic. + +For example imagine you are processing a price feed; you're using a federated network and either a network glitch occurs or someone kills the broker you're talking to. If you reconnect to another broker in the cluster you may have lost messages. + +So we support a timed or fixed size recovery buffer so that if you reconnect to another broker within some time period (depending on volume & RAM this could be 30 seconds to 5 minutes), then any messages you missed during the downtime are redelivered before new messages are delivered to you. + +For more information see [Retroactive Consumer](retroactive-consumer) + +### Last image caching + +Its often common in financial market data type worlds to want to know the latest price of say IBM stock along with get all the future updates to the price. Historically you often had a request-reply snapshot quote service for the latest price, then you subscribe to a topic for updates. The issue is the client then has 2 APIs / middlewares to deal with - often quite different things - plus you have an ordering issue (race condition) - the update could beat the last price request so you can get out of order (going back in time to an old price, which could be very old). + +One of our _subscription recovery policy_ implementations is called **Last Image Subscription Policy** which will ensure that when you subscribe to a topic (say PRICES.NASDAQ.IBM), you will receive the last image (the last message that was sent on that topic) plus any updates which occur in the future, with ordering to ensure that the last image is always first before any new messages arrive. + +A common problem in market data type situations is that you may have a cache of last image prices, then a feed of new price changes; if you request the last price from the cache and subscribe to new prices; depending on how you do it you can either, miss an update or receive a newer update before the old last image arrives (so either get out of order messages). + +Note that you can configure the subscription recovery policy, and most other policies on different destinations or wildcards. So you may use last image policy for prices on topics only and use a buffered fixed size policy for other notifications on different topics etc. + +### Summary of Available Recovery Policies + +Policy Name|Sample Configuration|Description +---|---|--- +FixedSizedSubscriptionRecoveryPolicy|``|Keep a fixed amount of memory in RAM for message history which is evicted in time order. +FixedCountSubscriptionRecoveryPolicy|``|Keep a fixed count of last messages. +LastImageSubscriptionRecoveryPolicy|``|Keep only the last message. +NoSubscriptionRecoveryPolicy|``|Disables message recovery. +QueryBasedSubscriptionRecoveryPolicy|``|Perform a user specific query mechanism to load any message they may have missed. Details on message selectors are available [here](http://java.sun.com/j2ee/1.4/docs/api/javax/jms/Message.html) +TimedSubscriptionRecoveryPolicy|``|Keep a timed buffer of messages around in memory and use that to recover new subscriptions. Recovery time is in milliseconds. +RetainedMessageSubscriptionRecoveryPolicy|``|Keep the last message with ctiveMQ.Retain property set to true + diff --git a/hugo/content/components/classic/documentation/test-source-xref.md b/hugo/content/components/classic/documentation/test-source-xref.md new file mode 100644 index 0000000000..c310874ee1 --- /dev/null +++ b/hugo/content/components/classic/documentation/test-source-xref.md @@ -0,0 +1,9 @@ +--- +title: Test Source XRef +layout: classic-doc +--- + +## Test Source XRef + +- [ActiveMQ Classic Resource Adapter](http://activemq.codehaus.org/maven/activemq-ra/xref-test/) +- [ActiveMQ Classic Web](http://activemq.codehaus.org/maven/activemq-web/xref-test/) diff --git a/hugo/content/components/classic/documentation/the-broker-will-not-start.md b/hugo/content/components/classic/documentation/the-broker-will-not-start.md new file mode 100644 index 0000000000..013b4d702d --- /dev/null +++ b/hugo/content/components/classic/documentation/the-broker-will-not-start.md @@ -0,0 +1,13 @@ +--- +title: The Broker will not start +layout: classic-doc +--- + + + +It's been reported that during broker start some users get a message similar to: + +15:26:29 INFO Opening journal. Caught: javax.jms.JMSException: Failed to open transaction journal: java.io.IOException: Invalid argument + +It could be [this problem](journal-is-already-opened-by-this-application) or the problem could be due to a bad os/jvm combination. See [Known Bad OS and JVM Combinations](known-bad-os-and-jvm-combinations) + diff --git a/hugo/content/components/classic/documentation/the-vm-transport-starts-a-broker-before-my-configured-broker-starts.md b/hugo/content/components/classic/documentation/the-vm-transport-starts-a-broker-before-my-configured-broker-starts.md new file mode 100644 index 0000000000..6401a30b99 --- /dev/null +++ b/hugo/content/components/classic/documentation/the-vm-transport-starts-a-broker-before-my-configured-broker-starts.md @@ -0,0 +1,23 @@ +--- +title: The vm transport starts a broker before my configured broker starts +layout: classic-doc +--- + + + +### Scenario + +You are using the **vm:** transport and a broker is auto-started for you so that your configured embedded broker doesn't start. + +### Solution + +Its most likely a dependency issue; your JMS connection is starting before your embedded broker. So just make sure your embedded broker is started first. + +Another cause could be that your use of the [VM Transport](vm-transport-reference) defines a broker name of localhost whereas your embedded broker uses a different name; so just be consistent in the naming. + +ActiveMQ Classic 5.2 adds the waitForStart='timeout in milliseconds' option to the VM transport which forces the VM transport to wait till the broker is started. Coupled with the "create=false" option, it is possible to ensure that a single embedded broker is auto-started. + +### See also + +* [VM Transport Reference](vm-transport-reference) + diff --git a/hugo/content/components/classic/documentation/throughput.md b/hugo/content/components/classic/documentation/throughput.md new file mode 100644 index 0000000000..d828c36eff --- /dev/null +++ b/hugo/content/components/classic/documentation/throughput.md @@ -0,0 +1,11 @@ +--- +title: Throughput +layout: classic-doc +--- + + + +How many messages can we process per second. + +Normally [MOM](mom) style applications focus on asynchronous messaging and [SEDA](seda) style architectures which aim for massive throughput numbers at the cost of some [Latency](latency) + diff --git a/hugo/content/components/classic/documentation/tomcat.md b/hugo/content/components/classic/documentation/tomcat.md new file mode 100644 index 0000000000..a7b84f4479 --- /dev/null +++ b/hugo/content/components/classic/documentation/tomcat.md @@ -0,0 +1,103 @@ +--- +title: Tomcat +layout: classic-doc +--- + + + +#### Configuration issues for Tomcat 7 and later + +Tomcat needs to be configured to ignore Jetty SCI annotations so that the Jetty WebSocket ServerContainerInitializer class is not inadvertently picked up by Tomcat. For more information on this problem see [AMQ-6154](https://issues.apache.org/jira/browse/AMQ-6154) and [https://wiki.apache.org/tomcat/HowTo/FasterStartUp](https://wiki.apache.org/tomcat/HowTo/FasterStartUp) and consult the Tomcat documentation for the version you are using to properly exclude the Jetty jar files from being scanned by Tomcat. + +Pre-integrated Tomcat with ActiveMQ Classic +----------------------------------- + +Apache TomEE is a distribution of [Tomcat with fully integrated ActiveMQ Classic](http://tomee.apache.org/tomcat-/FAQ/jms). All integration steps detailed here have already been done. The stack supports injection of Topic, Queue and ConnectionFactory references as well as transactional sending and delivery. + +Something like the following works out of the box with no configuration: + +import javax.annotation.Resource; +import javax.servlet.http.HttpServlet; +import javax.jms.Topic; +import javax.jms.Queue; +import javax.jms.ConnectionFactory; + +public class MyServet extends HttpServlet { + + @Resource(name = "foo") + private Topic fooTopic; + + @Resource(name = "bar") + private Queue barQueue; + + @Resource + private ConnectionFactory connectionFactory; + +Manually integrating Tomcat and ActiveMQ Classic +---------------------------------------- + +Note, manually integrating ActiveMQ Classic with Tomcat does allow for Topic, Queue, and ConnectionFactory injection but does not support transactional sending and delivery. + +You should go to Tomcat documentation and read JNDI Resources HOW-TO, especially part: Configure Tomcat's Resource Factory. + +ActiveMQ Classic has ready JNDI resource factory for all its administered objects: ConnectionFactory and destinations. + +You must provide it as a parameter factory for your resources: + + + ... + + + + factory + org.activemq.jndi.JNDIReferenceFactory + + + brokerURL + vm://localhost + + + brokerName + LocalActiveMQBroker + + + useEmbeddedBroker + true + + + ... + + +If you are using Tomcat 5.5 or later then try this instead... + + + ... + + .... + + +Also, don't forget to put ActiveMQ Classic and dependent jars to tomcat shared lib directory. + +### Creating destinations in Tomcat 5.5 or later + +This is completely untested but should work ![(smile)](https://cwiki.apache.org/confluence/s/en_GB/5997/6f42626d00e36f53fe51440403446ca61552e2a2.1/_/images/icons/emoticons/smile.png) + + + ... + + + + .... + + +JMX Tip when working with Tomcat + +If you want to use JMX with Tomcat and then connect via JConsole to view the [JMX](jmx) MBeans of the server then set the following + +CATALINA\_OPTS="$CATALINA\_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1099 \ + -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false" + diff --git a/hugo/content/components/classic/documentation/tools.md b/hugo/content/components/classic/documentation/tools.md new file mode 100644 index 0000000000..a704561b25 --- /dev/null +++ b/hugo/content/components/classic/documentation/tools.md @@ -0,0 +1,8 @@ +--- +title: Tools +layout: classic-doc +--- + +- [Java Service Wrapper](../java-service-wrapper) +- [Maven2 ActiveMQ Classic Broker Plugin](../maven2-activemq-broker-plugin) +- [Web Console](../web-console) diff --git a/hugo/content/components/classic/documentation/uri-protocols.md b/hugo/content/components/classic/documentation/uri-protocols.md new file mode 100644 index 0000000000..4ce238d3f2 --- /dev/null +++ b/hugo/content/components/classic/documentation/uri-protocols.md @@ -0,0 +1,46 @@ +--- +title: URI Protocols +layout: classic-doc +--- + + + +ActiveMQ Classic is designed to support mutliple different [topologies](topologies) and protocols. Which one you use depends on your messaging requirements, quality of service and network topology. + +The following table describes the different network protocols available for JMS clients along with showing the connection URL string you use to enable this communication protocol. On the broker side there are additional [transports](configuring-transports) supported. You can specify the connection URL on an [ActiveMQConnectionFactory](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/ActiveMQConnectionFactory.html) (in a constructor or via the brokerURL property). + +e.g. if you don't want to bother setting up JNDI and so forth and just wanna create a JMS connection you can do something like + +ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://somehost:61616"); +Connection connection = factory.createConnection(); + +Protocol Summary +---------------- + +Protocol|Example|Description|Server? +---|---|---|--- +VM|vm://host:port|Client connect to each other within the same JVM. This does use an asynchronous channel and a separate worker thread. You can enable sync sending using a query parameter, such as vm://localhost?async=false|Yes +TCP|tcp://host:port|Client connects to the broker at the given URL|Yes +SSL|ssl://host:port|Client connects to the broker at the given URL|Yes +Failover|failover:(Uri1,Uri2,Uri3,...,UriN)|Provides a list of possible URIs to connect to and one is randomly chosen. If the connection fails then the transport auto-reconnects to a different one +Peer|peer://serviceName|Creates a pure peer to peer network of nodes of a given service name. In peer mode there is no server, nodes just automatically connect and make a peer network. The serviceName allows you to keep networks apart from each other, such as development, testing, UAT and production. +Discovery|discovery://host:port|Uses [Discovery](discovery) to connect to an available broker of the correct channel name. If multiple brokers can be found then one is chosen at random. If the connection fails then another broker is chosen, if available +Zeroconf|zeroconf:_activemq.broker.development.|Uses [Zeroconf](zeroconf) to connect to an available broker of the correct Zeroconf service name. If multiple brokers can be found then one is chosen at random. If the connection fails then another broker is chosen, if available +HTTP|http://host:port|Client connects to the broker using HTTP tunnelling, with XML payloads suitable for going through firewalls|Yes +UDP|udp://host:port|Client connects to the broker at the given URL +multicast|multicast://host:port|No server, though only works for pub/sub. A pure peer based network where all traffic is multicasted around and filtering is performed on the client. + +The _Server_ column above indicates whether a protocol can be used in an ActiveMQ Classic broker transport connector. All of the above protocols can be used in a JMS client to connect to the messaging fabric; only those protocols indicated can be used in a broker-side transport connector. + +When connecting to an ActiveMQ Classic broker, this could reside locally inside your JVM or be remote on another machine somewhere. If you want to enable the deployment of the ActiveMQ Classic inside your JVM you can enable the useEmbeddedBroker property on the [ActiveMQConnectionFactory](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/ActiveMQConnectionFactory.html). + +Please refer to the [topologies overview](topologies) to see how we can use ActiveMQ Classic in many different topologies to suit your messaging needs. + +### Specifying multiple URLs to connect to + +If you want full [HA](ha) to provide failover and auto-reconnection you can use the _failover:_ prefix + +failover:(tcp://foo:61699,tcp://bar:61617,tcp://whatnot:61698) + +see [Configuring Transports](configuring-transports) for more details + diff --git a/hugo/content/components/classic/documentation/using-activemq-classic-5.md b/hugo/content/components/classic/documentation/using-activemq-classic-5.md new file mode 100644 index 0000000000..68f0402638 --- /dev/null +++ b/hugo/content/components/classic/documentation/using-activemq-classic-5.md @@ -0,0 +1,24 @@ +--- +title: Using ActiveMQ Classic 5 +layout: classic-doc +--- + +To get started with Apache ActiveMQ Classic 5, see the [Version 5 Getting Started](../version-5-getting-started) guide or [Configuring Version 5 Transports](../configuring-version-5-transports). + +- [Configure version 5 Brokers](../configure-version-5-brokers) +- [Configuring Version 5 Transports](../configuring-version-5-transports) +- [LDAP Broker Discovery Mechanism](../ldap-broker-discovery-mechanism) +- [Version 5 Examples](../version-5-examples) +- [Version 5 Getting Started](../version-5-getting-started) +- [Version 5 Hello World](../version-5-hello-world) +- [Version 5 Initial Configuration](../version-5-initial-configuration) +- [Version 5 Installation](../version-5-installation) +- [Version 5 Performance Tuning](../version-5-performance-tuning) +- [Version 5 Run Broker](../version-5-run-broker) +- [Version 5 Topologies](../version-5-topologies) +- [Version 5 Web Samples](../version-5-web-samples) +- [Version 5 XML Configuration](../version-5-xml-configuration) + +### Commercial Documentation + +The commercial providers listed on the [support](/support/) page may also have additional documentation, examples, and tutorials. diff --git a/hugo/content/components/classic/documentation/version-5-examples.md b/hugo/content/components/classic/documentation/version-5-examples.md new file mode 100644 index 0000000000..6e7244f8a9 --- /dev/null +++ b/hugo/content/components/classic/documentation/version-5-examples.md @@ -0,0 +1,93 @@ +--- +title: Version 5 Examples +layout: classic-doc +--- + + + +Since version **5.12.0**, Apache ActiveMQ Classic comes with the new tool that can be used to produce and consume messages from the broker. + +Prerequisites +------------- + +Before running the examples you should try [running a JMS broker](run-broker) on your machine. Follow the [Installation](installation) instructions to use a binary distribution of ActiveMQ Classic. To run the broker in a command shell, type: + +bin/activemq console + +This starts up ActiveMQ Classic. + +Running +------- + +From the [command line](unix-shell-script) you can run +``` +${ACTIVEMQ_HOME}/bin/activemq producer +${ACTIVEMQ_HOME}/bin/activemq consumer +``` +If you have `activemq-all` jar available you can achieve the same with +``` +java -jar activemq-all-5.x.x.jar producer +java -jar activemq-all-5.x.x.jar consumer +``` +If you run inside [Karaf](osgi-integration), you can run the commands as +``` +activemq:producer +activemq:consumer +``` + +Options +------- + +For all options on the commands, run them with `--help` parameter. The up to date, options for [producer](https://github.com/apache/activemq/blob/master/activemq-console/src/main/resources/org/apache/activemq/console/command/producer.txt) and [consumer](https://github.com/apache/activemq/blob/master/activemq-console/src/main/resources/org/apache/activemq/console/command/consumer.txt) can be found in the source. + +Examples +-------- + +Here are a couple of examples of more advanced features. + +To send a text message with custom text use +``` +bin/activemq producer --message "My message" --messageCount 1 +``` +To send byte message of custom length use +``` +bin/activemq producer --messageSize 100 --messageCount 1 +``` +To send a text message with content obtained from an url +``` +bin/activemq producer --payloadUrl http://activemq.apache.org/schema/core/activemq-core.xsd --messageCount 1 +``` +To consume in transaction use +``` +bin/activemq consumer --transacted true +``` +To use client acknowledgment use +``` +bin/activemq consumer --ackMode CLIENT_ACKNOWLEDGE +``` +To use durable topic subscribers use +``` +bin/activemq consumer --durable true --clientId example --destination topic://TEST +``` + +Old examples +------------ + +In older versions of ActiveMQ Classic, the corresponding examples were located in `examples/` or `examples/openwire/swissarmy/` directories, where you can do the similar tasks with an ant script. +``` +ant producer +ant consumer +``` + +Other examples +-------------- + +In `examples/` directory (depending on the version) you can find more examples of using the broker with variety of protocols (mqtt, amqp, ...) and clients (Java, Ruby, JavaScript, ...), so it's the good place to start learning. Also, `examples/conf/` directory contains a lot of different configuration examples that you can use as a starting point for your deployment. + +See Also +-------- + +* [Web Samples](web-samples) +* [Web Console](web-console) +* [JMX](jmx) + diff --git a/hugo/content/components/classic/documentation/version-5-getting-started.md b/hugo/content/components/classic/documentation/version-5-getting-started.md new file mode 100644 index 0000000000..fc45676c97 --- /dev/null +++ b/hugo/content/components/classic/documentation/version-5-getting-started.md @@ -0,0 +1,373 @@ +--- +title: Version 5 Getting Started +layout: classic-doc +--- + + + +Introduction +------------ + +This document describes how to install and configure ActiveMQ Classic for both Unix and Windows' platforms. + + +Pre-Installation Requirements +----------------------------- + +**Hardware:** + +* 60 MB of free disk space for the ActiveMQ Classic binary distribution. +* 200 MB of free disk space for the ActiveMQ Classic source or developer's distributions. + +**Operating Systems:** + +* Windows: Windows XP SP2, Windows 2000. +* Unix: Ubuntu Linux, Powerdog Linux, MacOS, AIX, HP-UX, Solaris, or any Unix platform that supports Java. + +**Environment:** + +* Java Developer Kit (JDK) 1.7.x or greater for deployment and 1.7.x (Java 7) for compiling/building. +* The JAVA_HOME environment variable must be set to the directory where the JDK is installed, e.g., `c:\Program Files\jdk.1.7.0_xx_xx`. +* Maven 3.0 or greater (required when installing source or developer's releases). +* [JARs](http://cvs.apache.org/repository/geronimo-spec/jars/) that will be used must be added to the classpath. + +Installation Procedure for Windows +---------------------------------- + +This section of the Getting Started Guide explains how to install binary and source distributions of ActiveMQ Classic on a Windows system. + +#### Windows Binary Installation + +This procedure explains how to download and install the binary distribution on a Windows system. + +1. From a browser, navigate to [activemq.apache.org/](http://activemq.apache.org/). +2. Click the [Download](download) link in the navigation pane (the left pane). +3. Select the latest distribution (for older releases, click the link to the archives). + For a binary distribution, the filename will be similar to: `activemq-x.x.x.zip`. +4. Extract the files from the ZIP file into a directory of your choice. +5. Proceed to the [#Starting ActiveMQ Classic](version-5-getting-started) section of this document. +6. Following start-up, go to the [#Testing the Installation](version-5-getting-started) section of this document. + +#### Windows Source Installation + +This procedure explains how to download and install the source distribution on a Windows system. + +**NOTE:** ActiveMQ Classic requires Java 7 to run and to build + +1. From a browser, navigate to [activemq.apache.org/](http://activemq.apache.org/). +2. Click the [Download](download) link in the navigation pane (the left pane). +3. Select the latest distribution (for older releases, click the link to the archives). + For a source distribution, the filename will be similar to: `activemq-x.x-src.zip`. +4. Extract ActiveMQ Classic from the ZIP file into a directory of your choice. +5. Build ActiveMQ Classic using Maven 2.1 or greater and Java 1.7. + +The recommended method of building ActiveMQ Classic is the following: +``` +cd [activemq_install_dir] +mvn clean install +``` +where `[activemq_install_dir]` is the directory in which ActiveMQ Classic was installed. + +If the above build fails on some tests, type the following: +``` +cd [activemq_install_dir] +mvn clean install -Dmaven.test.skip=true +``` +1. If you prefer to use an IDE, then you can auto-generate the IDE's project file using maven plugins: + ``` + mvn eclipse:eclipse + ``` + or + ``` + mvn idea:idea + ``` + Feel free to use any other applicable IDE. Please refer to the [plugin reference](http://maven.apache.org/plugins/index.html) for more details. + +2. Start ActiveMQ Classic from the target directory, for example: + ``` + cd [activemq_install_dir]\assembly\target + unzip activemq-x.x-SNAPSHOT.zip + cd activemq-x.x-SNAPSHOT + bin\activemq + ``` + > **NOTE:** Working directories get created relative to the current directory. To create the working directories in the proper place, ActiveMQ Classic must be launched from its home/installation directory. + +3. Proceed to the [#Testing the Installation](version-5-getting-started) section. + +> **Warning** +> +> If you are building ActiveMQ Classic 5.x under Windows using Cygwin there is a path name length limitation. If the path name length is exceeded, you may see build errors. To correct this, move the ActiveMQ Classic source directory higher in the file system tree, e.g., /cygdrive/c/d/sm. + +#### Windows Developer's Release + +This procedure explains how to download and install the latest developer's snapshot. + +**NOTE:** ActiveMQ Classic requires Java 7 to run and to build + +1. From a browser, navigate to [activemq.apache.org/](http://activemq.apache.org/). +2. Click the [Download](download) link in the navigation pane (the left pane). +3. Click the Maven ActiveMQ Classic SNAPSHOT link. +4. Select the version of ActiveMQ Classic to download +5. Extract the files from the ZIP file into a directory of your choice. +6. If a binary snapshot was downloaded, proceed to the [#Starting ActiveMQ Classic](version-5-getting-started) section of this document. + If a source snapshot was downloaded, perform step 6 and step 7 of the [#Windows Source Installation](version-5-getting-started) procedure. +7. Following start-up, proceed to the [#Testing the Installation](version-5-getting-started) section. + +Installation Procedure for Unix +------------------------------- + +#### Unix Binary Installation + +This procedure explains how to download and install the binary distribution on a Unix system. + +**NOTE:** There are several alternative ways to perform this type of installation. + +1. Download the activemq gzip file to the Unix machine, using either a browser or a tool, i.e., wget, scp, ftp, etc. for example: + ``` + \> wget http://activemq.apache.org/path/tofile/apache-activemq-5.8-tar.gz + ``` +2. Extract the files from the gzip file into a directory of your choice. For example: + ``` + \> tar zxvf activemq-x.x.x.tar.gz + ``` +3. If the `activemq` start-up script is not executable, change its permissions. The `activemq` script is located in the `bin` directory. For example: + ``` + \> cd [activemq_install_dir]/bin + \> chmod 755 activemq + ``` +4. Proceed to the [#Starting ActiveMQ Classic](version-5-getting-started) section of this document. +5. Following start-up, go to the [#Testing the Installation](version-5-getting-started) section. + +#### Unix Source Installation + +This procedure explains how to download and install the source distribution on a Unix system. This procedure assumes the Unix machine has a browser. Please see the previous [#Unix Binary Installation](version-5-getting-started) section for details on how to install ActiveMQ Classic without a browser. + +**NOTE:** ActiveMQ Classic requires Java 7 to run and to build + +1. From a browser, navigate to [activemq.apache.org/](http://activemq.apache.org/). +2. Click the [Download](download) link in the navigation pane (the left pane). +3. Click the Maven ActiveMQ Classic SNAPSHOT link. +4. Select the version of ActiveMQ Classic to download + For a source distribution, the filename will be similar to: `activemq-x.x-src.tar.gz`. +5. Extract the files from the ZIP file into a directory of your choice. For example: + ``` + tar zxvf activemq.x.x-src.tar.gz + ``` +6. Build ActiveMQ Classic using Maven 3.0 or greater and Java 7: + The preferred method of building ActiveMQ Classic is the following: + ``` + cd [activemq_install_dir] + mvn clean install + ``` + If Maven crashes with a java.lang.OutOfMemoryError, you you need to do this first (assuming a Bourne-like shell): + ``` + export MAVEN_OPTS=-Xmx1024M + ``` + If the above build fails on some tests, do the following: + ``` + cd [activemq_install_dir] + mvn clean install -Dmaven.test.skip=true + ``` + If you prefer to use an IDE then you can auto-generate the IDE's project file using maven plugins: + ``` + mvn eclipse:eclipse + ``` + or + ``` + mvn idea:idea + ``` + Feel free to use any other applicable IDE. Please refer to the [plugin reference](http://maven.apache.org/reference/plugins/plugins.html) for more details. + **NOTE:** Working directories get created relative to the current directory. To create working directories in the proper place, ActiveMQ Classic must be launched from its home/installation directory. + +7. Proceed to the [#Starting ActiveMQ Classic](version-5-getting-started) section of this document. +8. Proceed to [#Testing the Installation](version-5-getting-started) section. + +#### Unix Developer's Release + +This procedure explains how to download and install the latest developer's snapshot. + +**NOTE:** ActiveMQ Classic requires Java 7 to run and to build + +1. From a browser, navigate to [activemq.apache.org/](http://activemq.apache.org/). +2. Click the [#Download](version-5-getting-started) link in the navigation pane (the left pane). +3. Click the Maven ActiveMQ Classic SNAPSHOT link. +4. Select the version of ActiveMQ Classic to download +5. Extract the files from the gzip file into a directory of your choice. For example: + For a binary developer's snapshot: + ``` + tar zxvf activemq-x.x.x.tar.gz + ``` + For a source developer's snapshot: + ``` + tar zxvf activemq-x.x.x-src.tar.gz + ``` +6. If a binary snapshot was downloaded, to make it executable, the `activemq` script may need its permissions changed: + ``` + cd [activemq_install_dir]/bin + chmod 755 activemq + ``` +7. For a binary snapshot, proceed to the [#Starting ActiveMQ Classic](version-5-getting-started) section of this document. +8. If a source snapshot was downloaded perform steps 6 - 8 of the [#Unix Source Installation](version-5-getting-started) procedure. +9. Proceed to the [#Testing the Installation](version-5-getting-started) section. + +Starting ActiveMQ Classic +----------------- + +There now follows instructions on how to [run the ActiveMQ Classic Message Broker](run-broker). + +See also [Starting ActiveMQ Classic with a different configuration file](#) + +### On Windows + +From a console window, change to the installation directory and run `activemq`: +``` +cd [activemq_install_dir] +``` +where `activemq_install_dir` is the directory in which ActiveMQ Classic was installed, e.g., `c:\Program Files\ActiveMQ-5.x`. + +Then type (depending on ActiveMQ Classic version): + +**ActiveMQ Classic 5.10 onwards** +``` +bin\activemq start +``` +`ActiveMQ Classic 5.9 or older** +``` +bin\activemq +``` +**NOTE:** Working directories get created relative to the current directory. To create working directories in the proper place, ActiveMQ Classic must be launched from its home/installation directory. + +### On Unix + +From a command shell, change to the installation directory and run `activemq`: +``` +cd [activemq_install_dir] +``` +where `activemq_install_dir` is the directory in which ActiveMQ Classic was installed, e.g., `/usr/local/activemq-5.x`. +Then type: +``` +bin/activemq start +``` +OR +``` +bin/activemq start > /tmp/smlog 2>&1 &; +Note: /tmp/smlog may be changed to another file name. +``` +**NOTE:** Working directories get created relative to the current directory. To create working directories in the proper place, ActiveMQ Classic must be launched from its home/installation directory. + +> **Warning** +> +> Do NOT close the console or shell in which ActiveMQ Classic was started, as that will terminate ActiveMQ Classic (unless ActiveMQ Classic was started with nohup). +``` +nohup bin/activemq > /tmp/smlog 2>&1 & +``` + +### More help + +For other ways of running the broker see [Here](run-broker). For example you can run an [embedded broker](how-do-i-embed-a-broker-inside-a-connection) inside your JMS Connection to avoid starting a separate process. + +Testing the Installation +------------------------ + +If ActiveMQ Classic is up and running without problems, the Window's console window or the Unix command shell will display information similar to the following log line: +``` +INFO ActiveMQ JMS Message Broker (ID:apple-s-Computer.local-51222-1140729837569-0:0) has started +``` + +ActiveMQ Classic's default port is 61616. From another window run netstat and search for port 61616. + +From a Windows console, type: +``` +netstat -an|find "61616" +``` +**OR** + +From a Unix command shell, type: +``` +netstat -an|grep 61616 +``` + +Monitoring ActiveMQ Classic +------------------- + +You can monitor ActiveMQ Classic using the [Web Console](web-console) by pointing your browser at + +[http://localhost:8161/admin](http://localhost:8161/admin) + +From ActiveMQ Classic 5.8 onwards the web apps is secured out of the box. +The default username and password is admin/admin. You can configure this in the conf/jetty-real.properties file. + +Or you can use the [JMX](jmx) support to view the running state of ActiveMQ Classic. + +For more information see the file `docs/WebConsole-README.txt` in the distribution. + +Stopping ActiveMQ Classic +----------------- + +For both Windows and Unix installations, terminate ActiveMQ Classic by typing "CTRL-C" in the console or command shell in which it is running. + +If ActiveMQ Classic was started in the background on Unix, the process can be killed, with the following: +``` +cd [activemq_install_dir] +``` +where `activemq_install_dir` is the directory in which ActiveMQ Classic was installed, e.g., `/usr/local/activemq-5.x`. +Then type: +``` +bin/activemq stop +``` +Or you can do the following: +``` +ps -ef|grep activemq +kill [PID] +``` +where `[PID]` is the process id of the ActiveMQ Classic process. + +Starting ActiveMQ Classic with a different configuration file +----------------------------------------------------- + +By default ActiveMQ Classic uses the `conf/activemq.xml` as the main configuration file when starting. If you want to use a different configuration file you can specify this as a parameter. + +#### ActiveMQ Classic 5.8 or older + +For example to use `conf/activemq-demo.xml` which includes the web demos, you do as follows: +``` +bin/activemq console xbean:conf/activemq-demo.xml +``` +To start Active in console mode and load the `conf/activemq-demo.xml` file. Yes you need the `xbean:` as prefix. + +And to launch as a background process you can do: +``` +bin/activemq start xbean:conf/activemq-demo.xml +``` + +#### ActiveMQ Classic 5.9 onwards + +For example to use `examples/conf/activemq-demo.xml` which includes the web demos, you do as follows: +``` +bin/activemq console xbean:examples/conf/activemq-demo.xml +``` +To start Active in console mode and load the `examples/conf/activemq-demo.xml` file. Yes you need the `xbean:` as prefix. + +And to launch as a background process you can do: +``` +bin/activemq start xbean:examples/conf/activemq-demo.xml +``` + +Configuring ActiveMQ Classic +-------------------- + +The ActiveMQ Classic broker should now run. You can configure the broker by specifying an [Xml Configuration](xml-configuration) file as a parameter to the _activemq_ command. An alternative is to use the [Broker Configuration URI](broker-configuration-uri) to configure things on the command line in a concise format (though the configuration options are not as extensive as if you use Java or XML code). You can also + +Also see [Configuring Transports](configuring-transports) to see how you can configure the various connection, transport and broker options using the connection URL in the ActiveMQConnectionFactory. + +See the [Initial Configuration](initial-configuration) for details of which jars you need to add to your classpath to start using ActiveMQ Classic in your Java code + +If you want to use JNDI to connect to your JMS provider then please view the [JNDI Support](jndi-support). If you are a Spring user you should read about [Spring Support](spring-support) + +After the installation, ActiveMQ Classic is running with a basic configuration. For details on configuring options, please see refer to the [Configuration](configuration) section. + +Additional Resources +-------------------- + +If you are new to using ActiveMQ Classic, running the [Web Samples](web-samples) or the [Examples](examples) is a good next step to learn more about ActiveMQ Classic. + diff --git a/hugo/content/components/classic/documentation/version-5-hello-world.md b/hugo/content/components/classic/documentation/version-5-hello-world.md new file mode 100644 index 0000000000..474908c907 --- /dev/null +++ b/hugo/content/components/classic/documentation/version-5-hello-world.md @@ -0,0 +1,162 @@ +--- +title: Version 5 Hello World +layout: classic-doc +--- + + + +The following is a very simple JMS application with multiple, concurrent, consumers and producers. See the [Initial Configuration](initial-configuration) guide for details on how to setup your classpath correctly. + +Things you might do after running this example: + +* [Setup a broker](run-broker) instead of using the org.activemq.broker.impl.Main class directly +* Use JNDI to lookup a javax.jms.ConnectionFactory rather than creating ActiveMQConnectionFactory directly. +* Implement the javax.jms.MessageListener interface rather than calling consumer.receive() +* Use transactional sessions +* Use a Topic rather than a queue + +The point of this example is to show you the basic code required to use JMS in a straightforward way. The Consumers and Producers could very easy be on completely different machines or in different processes. + +**App.java** +``` +import org.apache.activemq.ActiveMQConnectionFactory; + +import javax.jms.Connection; +import javax.jms.DeliveryMode; +import javax.jms.Destination; +import javax.jms.ExceptionListener; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; + +/** + * Hello world! + */ +public class App { + + public static void main(String[] args) throws Exception { + thread(new HelloWorldProducer(), false); + thread(new HelloWorldProducer(), false); + thread(new HelloWorldConsumer(), false); + Thread.sleep(1000); + thread(new HelloWorldConsumer(), false); + thread(new HelloWorldProducer(), false); + thread(new HelloWorldConsumer(), false); + thread(new HelloWorldProducer(), false); + Thread.sleep(1000); + thread(new HelloWorldConsumer(), false); + thread(new HelloWorldProducer(), false); + thread(new HelloWorldConsumer(), false); + thread(new HelloWorldConsumer(), false); + thread(new HelloWorldProducer(), false); + thread(new HelloWorldProducer(), false); + Thread.sleep(1000); + thread(new HelloWorldProducer(), false); + thread(new HelloWorldConsumer(), false); + thread(new HelloWorldConsumer(), false); + thread(new HelloWorldProducer(), false); + thread(new HelloWorldConsumer(), false); + thread(new HelloWorldProducer(), false); + thread(new HelloWorldConsumer(), false); + thread(new HelloWorldProducer(), false); + thread(new HelloWorldConsumer(), false); + thread(new HelloWorldConsumer(), false); + thread(new HelloWorldProducer(), false); + } + + public static void thread(Runnable runnable, boolean daemon) { + Thread brokerThread = new Thread(runnable); + brokerThread.setDaemon(daemon); + brokerThread.start(); + } + + public static class HelloWorldProducer implements Runnable { + public void run() { + try { + // Create a ConnectionFactory + ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost"); + + // Create a Connection + Connection connection = connectionFactory.createConnection(); + connection.start(); + + // Create a Session + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Create the destination (Topic or Queue) + Destination destination = session.createQueue("TEST.FOO"); + + // Create a MessageProducer from the Session to the Topic or Queue + MessageProducer producer = session.createProducer(destination); + producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + + // Create a messages + String text = "Hello world! From: " + Thread.currentThread().getName() + " : " + this.hashCode(); + TextMessage message = session.createTextMessage(text); + + // Tell the producer to send the message + System.out.println("Sent message: "+ message.hashCode() + " : " + Thread.currentThread().getName()); + producer.send(message); + + // Clean up + session.close(); + connection.close(); + } + catch (Exception e) { + System.out.println("Caught: " + e); + e.printStackTrace(); + } + } + } + + public static class HelloWorldConsumer implements Runnable, ExceptionListener { + public void run() { + try { + + // Create a ConnectionFactory + ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost"); + + // Create a Connection + Connection connection = connectionFactory.createConnection(); + connection.start(); + + connection.setExceptionListener(this); + + // Create a Session + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Create the destination (Topic or Queue) + Destination destination = session.createQueue("TEST.FOO"); + + // Create a MessageConsumer from the Session to the Topic or Queue + MessageConsumer consumer = session.createConsumer(destination); + + // Wait for a message + Message message = consumer.receive(1000); + + if (message instanceof TextMessage) { + TextMessage textMessage = (TextMessage) message; + String text = textMessage.getText(); + System.out.println("Received: " + text); + } else { + System.out.println("Received: " + message); + } + + consumer.close(); + session.close(); + connection.close(); + } catch (Exception e) { + System.out.println("Caught: " + e); + e.printStackTrace(); + } + } + + public synchronized void onException(JMSException ex) { + System.out.println("JMS Exception occured. Shutting down client."); + } + } +} +``` diff --git a/hugo/content/components/classic/documentation/version-5-initial-configuration.md b/hugo/content/components/classic/documentation/version-5-initial-configuration.md new file mode 100644 index 0000000000..0488193fdc --- /dev/null +++ b/hugo/content/components/classic/documentation/version-5-initial-configuration.md @@ -0,0 +1,79 @@ +--- +title: Version 5 Initial Configuration +layout: classic-doc +--- + + +Firstly you need to add the jars to your classpath. + +Required JARs +------------- + +To make ActiveMQ Classic easy to use, the default **activemq-all.jar** comes complete with all the libraries required. If you prefer to have explicit control over all the jars used by ActiveMQ Classic here is the full list of individual jars required + +* activemq-broker.jar +* activemq-client.jar +* activemq-kahadb-store.jar +* activemq-spring.jar +* hawtbuf-1.11.jar +* slf4j-api.jar +* slf4j-log4j12.jar +* log4j-1.2.17.jar +* J2EE APIs which could be the j2ee.jar from Sun or your J2EE container or you could use Geronimo's freely distributable geronimo-spec-j2ee.jar. If you are inside a servlet container and being dependent on the j2ee.jar causes you troubles, the parts of the J2EE jar we are dependent on are as follows... + * geronimo-spec-jms.jar + * geronimo-spec-jta.jar + * geronimo-spec-j2ee-management.jar + +If you want to grab a J2EE specification jar we recommend the Apache [repository](http://cvs.apache.org/repository/geronimo-spec/jars/) + +Optional JARS +------------- + +* spring.jar - if you wish to use the XML configuration file for configuring the Message Broker + +* if you wish to use message persistence then you need to add a persistent jar to your classpath (see below). If you just want a lightweight message bus with no durability you can leave this step out but we highly recommend persistence for production deployments. + +Persistence support +------------------- + +The default persistence is the [AMQ Message Store](Persistence/amq-message-store). We do still support persistence via [JDBC and a high performance journal](persistence). For full explict control over configuration check out the [Xml Configuration](xml-configuration). + +If you're just doing some testing or in-VM SEDA based messaging you may wish to disable persistence. You can use the [Xml Configuration](xml-configuration) for this. + +You can do this by setting the usePersistence property to false either in the [Xml Configuration](xml-configuration) or on the [broker URL](configuring-transports). + +Next steps +---------- + +One of the first things you might want to do is [start a broker](run-broker). Once you have a broker running you could try using the [JNDI Support](jndi-support) which shows how to run an example JMS program. Or there are some other [example programs](examples) + +If you don't want to use JNDI you can just instantiate an [ActiveMQConnectionFactory](http://activemq.codehaus.org/maven/apidocs/org/apache/activemq/ActiveMQConnectionFactory.html), configure its properties directly and then you're ready to use the standard JMS API to create Connections, Sessions, MessageProducer and MessageConsumer instances. + +Additional resources +-------------------- + +### Related reading + +* Sun's [JMS Tutorial](http://java.sun.com/products/jms/tutorial/) is a handy place to start looking at how to use the JMS API directly +* The ActiveMQ Classic [Website](http://activemq.apache.org) for specifics on how to use ActiveMQ Classic +* [ActiveMQ Classic Topologies](topologies) +* [ActiveMQ Classic Clustering](clustering) +* [ActiveMQ Classic Network of Brokers](networks-of-brokers) +* [Staged Event Driven Architecture (SEDA)](http://www.eecs.harvard.edu/~mdw/proj/seda/) + +### Specifications + +* [Java Connector Architecture 1.5](http://java.sun.com/j2ee/connector/) +* [Java Messaging Service](http://java.sun.com/products/jms/index.jsp) +* [WSIF](http://ws.apache.org/wsif/) +* [WS-Notification](http://www-128.ibm.com/developerworks/webservices/library/specification/ws-notification/) + +### Related open source projects + +* [Apache Geronimo](http://geronimo.apache.org/) +* [Jencks](http://jencks.org/) is a Spring JCA container allowing you to use connection & thread & POJO pooling for consuming JMS in highly concurrent servers +* [Lingo](http://lingo.codehaus.org/) is a Spring/POJO remoting layer for JMS. It allows you to reuse all the power of JMS from your POJOs without using any of the JMS APIs directly +* [Spring](http://www.springframework.org/) +* [Stomp](http://stomp.codehaus.org/) is an open wire protocol (similar to HTTP) for communicating with MOMs from different languages. It has clients for languages like C, C#, Python, Perl, Ruby etc. +* [XBean](https://geronimo.apache.org/xbean/) is used as the default XML configuration mechanism for ActiveMQ Classic + diff --git a/hugo/content/components/classic/documentation/version-5-installation.md b/hugo/content/components/classic/documentation/version-5-installation.md new file mode 100644 index 0000000000..377c0785c1 --- /dev/null +++ b/hugo/content/components/classic/documentation/version-5-installation.md @@ -0,0 +1,22 @@ +--- +title: Version 5 Installation +layout: classic-doc +--- + + + +* [Download](download) a binary distribution of ActiveMQ Classic and unpack it into some directory. + +* To run an ActiveMQ Classic broker, type the following commands from the directory in which you have just unpacked the ActiveMQ Classic distribution. +``` +cd bin +activemq +``` +The ActiveMQ Classic broker should now run. You can configure the broker by specifying an [Xml Configuration](xml-configuration) file as a parameter to the _activemq_ command. + +You can now run the [Examples](examples) using Ant. + +See the [getting started guide](initial-configuration) for details of which jars you need to add to your classpath to start using ActiveMQ Classic in your Java code + +If you want to use JNDI to connect to your JMS provider then please view the [JNDI Support](jndi-support). If you are a Spring user you should read about [Spring Support](spring-support) + diff --git a/hugo/content/components/classic/documentation/version-5-performance-tuning.md b/hugo/content/components/classic/documentation/version-5-performance-tuning.md new file mode 100644 index 0000000000..5eaff47d15 --- /dev/null +++ b/hugo/content/components/classic/documentation/version-5-performance-tuning.md @@ -0,0 +1,50 @@ +--- +title: Version 5 Performance Tuning +layout: classic-doc +--- + + + +For a more complete overview see [Performance](performance). + +There are trade-offs between performance and reliabilty. +By default, activemq strikes a balance between the two, so there are some things you can change to increase throughput. + +Async publishing +---------------- + +First some background: + +When an ActiveMQ Classic message producer sends a non-persistent message, its dispatched asynchronously (fire and forget) - but for persistent messages, the publisher will block until it gets a notification that the message has been processed (saved to the store - queued to be dispatched to any active consumers etc) by the broker. messages are dispatched with delivery mode set to be persistent by default (which is required by the JMS spec). So if you are sending messages on a Topic, the publisher will block by default (even if there are no durable subscribers on the topic) until the broker has returned a notification. + +So if you looking for good performance with topic messages, either set the delivery mode on the publisher to be non-persistent, or set the **useAsyncSend** property on the ActiveMQ Classic ConnectionFactory to be **true**. + +Pre-fetch sizes for Consumers +----------------------------- + +ActiveMQ Classic will push as many messages to the consumer as fast as possible, where they will be queued for processing by an ActiveMQ Classic Session. The maximum number of messages that ActiveMQ Classic will push to a Consumer without the Consumer processing a message is set by the pre-fetch size. You can improve throughput by running ActiveMQ Classic with larger pre-fetch sizes. Pre-fetch sizes are determined by the ActiveMQPrefetchPolicy bean, which is set on the ActiveMQ Classic ConnectionFactory. + +Default values: + +consumer type|default value +---|--- +queue|1000 +queue browser|500 +topic|32766 +durable topic|1000 + +Optimized Acknowledge +--------------------- + +When consuming messages in auto acknowledge mode (set when creating the consumers' session), ActiveMQ Classic will acknowledge receipt of messages back to the broker in batches (to improve performance). The batch size is 50% of the prefetch limit for the Consumer. You switch batch acknowledgment off by setting the **optimizeAcknowledge** property on the ActiveMQ Classic ConnectionFactory to be **false** + +Straight through Session Consumption +------------------------------------ + +By default, a Consumer's session will dispatch messages to the consumer in a separate thread. If you are using Consumers with auto acknowledge, you can increase throughput by passing messages straight through the Session to the Consumer by setting the **alwaysSessionAsync** property on the ActiveMQ Classic ConnectionFactory to be **false** + +File based Persistence +---------------------- + +The default persistence store is the [AMQ Message Store](Persistence/amq-message-store) + diff --git a/hugo/content/components/classic/documentation/version-5-run-broker.md b/hugo/content/components/classic/documentation/version-5-run-broker.md new file mode 100644 index 0000000000..386ba5a2c9 --- /dev/null +++ b/hugo/content/components/classic/documentation/version-5-run-broker.md @@ -0,0 +1,83 @@ +--- +title: Version 5 Run Broker +layout: classic-doc +--- + + + +Running an ActiveMQ Classic Broker +========================== + +Note if you want to use an **embedded broker** then see [How do I embed a Broker inside a Connection](how-do-i-embed-a-broker-inside-a-connection) + +The [binary distribution](download) of ActiveMQ Classic comes with a script called 'activemq' which allows you to run a broker. +For details regarding the activemq init script file review  [Unix Shell Script](unix-shell-script)  and  [ActiveMQ Classic Command Line Tools Reference](activemq-classic-command-line-tools-reference) + +Typing the following will run an ActiveMQ Classic Broker using the out of the box configuration in the foreground +``` +bin/activemq console +``` +You can then use a [Broker Configuration URI](broker-configuration-uri) to specify how to start and configure your broker using a single URI. For example +``` +bin/activemq console broker:(tcp://localhost:61616,network:static:tcp://remotehost:61616)?persistent=false&useJmx=true +``` +Or you can a [Broker XBean URI](broker-xbean-uri) to customize the Message Broker using the [Xml Configuration](xml-configuration) to suit your needs. You can run a broker with a specific XML configuration as +``` +bin/activemq console xbean:foo.xml +``` +Or you can use a [Broker Properties URI](broker-properties-uri) to customize the Message Broker using a properties file; which avoids the dependency on Spring, xbean-spring and XML. +``` +bin/activemq console properties:foo.properties +``` + +### Monitoring the broker + +You can monitor ActiveMQ Classic using the [Web Console](web-console) by pointing your browser at + +[http://localhost:8161/admin](http://localhost:8161/admin) + +From ActiveMQ Classic 5.8 onwards the web apps is secured out of the box. + +The default username and password is admin/admin. You can configure this in the conf/jetty-real.properties file. + +Or you can use the [JMX](jmx) support to view the running state of ActiveMQ Classic. + +For more information see the file `docs/WebConsole-README.txt` in the distribution. + +### Running the broker inside a Servlet Engine + +See the source code (or WAR) of the [Web Console](web-console) for an example of how to run the broker inside a web application using Spring. + +### Running the broker inside your J2EE Application Server + +Whether its Apache Geronmio, JBoss, WebLogic or some other J2EE container you should be able to just reconfigure and then deploy the activemq-*.rar which is included in the binary distribution as a deployment unit in your app server. By default the rar is not configured to start an embedded broker. But by setting the brokerXmlConfig on the resource adapter configuration, the resource adapter will start an embedded broker. + +For more details see [J2EE](j2ee) + +### Running the broker from the source code + +From the latest [checkout](source) of the code you can run a broker using the [ActiveMQ Classic Performance Plugin](activemq-classic-performance-module-users-manual) + +### Running the broker from maven + +You can download and install the ActiveMQ Classic Startup Maven Plugin via the following command if you are in a directory with a pom.xml. More detailed usage [here](maven2-activemq-broker-plugin) +``` +mvn org.apache.activemq.tooling:maven-activemq-plugin:5.0-SNAPSHOT:run +``` +You can also include it the pom and run it using: +``` +mvn activemq:run +``` +Handling JMS brokers going down +------------------------------- + +A common requirement is that if the JMS broker goes down you want to automatically detect the failure and try to reconnect under the covers so that your application does not have to worry about reconnection. + +There is detailed documentation on this in [Configuring Version 5 Transports](configuring-version-5-transports); briefly... + +Just change your connection URI i to +``` +failover:tcp://host:port +``` +And the JMS client will auto-reconnect to the broker if it is shutdown and restarted later on. + diff --git a/hugo/content/components/classic/documentation/version-5-topologies.md b/hugo/content/components/classic/documentation/version-5-topologies.md new file mode 100644 index 0000000000..0d20220368 --- /dev/null +++ b/hugo/content/components/classic/documentation/version-5-topologies.md @@ -0,0 +1,82 @@ +--- +title: Version 5 Topologies +layout: classic-doc +--- + + + +ActiveMQ Classic supports a wide range of different deployment topologies as well as [protocols](uri-protocols) & wire formats. The following diagram shows a federated network of brokers with a few different kinds of topology. + +[![](assets/img/BrokerTopology-1.png)](http://activemq.org/BrokerTopology.pdf) + +Which topology you choose is up to you. We'll now describe a few of these protocols in a little more detail. + +In VM +----- + +A useful option when unit testing is to limit JMS communication to within a single JVM. For this use the protocol +``` +vm://localhost +``` +You can segment the VM protocol to different groups - e.g. if you want to have logically different JMS networks within the same JVM, you can group networks using different URIs. e.g. +``` +vm://localhost/foo +``` +This will ensure that different segments do not interfere with one another. Though typically we use unique topic and queue destinations so that all traffic can coexist happily on the same logical network. + +Client-Server +------------- + +This is probably the most efficient and fastest solution for large numbers of clients requiring a diverse range of communication options from publish / subscribe to queue based communication. Typically the clients will connect with a Message Broker using a protocol, typically TCP or SSL but this could be NIO or other protocols. + +We can load balance clients across brokers and provide broker failover so that we have a logical cluster of brokers with [HA](ha). + +e.g. +``` +tcp://somehost:port +``` +Or for SSL +``` +ssl://somehost:port +``` +You can use [Discovery](discovery) to find the brokers available that you can connect to which makes it easier to seamlessly connect to a cluster of brokers. + +Embedded Broker +--------------- + +This is logically equivalent to Client-Server but some (or all) clients contain a locally embedded broker. So communcation between the client and server (broker) are all within the same JVM and so do not use real networking - though brokers may communicate with other brokers or clients connected to it. + +This can avoid the extra hop required to go from producer to broker to consumer - which is a great optimisation for RMI / RPC style situations, where you want the performance benefits (reduced latency) of point to point networking but with the scalabilty of a flexible messaging fabric. + +Embedded Brokers can also simplify deployment options as well, its one less process to run. + +Another use case for embedded brokers is to provide store and forward isolation from each service - so that the remote brokers can fail quite happily without affecting the service with the embedded broker. e.g. the entire network could fail, but a service could continue publishing messages to its embedded broker. + +You can find out how to [configure an embedded broker here](how-do-i-embed-a-broker-inside-a-connection) + +Peer to Peer +------------ + +This allows peer based clusters to be created where there is no server - just clients connecting together. +There are various ways to implement a peer to peer JMS network. One easy way is just to use a multicast transport for communication; then all nodes on the same multicast address will receive all messages and the local embedded message broker will route messages to the necessary MessageConsumers. + +We currently have 3 choices for multicast protocols + +* multicast +* jgroups: uses the JGroups library to implement reliable multicast +* jrms: uses Sun's JRMS library to implement reliable multicast + +Multicast is great in development though often you might want to disable this feature in production and have well known servers fixed on specific machines. Often socket based communication (using pointcast) is much faster & better for heavy-lifting - particularly on Java - so we tend to recommend to use multicast mostly for discovery and use TCP / SSL for your heavy duty messaging. + +Often we can use the peer to peer topology as a bootstrap to create a cluster of clients & brokers and then autodeploy servers into the cluster for a true grid style network. + +So you can get the effect of a peer based network using [Discovery](discovery) together with either stand alone Brokers or using embedded brokers. + +### JXTA + +We have a JXTA transport which will use the full JXTA stack for negotiating NAT and across firewalls and so forth for creating a true peer based JMS network. +``` +jxta://hostname:port +``` +Currently you need to run one server which everyone connects to via JXTA. We've not yet created a pure peer network with JXTA + diff --git a/hugo/content/components/classic/documentation/version-5-web-samples.md b/hugo/content/components/classic/documentation/version-5-web-samples.md new file mode 100644 index 0000000000..d2609cd9d5 --- /dev/null +++ b/hugo/content/components/classic/documentation/version-5-web-samples.md @@ -0,0 +1,20 @@ +--- +title: Version 5 Web Samples +layout: classic-doc +--- + + + +There are a few example programs demonstrating the [REST](rest) messaging or [Ajax](ajax) in the [activemq/activemq-web-demo](https://github.com/apache/activemq/tree/main/activemq-web-demo/) module. + +Running the Web Samples +----------------------- + +We have integrated the Web Samples into the binary distribution. + +The steps to running the Web Samples are + +* [Download](download) a binary distribution +* [Run the Message Broker](run-broker) e.g. by running bin/activemq +* point your browser to [http://localhost:8161/demo](http://localhost:8161/demo) + diff --git a/hugo/content/components/classic/documentation/version-5-xml-configuration.md b/hugo/content/components/classic/documentation/version-5-xml-configuration.md new file mode 100644 index 0000000000..e4a0e0b7b5 --- /dev/null +++ b/hugo/content/components/classic/documentation/version-5-xml-configuration.md @@ -0,0 +1,200 @@ +--- +title: Version 5 XML Configuration +layout: classic-doc +--- + + + +* transport connectors which consist of transport channels and wire formats TODO: add a link to a page explaining what transport connectors are how to configure and use them. +* network connectors using network channels or discovery TODO: add a link to a page explaining what network connectors are how to configure and use them. +* discovery agents TODO: add a link to a page explaining what discovery agents are how to configure and use them. +* persistence providers & locations TODO: add a link to a page explaining what persistence providers are how to configure and use them. +* custom message containers (such as last image caching etc) + +We use [XBean](https://geronimo.apache.org/xbean/) to perform the XML configuration. + +For details of the XML see the [Xml Reference](xml-reference) + +Be careful with broker names and URIs + +Make sure you do not use any strange characters in the names of brokers as they are converted to URIs which [do not allow things like underscores](http://java.sun.com/j2se/1.4.2/docs/api/java/net/URI.html) in them etc. + +Examples +-------- + +The default ActiveMQ Classic configuration: [current default config](http://svn.apache.org/repos/asf/activemq/trunk/assembly/src/release/conf/activemq.xml). + +``` + + + + + + file:${activemq.conf}/credentials.properties + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +From a binary distribution there is an _activemq_ script allowing you to run a Message Broker as a stand alone process from the command line easily providing the $ACTIVEMQ_HOME/bin directory is on your PATH. + +Configuring embedded brokers +---------------------------- + +You can also use the XML Configuration to configure [embedded brokers](how-do-i-embed-a-broker-inside-a-connection). For example using the JNDI configuration mechanism you can do the following [BrokerXmlConfigFromJNDITest](http://svn.apache.org/repos/asf/activemq/trunk/assembly/src/test/java/org/apache/activemq/config/BrokerXmlConfigFromJNDITest.java) + +Or of you want to explicitly configure the embedded broker via Java code you can do the following [BrokerXmlConfigTest](http://svn.apache.org/repos/asf/activemq/trunk/assembly/src/test/java/org/apache/activemq/config/BrokerXmlConfigTest.java) + +User Submitted Configurations +----------------------------- + +We have a page which allows users to submit details of their configurations. + +* [User Submitted Configurations](user-submitted-configurations) + +Background +---------- + +Since ActiveMQ Classic has so many strategy pattern plugins for transports, wire formats, persistence and many other things, we wanted to leave the configuration format open so that you the developer can configure and extend ActiveMQ Classic in any direction you wish. + +So we use the [Spring XML](http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-basics) configuration file format, which allows any beans / POJOs to be wired together and configured. However often Spring's XML can be kinda verbose at times, so we have implemented an ActiveMQ Classic extension to the Spring XML which knows about the common, standard ActiveMQ Classic things you're likely to do (e.g. tags like connector, wireFormat, serverTransport, persistence) - but at any time you can fall back to the normal Spring way of doing things (with tags like bean, property etc). + +To see documentation of the XML file we use or to get access to the XSD/DTD see the [Xml Reference](xml-reference) + diff --git a/hugo/content/components/classic/documentation/virtual-destinations.md b/hugo/content/components/classic/documentation/virtual-destinations.md new file mode 100644 index 0000000000..020e0c5260 --- /dev/null +++ b/hugo/content/components/classic/documentation/virtual-destinations.md @@ -0,0 +1,142 @@ +--- +title: Virtual Destinations +layout: classic-doc +--- + + +_Virtual Destinations_ allow us to create logical destinations that clients can use to produce and consume from but which map onto one or more _physical destinations_. It allows us to provide more flexible loosely coupled messaging configurations. + +Virtual Topics +-------------- + +The idea behind _publish subscribe_ is a great one. Allow producers to be decoupled from consumers so that they do not even know how many consumers are interested in the messages they publish. The JMS specification defines support for durable topics however they have limitations as we will describe... + +### The limitations of JMS durable topics + +A JMS durable subscriber MessageConsumer is created with a unique JMS clientID and durable subscriber name. To be JMS compliant only one JMS connection can be active at any point in time for one JMS clientID, and only one consumer can be active for a clientID and subscriber name. i.e., only **one** thread can be actively consuming from a given logical topic subscriber. This means we cannot implement + +* load balancing of messages. +* fast failover of the subscriber if that one process running that one consumer thread dies. + +Now _queue_ semantics in JMS offer the ability to load balance work across a number of consumers in a reliable way - allowing many threads, processes and machines to be used to process messages. Then we have sophisticated sticky load balancing techniques like [Message Groups](message-groups) to load balance and parallelise work while maintaining ordering. + +Another added benefit of having physical queues for each logical topic subscriber is we can them monitor the queue depths via [JMX](jmx) to monitor system performance together with being able to browse these physical queues. + +### Virtual Topics to the rescue + +The idea behind virtual topics is that producers send to a topic in the usual JMS way. Consumers can continue to use the Topic semantics in the JMS specification. However if the topic is virtual, consumer can consume from a physical queue for a logical topic subscription, allowing many consumers to be running on many machines & threads to load balance the load. + +E.g., let's say we have a topic called **VirtualTopic.Orders**. (Where the prefix VirtualTopic. indicates its a virtual topic). And we logically want to send orders to systems A and B. Now with regular durable topics we'd create a JMS consumer for clientID\_A and "A" along with clientID\_B and "B". + +With virtual topics we can just go right ahead and consume to queue **Consumer.A.VirtualTopic.Orders** to be a consumer for system A or consume to **Consumer.B.VirtualTopic.Orders** to be a consumer for system B. + +We can now have a pool of consumers for each system which then compete for messages for systems A or B such that all the messages for system A are processed exactly once and similarly for system B. + +### Customizing the out-of-the-box defaults + +The out-of-the-box defaults are described above. Namely that the only virtual topics available must be within the **VirtualTopic.>** namespace and that the consumer queues are named **Consumer.*.VirtualTopic.>**. + +You can configure this to use whatever naming convention you wish. The following [example](https://github.com/apache/activemq/tree/main/activemq-unit-tests/src/test/resources/org/apache/activemq/broker/virtual/global-virtual-topics.xml) shows how to make all topics virtual topics. The example below is using the name **>** to indicate 'match all topics'. You could use this wildcard to apply different virtual topic policies in different hierarchies. +``` + + + + + + + +``` +Note that making a topic virtual does add a small CPU overhead when sending messages to the topic but it is fairly small. + +Option|Default|Description +---|---|--- +selectorAware|false|only messages that match one of the existing subscribers are actually dispatched. Using this option prevents the build up of unmatched messages when selectors are used by exclusive consumers +local|false|when true, don't fan out messages that were received over a network +concurrentSend|false|when true, use an executor to fanout such that sends occur in parallel. This allows the journal to batch writes which will reduce disk io (5.12) +transactedSend|false|when true, use a transaction for fanout sends such that there is a single disk sync. A local broker transaction will be created if there is no client transaction (5.13) +dropOnResourceLimit|false|when true, ignore any ResourceAllocationException thrown during fanout (see: sendFailIfNoSpace policy entry) (5.16) +setOriginalDestination|true|when true, the destination on the forwarded message is set to the consumer queue and the originalDestination message property tracks the virtual topic (5.16) + +VirtualSelectorCacheBrokerPlugin +-------------------------------- + +When selectorAware=true, only active consumers are considered for selector matching. If consumers disconnect and reconnect they will miss messages. The intent of selectorAware=true is to not have messages build up. The virtualSelectorCacheBrokerPlugin provides a cache that tracks the selectors associated with a destination by a consumers such that they can apply in the absense of that consumer. In this way the just the selected messages build up. The existing set of selectors can be persisted such that it can be recovered on restart. the plugin is applied in the normal way to the plugins section. +Code Block + +``` + + + +``` + +Note: the persistFile option uses java serialisation that should be locked down with an appropriate jdk.serialFilter that allows ConcurrentHashMap + +Composite Destinations +---------------------- + +Composite Destinations allow for one-to-many relationships on individual destinations; the main use case is for _composite queues_. For example when a message is sent to queue A you may want to forward it also to queues B and C and topic D. Composite destinations are then a mapping from a virtual destination to a collection of other physical destinations. In this case the mapping is broker side and the client is unaware of the mapping between the destinations. This is different from client side [Composite Destinations](composite-destinations) where the client uses a URL notation to specify the actual physical destinations that a message must be sent to. + +The following [example](http://svn.apache.org/repos/asf/incubator/activemq/trunk/activemq-unit-tests/src/test/resources/org/apache/activemq/broker/virtual/composite-queue.xml) shows how to set up a **** element in the XML configuration so that when a message is sent to `MY.QUEUE` then it is really forwarded to the physical queue `FOO` and the topic `BAR`. +``` + + + + + + + + + + + + +``` +By default, subscribers cannot consume messages directly from a composite queue or topic - it is a logical construct only. Given the configuration above, subscribers can only consume messages from `FOO` and `BAR`; but not `MY.QUEUE`. + +This behaviour can be altered to implement use cases such as watching a queue by sending the same messages to a notification topic (wire tapping), by setting the optionally set `forwardOnly` attribute to false. +``` + + + + + +``` +Messages sent to `IncomingOrders` will all be copied and forwarded to `Notifications`, before being placed on the physical `IncomingOrders` queue for consumption by subscribers. + +Where the `forwardOnly` attribute is not defined or is set to `true`, there is no logical difference between a `compositeQueue` and a `compositeTopic` \- they can be used interchangeably. It is only when a composite destination is made physical through the use of `forwardOnly` that the choice of `compositeTopic`/`compositeQueue` has an impact on behavior. + +### Using filtered destinations + +From Apache ActiveMQ Classic **4.2** onwards you can now use selectors to define virtual destinations. + +You may wish to create a virtual destination which forwards messages to multiple destinations but applying a selector first to decide if the message really does have to go to a particular destination. + +The following example shows how a message sent to the virtual destination **MY.QUEUE** will be forwarded to **FOO** and **BAR** if the selectors match +``` + + + + + + + + +``` + +Avoiding Duplicate Message in a Network of Brokers +-------------------------------------------------- + +**TLDR:** bridge consumer queues or virtual topics, not both. + +Typically you would network consumer queues. In this case it is important to not bridge any normal topic consumer on the virtual topic because any forwarded message would again get fanned out to consumer queues on the networked broker, leading to duplicates. + +It is also possible to bridge the virtual topic in which case it is necessary exclude the consumer queues from any network connector configuration. + +Here is an example of how to exclude virtual topic consumer queues: +``` + + + + + +``` diff --git a/hugo/content/components/classic/documentation/web-console.md b/hugo/content/components/classic/documentation/web-console.md new file mode 100644 index 0000000000..e1833178fb --- /dev/null +++ b/hugo/content/components/classic/documentation/web-console.md @@ -0,0 +1,103 @@ +--- +title: Web Console +layout: classic-doc +--- + + + +The ActiveMQ Classic Web Console is a web based administration tool for working with ActiveMQ Classic. When used with the [JMX](jmx) support it can be an invaluable tool for working with ActiveMQ Classic + +### Running the Web Console on ActiveMQ Classic 5.0 or later + +We have integrated the Web Console into the binary distribution. So [Download](download) a binary distribution then follow the instructions for [Version 5 Run Broker](run-broker). Then you can point your web browser at the URL + +* [http://localhost:8161/admin](http://localhost:8161/admin) + +And hey presto, you should now have the Web Console running. + +In the event that you are running a standalone broker and the Web Console is not reachable, check that the following lines are included in your ActiveMQ Classic config xml: +``` + + +file:${activemq.base}/conf/credentials.properties + + + + + + +``` +The import will start up an embedded Jetty container. To verify that the config is working, the following should appear in your ActiveMQ Classic console/logs on next startup: +``` +INFO | jetty-7.1.6.v20100715 +INFO | ActiveMQ WebConsole initialized. +``` + +### Changing the port + +If you want to change the port number of the web console, see the configuration files in the conf directory. + +### Securing Web Console + +Starting with ActiveMQ Classic 5.4.0, Web Console comes pre-configured with basic access authentication setup. It's turned off by default, so you need to turn it on explicitly, but it's really simple. Go to the `${ACTIVEMQ_HOME}/conf/jetty.xml` and find the following line +``` + +``` +and change it to +``` + +``` +That's it. From that point on, web server will look at `${ACTIVEMQ_HOME}/conf/jetty-realm.properties` file trying to match provided credentials with those listed in the file. By default, you can access the web console with `admin/admin` credentials. That can be changed (and more users can be added) in the `jetty-realm.properties` file. + +You may also wish to enable **ssl connector** to further secure access to the web console and other web resources of the broker. To do that, go to the `${ACTIVEMQ_HOME}/conf/jetty.xml` and make sure you have the secure connector enabled. In versions 5.7 and newer just uncomment a predefined config. In any case make sure your connectors settings looks similar to this. +``` + + + + + + + + + + + + +``` +Standard connector is left enabled in this example, but you can remove it in your configuration if you wish. + +Note that these changes will affect the whole web server, so if you're using [REST](rest) API or blob fileserver be sure to provide appropriate credentials. + +If you're interested in securing 5.3.1 (and 5.3.2) Web consoles, take a look at [this article](http://www.nighttale.net/activemq/securing-activemq-531-console.html). For older versions, please refer to [this article](http://it.toolbox.com/blogs/unix-sysadmin/securing-activemq-web-console-27727) + +### Using the Web Console + +The web console is depicted in the following image: + +![](assets/img/web_console.png) + +To get started, go to the [Send](http://localhost:8080/activemq-web-console/send.jsp) page and send a message to a queue (you can send multiple if you like, see the message count field). + +Now that you have sent messages to a queue you should be able to [Browse](http://localhost:8080/activemq-web-console/browse.jsp) then and view the queue as an RSS or Atom feed. + +The Web Console has many features relative to it's tabs as shown in the following table. + +Tab|Features +---|--- +Home|[System Usage](producer-flow-control.md#ProducerFlowControl-Systemusage) +Queues| +Topics|[Viewing Advisory Messages](advisory-message) +Subscribers| +Connections|[Protocols](protocols) +Scheduled| +Send|[Delay and Schedule Message Delivery](delay-and-schedule-message-delivery) + +External Web Consoles +===================== + +There are a number of external web consoles for Apache ActiveMQ Classic in separate open source projects: + +External Project|Description +---|--- +[hawtio](http://hawt.io/)|hawtio is an open source HTML5 web application for visualising, managing, tracing and debugging Camel routes & endpoints, ActiveMQ Classic brokers, JMX, OSGi and logging. Here is a [blog entry](http://www.bennet-schulz.com/2016/07/apache-activemq-and-hawtio.html) how to install hawtio as web console for ActiveMQ Classic. +[RHQ](http://www.jboss.org/rhq)|RHQ is an open source operational monitoring tool which has support for Apache Camel (along with other Apache projects like Tomcat, httpd, ActiveMQ Classic etc) diff --git a/hugo/content/components/classic/documentation/websockets.md b/hugo/content/components/classic/documentation/websockets.md new file mode 100644 index 0000000000..020435292f --- /dev/null +++ b/hugo/content/components/classic/documentation/websockets.md @@ -0,0 +1,81 @@ +--- +title: WebSockets +layout: classic-doc +--- + + + +Introduction +============ + +Besides [Ajax](ajax) API, starting with version **5.4.0** onwards, you can use HTML5 [WebSockets](http://dev.w3.org/html5/websockets/) to exchange messages with the broker from your browser. + +HTML 5 introduced web sockets, as a standardized way to communicate asynchronously with the server from a web page. This is practically an ideal channel for implementing asynchronous messaging for web pages. Since JavaScript easily handles text and JSON formatted data, [Stomp](http://activemq.apache.org/stomp/) protocol is a good choice for the wire protocol to be used over web sockets. Since version **5.9.0**, we also support efficient binary MQTT protocol over Web sockets. + +This solution should bring better messaging capabilities to JavaScript clients then simple Ajax API, as implementing Stomp or MQTT in JavaScript brings much more messaging-oriented API and features such as transactions, for example. + +Configuration +============= + +ActiveMQ Classic comes with _WebSocket_ transport which implements Stomp over WebSockets functionality. + +To configure it, you need to place something like this to your ActiveMQ Classic configuration file + +```xml + + + +``` + +One thing worth noting is that web sockets (just as Ajax) implements the _same origin policy_, so you can access only brokers running on the same host as the web application running the client. + +Secure Web Sockets +================== + +Version 5.7.0 introduced _Secure Web Socket_ transport. To configure it you need two things. First, you need to configure a new transport connector like this + +```xml + + + +``` + +Note that we use _wss_ url prefix to denote a secured version of the protocol. Next you need to provide SSL context for this transport. You can do that by providing _sslContext_ in your broker configuration in a similar fashion as you'd do for _ssl_ or _https_ transports. + +```xml + + + +``` + +That's it, your secure websocket transport is ready. Take a look at the next section to see how to use a demo to test it out. + +Demos +===== + +As of version 5.6.0, an adapted demo of [stomp-websocket](http://github.com/jmesnil/stomp-websocket) library is integrated with ActiveMQ Classic web demo application. +As of version 5.9.0, we have a similar demo using MQTT and [Eclipse Paho client](http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.javascript.git) + +To see demos: + +* Start the broker with `ws` transport (you can use activemq-demo.xml configuration for that) +* Go to [http://localhost:8161/demo/websocket](http://localhost:8161/demo/websocket) to check Stomp example +* Go to [http://localhost:8161/demo/mqtt](http://localhost:8161/demo/mqtt) to check MQTT example + +Clients +======= + +* [Stomple](http://github.com/krukow/stomple) by [Karl Krukow](http://blog.higher-order.net/) +* [stomp-websocket](http://github.com/jmesnil/stomp-websocket) by [Jeff Mesnil](http://jmesnil.net/weblog/) +* [Eclipse Paho MQTT JavaScript client](http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.javascript.git) + +More Resources +============== + +* [ActiveMQ Classic 5.4: Stomp over Web Sockets](http://www.nighttale.net/activemq/activemq-54-stomp-over-web-sockets.html) +* [Stomple RC1: Combining WebSockets and Reliable Messaging](http://blog.higher-order.net/2010/06/01/stomple-rc1-combining-websockets-and-reliable-messaging/) +* [Stomp On Web Sockets](http://jmesnil.net/stomp-websocket/doc/) + diff --git a/hugo/content/components/classic/documentation/what-are-administered-objects.md b/hugo/content/components/classic/documentation/what-are-administered-objects.md new file mode 100644 index 0000000000..1c2fdb0576 --- /dev/null +++ b/hugo/content/components/classic/documentation/what-are-administered-objects.md @@ -0,0 +1,24 @@ +--- +title: What are administered objects +layout: classic-doc +--- + + + +What are administered objects? +------------------------------ + +Administered objects refers to objects that are configured in [JNDI](jndi-Community/support) and then accessed by a JMS client. So they are simply client-side objects typically either a ConnectionFactory or a Destination (such as a Queue or Topic). + +Note that administered objects are only used for JNDI. JNDI can then be used as a level of indirection between the JNDI API and the concrete API of the JMS provider. So looking up objects in JNDI avoids you having a runtime dependency on ActiveMQ Classic. Given that we are only talking about one ConnectionFactory object and a few Destination objects, this is not a huge big deal though ![(smile)](https://cwiki.apache.org/confluence/s/en_GB/5997/6f42626d00e36f53fe51440403446ca61552e2a2.1/_/images/icons/emoticons/smile.png) + +Often folks get very confused with JNDI. e.g. in RMI / EJB scenarios JNDI provides client side proxies; this is not the case with JMS, as the JMS client is the client side proxy to the broker. + +An alternative approach to creating administered objects in JNDI is to just use the [Spring Support](spring-Community/support) and let dependency injection be an alternative to JNDI. + +### See Also + +* [How do I create new destinations](how-do-i-create-new-destinations) +* [How do I embed a Broker inside a Connection](how-do-i-embed-a-broker-inside-a-connection) +* [How does ConnectionFactory relate to the Broker](how-does-connectionfactory-relate-to-the-broker) + diff --git a/hugo/content/components/classic/documentation/what-are-those-topics-activemqadvisory.md b/hugo/content/components/classic/documentation/what-are-those-topics-activemqadvisory.md new file mode 100644 index 0000000000..972b02a318 --- /dev/null +++ b/hugo/content/components/classic/documentation/what-are-those-topics-activemqadvisory.md @@ -0,0 +1,9 @@ +--- +title: What are those topics ActiveMQ.Advisory +layout: classic-doc +--- + + + +When you look at a broker using [JMX](jmx) you will see a number of topics starting with **ActiveMQ.Advisory.**. These are the destinations used by the [Advisory Message](advisory-message) feature of ActiveMQ Classic which allows you to listen to the behaviour of the system. + diff --git a/hugo/content/components/classic/documentation/what-happens-when-the-journal-size-is-exceeded.md b/hugo/content/components/classic/documentation/what-happens-when-the-journal-size-is-exceeded.md new file mode 100644 index 0000000000..a9d3ff9e1e --- /dev/null +++ b/hugo/content/components/classic/documentation/what-happens-when-the-journal-size-is-exceeded.md @@ -0,0 +1,9 @@ +--- +title: What happens when the journal size is exceeded +layout: classic-doc +--- + + + +If the "preferred" size is exceeded then the last log files keeps growing until the first log files can be overwritten. When a log file is overwritten, it's size is reset to the "preferred" size. + diff --git a/hugo/content/components/classic/documentation/what-happens-with-a-fast-producer-and-slow-consumer.md b/hugo/content/components/classic/documentation/what-happens-with-a-fast-producer-and-slow-consumer.md new file mode 100644 index 0000000000..c59683b41d --- /dev/null +++ b/hugo/content/components/classic/documentation/what-happens-with-a-fast-producer-and-slow-consumer.md @@ -0,0 +1,11 @@ +--- +title: What happens with a fast producer and slow consumer +layout: classic-doc +--- + + + +It depends a little on the [QoS](qos) but in general we implement _flow control_ which means that when we have a very fast producer and a slow consumer, when we get to a high water mark of outstanding messages we will start to tell the producer to slow down (which occurs inside the JMS client automatically, no application code changes are required). The slow down messages will increase exponentially over time until things get back into balance again. + +Flow control avoids unnecessary resource exhaustion and is particularly useful in non-durable messaging modes to avoid running out of memory / disk on a node. + diff --git a/hugo/content/components/classic/documentation/what-is-activemq-classic.md b/hugo/content/components/classic/documentation/what-is-activemq-classic.md new file mode 100644 index 0000000000..f17e937ef1 --- /dev/null +++ b/hugo/content/components/classic/documentation/what-is-activemq-classic.md @@ -0,0 +1,9 @@ +--- +title: What is ActiveMQ Classic +layout: classic-doc +--- + + + +ActiveMQ Classic is an open sourced implementation of JMS 1.1 as part of the J2EE 1.4 specification. + diff --git a/hugo/content/components/classic/documentation/what-is-the-difference-between-a-virtual-topic-and-a-composite-destination.md b/hugo/content/components/classic/documentation/what-is-the-difference-between-a-virtual-topic-and-a-composite-destination.md new file mode 100644 index 0000000000..c956543e74 --- /dev/null +++ b/hugo/content/components/classic/documentation/what-is-the-difference-between-a-virtual-topic-and-a-composite-destination.md @@ -0,0 +1,20 @@ +--- +title: What is the difference between a Virtual Topic and a Composite Destination +layout: classic-doc +--- + + + +What is the difference between a Virtual Topic and a Composite Destination +-------------------------------------------------------------------------- + +Both kinds of [Virtual Destinations](virtual-destinations) offer similar capabilities, namely that the producer sees a single Destination to send to and the consumer sees a different Destination to consume from and there can be a many to many map of producer Destination to many different consumer destinations (as well as a mix of Topics and Queues. + +The main difference between a Virtual Topic and a Composite Desetination is that with a Composite Destination the list of consumer destinations is static and hard wired. Whereas with a Virtual Topic at run time a new consumer or queue can be created dynamically and addded to the subscription without having to reconfigure the broker. + +e.g. for a virtual topic, **VirtualTopic.Orders** at run time a new consumer can be created on the non-existent queue **Consumer.FOO.VirtualTopic.Orders** (where FOO is the unique name of the consumer) and the queue will be created which is also automatically wired up to the virtual topic as a consumer queue. + +### See + +* [How does a Queue compare to a Topic](how-does-a-queue-compare-to-a-topic) + diff --git a/hugo/content/components/classic/documentation/what-is-the-difference-between-discovery-multicast-and-zeroconf.md b/hugo/content/components/classic/documentation/what-is-the-difference-between-discovery-multicast-and-zeroconf.md new file mode 100644 index 0000000000..89a3e2d01f --- /dev/null +++ b/hugo/content/components/classic/documentation/what-is-the-difference-between-discovery-multicast-and-zeroconf.md @@ -0,0 +1,37 @@ +--- +title: What is the difference between discovery, multicast and zeroconf +layout: classic-doc +--- + + + +Discovery refers to either a client (producer or consumer) establishing a 'transport connector' to the broker or a broker establishing 'network connector' to another broker without explicit static configuration of broker (IP or hostname). + +The scheme 'multicast' refers to either listening for or advertising discovery events on a multicast address. zeroconf is similar to multicast, except for protocol specific to Apple's Rendezvous (bonjour). + +### Broker + + + + + +The above configuration in the broker xml file will make it automatically establish network connectors to other brokers that advertise themselves on the multicast address: when this broker gets a discovery event from another broker, the event has information that enables it to establish network connector to that broker. + +Self-advertisement is facilitated by the following config: + + + + + + +### Client + +An example usage of discovery on the client side (using the transport 'discovery' that uses discovery agent) ... + + + + + +ps: discovery (which is a confusing name) is just like a 'reliable' transport such as [failover](failover-transport-reference). If it is unable to connect to a broker, it will try another broker (assuming it +heard its advertisement over multicast). + diff --git a/hugo/content/components/classic/documentation/what-is-the-difference-between-persistent-and-non-persistent-delivery.md b/hugo/content/components/classic/documentation/what-is-the-difference-between-persistent-and-non-persistent-delivery.md new file mode 100644 index 0000000000..500f4eb5f1 --- /dev/null +++ b/hugo/content/components/classic/documentation/what-is-the-difference-between-persistent-and-non-persistent-delivery.md @@ -0,0 +1,20 @@ +--- +title: What is the difference between persistent and non-persistent delivery? +layout: classic-doc +--- + + +What is the difference between persistent and non-persistent delivery? +---------------------------------------------------------------------- + +ActiveMQ Classic supports both persistent and non-persistent delivery. As per the JMS specification, the default delivery mode is persistent. The persistence flag is set on the MessageProducer for all messages using the setDeliveryMode. It can also be specified on a per message basis using the long form of the send method. Persistence is a property of a an individual message. + +The main difference is that if you are using persistent delivery, messages are persisted to disk/database so that they will survive a broker restart. When using non-persistent delivery, if you kill a broker then you will lose all in-transit messages. + +The effect of this difference is that persistent messaging is usually slower than non-persistent delivery, particularly when not using [Async Sends](async-sends). + +### See also + +* [Async Sends](async-sends) +* [How do I disable persistence](how-do-i-disable-persistence) + diff --git a/hugo/content/components/classic/documentation/what-is-the-license.md b/hugo/content/components/classic/documentation/what-is-the-license.md new file mode 100644 index 0000000000..69317047d6 --- /dev/null +++ b/hugo/content/components/classic/documentation/what-is-the-license.md @@ -0,0 +1,12 @@ +--- +title: What is the license +layout: classic-doc +--- + + + +What is the license? +-------------------- + +This software is open source using the [Apache 2.0 licence](http://www.apache.org/licenses/LICENSE-2.0.html) (a liberal BSD style license which is very commercial friendly) + diff --git a/hugo/content/components/classic/documentation/what-is-the-prefetch-limit-for.md b/hugo/content/components/classic/documentation/what-is-the-prefetch-limit-for.md new file mode 100644 index 0000000000..214d2e955d --- /dev/null +++ b/hugo/content/components/classic/documentation/what-is-the-prefetch-limit-for.md @@ -0,0 +1,62 @@ +--- +title: What is the Prefetch Limit For? +layout: classic-doc +--- + +One of the design goals of ActiveMQ Classic is to be a highly performant message bus. This means using a [SEDA](seda) architecture to perform as much work as possible asynchronously. To make efficient use of network resources the broker utilizes a 'push' model to dispatch messages to consumers. This ensures that a consumer always has a local buffer of messages ready to process. The alternative would be for consumers to explicitly pull messages from the broker. Pulling messages individually is not very efficient and can increase the per message latency significantly. + +However, there is a danger that without limiting the number of messages that are pushed to a consumer its client-side resources could become exhausted. This is the natural consequence of message consumption typically being much slower than message delivery. To avoid this situation ActiveMQ Classic therefore employs a **prefetch limit** to limit the maximum number of messages that can be dispatched to an individual consumer at once. The consumer in turn uses the prefetch limit to size its prefetch message buffer. + +Once the broker has dispatched a prefetch limit number of messages to a consumer it will not dispatch any more messages to that consumer until the consumer has acknowledged at least 50% of the prefetched messages, e.g., prefetch/2, that it received. When the broker has received said acknowledgements it will dispatch a further prefetch/2 number of messages to the consumer to 'top-up', as it were, its prefetch buffer. Note that it's possible to specify a prefetch limit on a per consumer basis (see below). + +Large prefetch values are recommended for high performance with high message volumes. However, for lower message volumes, where each message takes a long time to process, the prefetch should be set to 1. This ensures that a consumer is only processing one message at a time. Specifying a prefetch limit of zero, however, will cause the consumer to poll for messages, one at a time, instead of the message being pushed to the consumer. + +> **What is a Slow Consumer?** +> +> A slow consumer is one that has more than twice its configured prefetch limit number of messages pending. + +> **Implementing Consumers Using a Dynamic Language** +> +> Consumers that are unable to cache prefetched messages must set their prefetch to 1. An example of such a consumer is one implemented using a scripting language like Ruby, say, that connects via STOMP. In this case there's no notion of a client-side message buffer. + +### Specifying the PrefetchPolicy + +You can specify an instance of the [ActiveMQPrefetchPolicy](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/ActiveMQPrefetchPolicy.html) on an [ActiveMQConnectionFactory](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/ActiveMQConnectionFactory.html) or [ActiveMQConnection](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/ActiveMQConnection.html). This allows you to configure all the individual prefetch values; as each different quality of service has a different value. e.g. + +* persistent queues (default value: `1000`) + +* non-persistent queues (default value: `1000`) + +* persistent topics (default value: `100`) + +* non-persistent topics (default value: `Short.MAX_VALUE - 1`) + + +The prefetch limit can also be configured on the connection URI used to establish a connection the broker. To change the prefetch limit for all consumer types configure a connection URI as follows: +``` +tcp://localhost:61616?jms.prefetchPolicy.all=50 +``` +To change the prefetch limit for queue consumers only configure the connection URI as follows: +``` +tcp://localhost:61616?jms.prefetchPolicy.queuePrefetch=1 +``` +It can also be configured on a per consumer basis using [Destination Options](destination-options): +``` +queue = new ActiveMQQueue("TEST.QUEUE?consumer.prefetchSize=10"); +consumer = session.createConsumer(queue); +``` +### Pooled Consumers and Prefetch + +Consuming messages from a pool of consumers an be problematic due to prefetch. Unconsumed prefetched messages are only released when a consumer is closed, but with a pooled consumer the close is deferred (for reuse) till the consumer pool closes. This leaves prefetched messages unconsumed till the consumer is reused. This feature can be desirable from a performance perspective. However, it can lead to out-of-order message delivery when there is more than one consumer in the pool. For this reason, the [org.apache.activemq.pool.PooledConnectionFactory](http://activemq.apache.org/components/classic/documentation/maven/apidocs/org/apache/activemq/jms/pool/PooledConnectionFactory.html) does **not** pool consumers. + +Pooling consumers is supported by Springs CachingConnectionFactory (although turned off by default). In case you use the CachingConnectionFactory with multiple consumer threads configured in Springs DefaultMessageListenerContainer (DMLC) then you either want to turn off consumer pooling in the CachingConnectionFactory (its off by default) or you may want to use a prefetch of 0 when pooling consumers. In this way, the consumer will poll for messages on each call to `receive(timeout)`. Its generally recommended to turn off consumer caching in Springs CachingConnectionFactory and any other frameworks that allow to pool JMS consumers. + +Note that Springs DefaultMessageListenerContainer (DMLC) and its `CACHE_CONSUMER` cache level is not affected by this problem! Springs DMLC does not pool consumers in the sense that it does not use an internal pool with multiple consumer instances. Instead it caches the consumer, i.e. it re-uses the same JMS consumer object to receive all messages for the life time of the DMLC instance. So it behaves pretty much like properly hand written JMS code, where you create the JMS connection, session, consumer and then use this consumer instance to receive all your messages. +Hence there is no problem with using  `CACHE_CONSUMER` in Springs DMLC, even with multiple consumer threads, unless you are using XA transactions. XA transactions do not work with `CACHE_CONSUMER`. However local JMS transactions and non-transacted consumers are just fine to use  `CACHE_CONSUMER` in Springs DMLC. + +Also note that Camel's [JMS](http://camel.apache.org/FAQ/jms.html) or [ActiveMQ Classic](http://camel.apache.org/activemq.html) components use Springs DMLC internally. So everything said above about Springs DMLC and  `CACHE_CONSUMER` applies to these two Camel components as well. + +### Ram vs. Performance Trade-off + +Setting a relatively high value of prefetch leads to higher performance. Therefore the default values are typically greater than 1000 and much higher for topics and higher still for the non-persistent messages. The prefetch size dictates how many messages will be held in RAM on the client so if your RAM is limited you may want to set a low value such as 1 or 10 etc. + diff --git a/hugo/content/components/classic/documentation/what-jars-do-i-need.md b/hugo/content/components/classic/documentation/what-jars-do-i-need.md new file mode 100644 index 0000000000..4a1a673e67 --- /dev/null +++ b/hugo/content/components/classic/documentation/what-jars-do-i-need.md @@ -0,0 +1,12 @@ +--- +title: What jars do I need +layout: classic-doc +--- + + + +What jars do I need +------------------- + +The basic jars you need to use are described on the [Initial Configuration](initial-Community/FAQ/configuration) page. + diff --git a/hugo/content/components/classic/documentation/what-open-source-integration-solution-works-best-with-activemq-classic.md b/hugo/content/components/classic/documentation/what-open-source-integration-solution-works-best-with-activemq-classic.md new file mode 100644 index 0000000000..f0cdd9886c --- /dev/null +++ b/hugo/content/components/classic/documentation/what-open-source-integration-solution-works-best-with-activemq-classic.md @@ -0,0 +1,13 @@ +--- +title: What open source integration solution works best with ActiveMQ Classic +layout: classic-doc +--- + + + +The [Apache Camel](http://camel.apache.org) project has been designed to work easily with ActiveMQ Classic - and comes [embedded](http://activemq.apache.org/camel/how-does-camel-work-with-activemq.html) in both the clients and the broker from ActiveMQ Classic 5.0 onwards. + +[Apache Camel](http://camel.apache.org) supports an extensive range of [integration patterns](http://camel.apache.orgFeatures/enterprise-integration-patterns) to make integration very simple! + +`It also supports a wide range of [transport binding components](http://camel.apache.org/components.html)** + diff --git a/hugo/content/components/classic/documentation/what-platforms-does-activemq-classic-support.md b/hugo/content/components/classic/documentation/what-platforms-does-activemq-classic-support.md new file mode 100644 index 0000000000..75b5f8e245 --- /dev/null +++ b/hugo/content/components/classic/documentation/what-platforms-does-activemq-classic-support.md @@ -0,0 +1,21 @@ +--- +title: What platforms does ActiveMQ Classic support +layout: classic-doc +--- + + + +What platforms does ActiveMQ Classic Support? +--------------------------------------------- + +ActiveMQ Classic 5.0-5.7 supports any Java platform of Java 5.0 or later. To run on 1.4 see [these instructions](can-i-use-activemq-classic-5x-or-later-on-java-14). ActiveMQ Classic 5.8-5.10 require Java 6 or higher and the releases from 5.11 onwards require Java 7 or later.  + +ActiveMQ Classic is based on J2EE 1.4 or later and so implements JMS 1.1 and a JCA 1.5 Resource Adaptor. + +We regularly test ActiveMQ Classic on Windows, OS X, Linux though we're aware of folks who use AIX and Solaris too. + +See Also +-------- + +* [Can I use ActiveMQ Classic 5.x or later on Java 1.4](can-i-use-activemq-classic-5x-or-later-on-java-14) + diff --git a/hugo/content/components/classic/documentation/what-version-should-i-use.md b/hugo/content/components/classic/documentation/what-version-should-i-use.md new file mode 100644 index 0000000000..5eb8e1650f --- /dev/null +++ b/hugo/content/components/classic/documentation/what-version-should-i-use.md @@ -0,0 +1,13 @@ +--- +title: What version should I use +layout: classic-doc +--- + + + +ActiveMQ Classic version numbers follow the **MAJOR.MINOR.PATCH** convention used by many software projects.  In general, patch releases are done only when there are significant enough bugs found in the current minor version to justify a release sooner than the next minor release (though 5.9.1 was an exception, as it was just as large as a minor release).  As a result, you should generally use the most recent patch version of whichever minor release you choose; there is very seldom a reason to pick a patch version other than the latest within a given minor version. + +You should also generally use the most recent minor version if possible since it will include bug fixes that may let you avoid being caught by problems in the older minor versions, though as always you may have reasons to deviate from this general rule (bugs introduced in the newer minor version, difficulty getting your company's security department to approve a new version, etc.). + +In all cases, when deciding what version to use you should review the release notes of the later version and of all intermediate versions (e.g. if deciding between 5.9.1 and 5.11.1, you should review the release notes for 5.10.0, 5.11.0, and 5.11.1) to understand what bugs are fixed in the later version, and you should review the release notes for versions after the later version as well as the unresolved issues in [JIRA](http://thoughts and suggestions) to understand what bugs were introduced after the earlier version. + diff --git a/hugo/content/components/classic/documentation/while-posting-large-binary-file-to-activemq-is-there-a-way-to-measure-its-progress.md b/hugo/content/components/classic/documentation/while-posting-large-binary-file-to-activemq-is-there-a-way-to-measure-its-progress.md new file mode 100644 index 0000000000..9092b1155b --- /dev/null +++ b/hugo/content/components/classic/documentation/while-posting-large-binary-file-to-activemq-is-there-a-way-to-measure-its-progress.md @@ -0,0 +1,9 @@ +--- +title: While posting large binary file to activeMQ, is there a way to measure its progress +layout: classic-doc +--- + + + +If you are using the [JMS Streams](jms-streams) feature with 4.x of ActiveMQ Classic you'd be able to watch the progress in a JMX console by looking at the queue depths; each large 1Gb file is split into individual JMS messages so you can monitor queue depth etc to track progress + diff --git a/hugo/content/components/classic/documentation/why-do-i-not-get-all-of-the-messages-i-sent.md b/hugo/content/components/classic/documentation/why-do-i-not-get-all-of-the-messages-i-sent.md new file mode 100644 index 0000000000..c7ea8bb3c9 --- /dev/null +++ b/hugo/content/components/classic/documentation/why-do-i-not-get-all-of-the-messages-i-sent.md @@ -0,0 +1,13 @@ +--- +title: Why do I not get all of the messages I sent +layout: classic-doc +--- + + + +### **For ActiveMQ Classic 3.x/4.x** + +As [Matt reported](http://forums.logicblaze.com/posts/list/0/14.page#37) its possible that there is a race condition in your application; are you sure you had created your consumer and called start() on the JMS Connection before the producer started publishing messages? + +Another option if startup race conditions are a problem is to use durable messaging. + diff --git a/hugo/content/components/classic/documentation/why-do-i-not-receive-messages-on-my-durable-topic-subscription.md b/hugo/content/components/classic/documentation/why-do-i-not-receive-messages-on-my-durable-topic-subscription.md new file mode 100644 index 0000000000..0cdd16d24d --- /dev/null +++ b/hugo/content/components/classic/documentation/why-do-i-not-receive-messages-on-my-durable-topic-subscription.md @@ -0,0 +1,20 @@ +--- +title: Why do I not receive messages on my durable topic subscription +layout: classic-doc +--- + + + +You follow these steps + +1. Create a durable topic subscription +2. Kill the consumer +3. Publish some messages to the topic +4. Restart the subscriber + +But you don't receive the messages? + +### Fix + +To be able to deliver messages to offline durable topic subscribers you must mark the message as being persistent. To do this set the PERSISTENT_DELIVERY mode on the MessageProducer as described [here](how-do-i-make-messages-durable). + diff --git a/hugo/content/components/classic/documentation/why-do-kahadb-log-files-remain-after-cleanup.md b/hugo/content/components/classic/documentation/why-do-kahadb-log-files-remain-after-cleanup.md new file mode 100644 index 0000000000..c8015225ae --- /dev/null +++ b/hugo/content/components/classic/documentation/why-do-kahadb-log-files-remain-after-cleanup.md @@ -0,0 +1,72 @@ +--- +title: Why do KahaDB log files remain after cleanup +layout: classic-doc +--- + + + +Clean-up of un-referenced KahaDB journal log files **`data-.log`** will occur every 30 seconds by default. If a data file is in-use it will not be cleaned up. + +A data file may be in-use because: + +1. It contains a pending message for a destination or durable topic subscription +2. It contains an ACK for a message which is in an in-use data file - the ACK cannot be removed as a recovery would then mark the message for redelivery +3. The journal references a pending transaction +4. It is a journal file, and there may be a pending write to it + +The **`TRACE`** level logging of the **`org.apache.activemq.store.kahadb.MessageDatabase`** class provides insight into the cleanup process and will allow you to determine why a given data file is considered in-use and as a result, not a candidate for cleanup. + +To debug, add the following (or similar) to your **`log4j.properties`** file (if needed): + +log4j.appender.kahadb=org.apache.log4j.RollingFileAppender +log4j.appender.kahadb.file=${activemq.base}/data/kahadb.log +log4j.appender.kahadb.maxFileSize=1024KB +log4j.appender.kahadb.maxBackupIndex=5 +log4j.appender.kahadb.append=true +log4j.appender.kahadb.layout=org.apache.log4j.PatternLayout +log4j.appender.kahadb.layout.ConversionPattern=%d \[%-15.15t\] %-5p %-30.30c{1} - %m%n +log4j.logger.org.apache.activemq.store.kahadb.MessageDatabase=TRACE, kahadb + +Either restart ActiveMQ Classic and let the cleanup process run (give it a minute or two for example) or alternatively apply this logging configuration to a running broker via JMX. The **`Broker`** MBean exposes an operation called **`reloadLog4jProperties`** in JMX that can be used to tell the broker to reload its **`log4j.properties`**. Often its enough to apply this logging configuration for 2-5 minutes and then analyze the broker's log file. + +Examine the log file and look for cleanup of the data files. The process starts with the complete set of known data files and queries the index on a per destination basis to prune this list. Anything that remains is a candidate for cleanup. The trace logging gives the destination and the log file numbers that remain candidates for removal as it iterates through the index. + +At some point you'll hit a destination and the number of data file ids will suddenly drop because that destination references them. It could be a DLQ or an offline durable subscriber. In any event, the logging will help you pinpoint the destinations that are hogging disk space. + +Here is a quick sample: + + TRACE | Last update: 164:41712, full gc candidates set: \[86, 87, 163, 164\] | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Journal Checkpoint Worker + TRACE | gc candidates after first tx:164:41712, \[86, 87, 163\] | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Journal Checkpoint Worker + TRACE | gc candidates after dest:0:A, \[86, 87, 163\] | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Journal Checkpoint Worker + TRACE | gc candidates after dest:1:B, \[86, 87, 163\] | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Journal Checkpoint Worker + TRACE | gc candidates after dest:0:D, \[86, 87, 163\] | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Journal Checkpoint Worker + TRACE | gc candidates after dest:0:E, \[86, 87\] | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Journal Checkpoint Worker + TRACE | gc candidates after dest:0:H, \[86, 87\] | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Journal Checkpoint Worker + TRACE | gc candidates after dest:0:I, \[86, 87\] | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Journal Checkpoint Worker + TRACE | gc candidates after dest:0:J, \[87\] | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Journal Checkpoint Worker + TRACE | gc candidates: \[87\] | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Journal Checkpoint Worker + DEBUG | Cleanup removing the data files: \[87\] | org.apache.activemq.store.kahadb.MessageDatabase | ActiveMQ Journal Checkpoint Worker + +We get one candidate, **`data-87.log`** from the existing set of journal data files **`[86, 87, 163, 164]`**. There is a current transaction using **`164`**, destination (Queue named **`E`**) `'**0:E**'` has some messages in **`163`**, destination `'**0:I**'` has messages in **`86`** and **`87`** is un-referenced. In this case, there must be some long standing un-acknowledged messages or a very slow consumer on destination `'**0:I**'`. + +The `'**0:**'` prefix is shorthand for a queue, `'**1:**'` for a topic. Example: **`dest:1:B`** refers to a topic named **`B`**. + +* * * + +### Non-persistent messages + +Similar for non-persistent messages that are not stored in your configured KahaDB persistence adapter but get swapped to temp storage once they exceed the broker's configured **`memoryUsage`** limit. A similar logging configuration can show details of the cleanup of temp storage. + +log4j.appender.kahadb=org.apache.log4j.RollingFileAppender +log4j.appender.kahadb.file=${activemq.base}/data/kahadb.log +log4j.appender.kahadb.maxFileSize=1024KB +log4j.appender.kahadb.maxBackupIndex=5 +log4j.appender.kahadb.append=true +log4j.appender.kahadb.layout=org.apache.log4j.PatternLayout +log4j.appender.kahadb.layout.ConversionPattern=%d \[%-15.15t\] %-5p %-30.30c{1} - %m%n +log4j.logger.org.apache.activemq.store.kahadb=TRACE, kahadb +log4j.logger.org.apache.activemq.store.kahadb.MessageDatabase=INFO, kahadb +  + +Note the last line of above logging configuration disables the verbose logging of the KahaDB cleanup task. If that line gets removed, the cleanup details of both KahaDB and temp storage will be logged to the same file but you need to be careful not to mix the logging output. + diff --git a/hugo/content/components/classic/documentation/wildcards.md b/hugo/content/components/classic/documentation/wildcards.md new file mode 100644 index 0000000000..3c43a6f66e --- /dev/null +++ b/hugo/content/components/classic/documentation/wildcards.md @@ -0,0 +1,69 @@ +--- +title: Wildcards +layout: classic-doc +--- + + + +We support destination wildcards to provide easy support for federated name hierarchies. This concept has been popular in financial market data for some time as a way of organizing events (such as price changes) into hierarchies and to use wildcards for easy subscription of the range of information you're interested in. + +For example imagine you are sending price messages from a stock exchange feed. You might use some kind of destination such as + +* `PRICE.STOCK.NASDAQ.ORCL` to publish Oracle Corporation's price on NASDAQ and +* `PRICE.STOCK.NYSE.IBM` to publish IBM's price on the New York Stock Exchange + +A subscriber could then use exact destinations to subscribe to exactly the prices it requires. Or it could use wildcards to define hierarchical pattern matches to the destinations to subscribe from. + +### Wildcards supported + +We support the following wildcards which are fairly standard practice; wildcards are not part of the JMS specification so are custom enhancements. + +* `.` is used to separate names in a path +* `*` is used to match any name in a path +* `>` is used to recursively match any destination starting from this name + +For example using the example above, these subscriptions are possible + +Subscription + +Meaning +``` +`PRICE.>` +``` +Any price for any product on any exchange +``` +`PRICE.STOCK.>` +``` +Any price for a stock on any exchange +``` +`PRICE.STOCK.NASDAQ.*` +``` +Any stock price on NASDAQ +``` +`PRICE.STOCK.*.IBM` +``` +Any IBM stock price on any exchange + +`Note:** Don't specify any string after '>' on your wildcard expression, it will be ignored. E.g. using a wildcard `PRICE.>.IBM` will also match `PRICE.STOCK.NASDAQ.FB.` Using '>' really matches everything till the end of the destination name. + +### Custom path separator + +As of version 5.5.0 we support [plugin](interceptors) that allows clients to use customer path separator. So instead of +``` +`FOO.BAR.*` +``` +you can use +``` +`FOO/BAR/*` +``` +To +``` + + ..... + + +``` +ActiveMQ Classic 3.2.1 Release + +A default path separator this plugin will use is `/`. You can customize it further using `pathSeparator` property. + diff --git a/hugo/content/components/classic/documentation/wire-protocol.md b/hugo/content/components/classic/documentation/wire-protocol.md new file mode 100644 index 0000000000..01b4f97ddb --- /dev/null +++ b/hugo/content/components/classic/documentation/wire-protocol.md @@ -0,0 +1,73 @@ +--- +title: Wire Protocol +layout: classic-doc +--- + + + +This page describes the logical [OpenWire](openwire) protocol for users developing clients in other languages than Java such as C# or C native clients. Note that OpenWire is designed for maximum performance and features; its the protocol used inside ActiveMQ Classic. If you want a simpler protocol to work with to get started with a cross language client then try [Stomp](stomp) which is designed for ease-of-implementation so its easy to support many clients. + +Protocol overview +================= + +A client of ActiveMQ Classic will exchange Command objects (following the _Command Pattern_). We'll describe how these commands are exchanged... + +The protocol uses mostly one way messaging (fire and forget) for most kinds of commands - but there are times when RPCs (request, response) messaging is used. We'll indiciate the RPC scenarios clearly. + +Establishing connections +------------------------ + +The client must send a ConnectionInfo command with details of the machine, host name, user name, password and most importantly the unique clientId the client wishes to use and then wait for a valid Response before continuing. The clientId must be generated using a unique string generator. + +Sending messages +---------------- + +Once you've established a connection, you need to create a logical MessageProducer. This involves sending a ProducerInfo command with a unique producerId, sessionId and the clientId (connection ID). + +From that point on you can send a Message command any time you like, provided you adorn the message with the clientId, sessionId, producerId along with a transactionId if required (see below on transactions). + +Consuming messages +------------------ + +Commands are delivered on your inbound socket for consumption. Some of these will be Responses of previous RPCs, the rest will be incoming Messages for dispatch. + +To start consuming messages you must send a ConsumerInfo command with details of the clientId, sessionId and a unique consumerId. From this point on you will receive inbound messages which contain the consumerId for which they are destined for. + +To acknowledge a message send a MessageAck to the server (one way). Fill in the MessageAck with details of the consumerId, sessionId, clientId and any transactionIds. + +Working with Responses +---------------------- + +When you create a connection, a producer and a consumer you will receive a Response to indicate the status of the request (such as did it work or fail). Since the protocol is asynchronous you can receive Response commands out of order; you could have multiple threads using the same connection/socket sending commands in parallel. + +So its usual in multi-threaded clients to have some kind of correlation Map to match Command ids with Response Ids so that you can know which operation in what thread worked or failed etc. See the Transport implementations in Java to see how we do that. e.g. see [ResponseCorrelator](https://github.com/apache/activemq/tree/main/activemq-core/src/main/java/org/apache/activemq/transport/ResponseCorrelator.java) + +IDs +--- + +It is currently a requirement of the client to automatically generate client, session, producer and consumer IDs which are typically Strings and indended to be globally unique. Similarly each Command has its own integer counter ID which is used for the client to correlate requests to responses; the client will typically use an incrementing rolling counter for these. + +Closing producers, consumers, sessions, connections +--------------------------------------------------- + +To close a resource send a RemoveInfo command with the correct objectId for the producer, consumer, session, connection etc. + +JMS Transactions +---------------- + +Each transacted session generates a unique transaction ID which is passed along on any transaction message. To start, commit or rollback the client should send a TransactionInfo command oneway (no Response is generated). + +After a commit or rollback a new transaction ID should be generated and a new start TransactionInfo sent. + +Any messages sent or message acknowledgements made should also propogate the transaction Id. + +XA Transactions +--------------- + +As above but using the XATransactionInfo. Also we pass an XAid rather than a transactionID. + +Final thoughts +============== + +If in doubt about a piece of the protocol, the easiest way to figure out what happens is to check the JMS client code. In particular check out the code of [ActiveMQSession](http://activemq.codehaus.org/maven/xref/org/activemq/ActiveMQSession.html) which contains pretty much all the above logic. Pay particular attention to calls to **syncSendCommand()** and **asyncSendCommand()** when Commands are sent to the Message Broker + diff --git a/hugo/content/components/classic/documentation/xml-reference.md b/hugo/content/components/classic/documentation/xml-reference.md new file mode 100644 index 0000000000..424483c273 --- /dev/null +++ b/hugo/content/components/classic/documentation/xml-reference.md @@ -0,0 +1,69 @@ +--- +title: Xml Reference +layout: classic-doc +--- + +## ActiveMQ Classic Xml Reference + +This page contains links to the XML reference guides and XML schema documents for [Xml Configuration](xml-configuration) with ActiveMQ Classic releases. + +### Released Schemas + +| Version | Reference | XML Schema | XML Schema Namespace | +|---|---|---|---| +| ActiveMQ v5.17.2 | [Reference](http://activemq.apache.org/schema/core/activemq-core-5.17.2-schema.html) | [activemq-core-5.17.2.xsd](http://activemq.apache.org/schema/core/activemq-core-5.17.2.xsd) | [http://activemq.apache.org/schema/core](http://activemq.apache.org/schema/core) | +| ActiveMQ v5.16.5 | [Reference](http://activemq.apache.org/schema/core/activemq-core-5.16.5-schema.html) | [activemq-core-5.16.5.xsd](http://activemq.apache.org/schema/core/activemq-core-5.16.5.xsd) | [http://activemq.apache.org/schema/core](http://activemq.apache.org/schema/core) | + +Browse all versions: [Schema listing](http://activemq.apache.org/schema/core/) + +### Using the XSDs in Configuration Files + +If you are using XBean to parse the XML configurations, XML validation is optional so you do not need to specify the XML Schema Locations. However if you are using Spring's 2.0 XML handling you need to refer to the XSD locations because Spring uses schema namespace or schema location to resolve namespace handlers. + +Refer to a specific version: +```xml + +``` + +Or use a generic XSD without a version number: +```xml + +``` + +### Pay Attention to the Namespace + +- ActiveMQ Classic 5.0 or earlier: use `http://activemq.org/config/1.0` +- ActiveMQ Classic 5.1 or later: use `http://activemq.apache.org/schema/core` + +**ActiveMQ Classic 5.2+ example:** +```xml + + +``` + +### Schema Validation + +> **Note:** The XML configuration ordering constraint is removed in [5.6](https://issues.apache.org/jira/browse/AMQ-3570). + +Beginning in ActiveMQ Classic 5.4, the XML elements inside the `` element must be ordered alphabetically. You can disable validation from the command line: +``` +bin/activemq console xbean:conf/activemq.xml?validate=false +``` diff --git a/hugo/content/components/classic/documentation/xmpp.md b/hugo/content/components/classic/documentation/xmpp.md new file mode 100644 index 0000000000..4e511c648f --- /dev/null +++ b/hugo/content/components/classic/documentation/xmpp.md @@ -0,0 +1,104 @@ +--- +title: XMPP +layout: classic-doc +--- + + + +XMPP Protocol Support (Jabber!) +------------------------------- + +> **Deprecated** +> +> This transport was deprecated in 5.8.0 and has been removed in a 5.9.0! + +We have support for [XMPP](http://www.xmpp.org/) (Jabber) as a transport in ActiveMQ Classic. + +To use just add a connector as follows +``` + + + + + + + +``` +And you can now use XMPP to connect to the broker & send and receive messages. + +> Some versions of the broker (5.0-5.2) does not include [WoodStox](http://woodstox.codehaus.org/) library by default, which could impact ActiveMQ Classic XMPP funcionality. You should have a library named like `wstx-asl-x.x.x.jar` in the `lib/optional` directory of your broker. If that's not the case, download it from [here](http://woodstox.codehaus.org/) and put it in the classpath + +### XMPP Support in Apache ActiveMQ Classic + +ActiveMQ Classic provides a bidirectional bridge between ActiveMQ Classic messages and XMPP. + +* if a client joins a chatroom / conference room, the name of the conference room is mapped to a JMS topic of the same name +* typing into a chatroom sends a message to the topic +* presence in a chatroom maintains a subscription on the JMS topic (using noLocal to avoid getting copies of things you say) so that messages sent by other clients (via [XMPP](xmpp), the [Web Console](web-console), the [Examples](examples) or any other [Cross Language Clients](cross-language-clients)) are then sent to the chatroom. + +### Using a Jabber Client + +Basically, you should be able to connect from any Jabber-compatible client to the broker. The below example is using [Spark](http://jivesoftware.com/products/spark/) 2.0.0 version. For more details on connecting with different clients take a look at [#Jabber clients compatibility](xmpp). + +To connect to Apache ActiveMQ Classic try the following... + +1. Run the [Web Console](web-console) +2. Start [Spark](http://jivesoftware.com/products/spark/) or whatever Jabber Client you wish +3. Login to localhost:61222 + + > Some Jabber clients (like iChat) insist on usernames in forms of _username@host_, so in that case just append _@localhost_ to your username + + ![](assets/img/step1.png) + + > Some Jabber clients like to auto-discover the host and port. You need to explicitly disable this feature so you can explicitly configure **localhost** as the host and **61222** as the port. + > + > e.g. on Spark go to the **Advanced** tab and disable the **Automatically discover host and port** + +4. You should now see the following screen... + + ![](assets/img/step2.png) + +5. Now click on the **Join Conference Room** button (next to the Add Contact button) and the following dialog should appear + + ![](assets/img/step3.png) + +6. Now press the **Create or Join Room** button to get the following dialog. Enter a JMS topic name, in this case **foo.bar** and you're good to go... + + ![](assets/img/step4.png) + +7. Now your chat window should appear for talking and listening to the topic **foo.bar**. So start typing to test things out.  + + ![](assets/img/step5.png) + +8. Now if you go to the [Topic Console](http://localhost:8161/admin/topics.jsp) in the Web Console you should see the topic has been created + + ![](assets/img/step6-new.png) + +9. If you now click on the **Send To** link next to the **foo.bar** topic you can send a message to the topic from the web console.  + + ![](assets/img/step7-new.png) + +10. Press send and you should see the chat appear on the chat window + + ![](assets/img/step8.png) + +### Jabber clients compatibility + +Here you can find specfic issues and workarounds for various Jabber clients. If you have some of your own, please post them here. + +#### Spark + +Url: [http://www.igniterealtime.org/projects/spark/index.jsp](http://www.igniterealtime.org/projects/spark/index.jsp) +Spark 2.0.0 works fine with ActiveMQ Classic; Click [here](http://www.igniterealtime.org/downloads/download-landing.jsp?file=spark/spark_2_ 0_0.exe) to download: [Spark 2.0.0 for Windows](http://www.igniterealtime.org/downloads/download-landing.jsp?file=spark/spark_2_0_0.exe). +Spark 2.5.x connects fine, but it won't open the **Join Conference Room** dialog. + +#### iChat + +Url: [http://www.apple.com/macosx/features/ichat.md](http://www.apple.com/macosx/features/ichat) +Tested version 4.0.7 works fine, but it insists you use _username@host_ format for usernames + +#### Adium + +Url: [http://www.adiumx.com/](http://www.adiumx.com/) +Tested version 1.3.3 works fine. The only spotted issue is reconnecting to [Command Agent](command-agent) topic. We recommend that you restart the Adium if you need to do this + diff --git a/hugo/content/components/cms/_index.md b/hugo/content/components/cms/_index.md new file mode 100644 index 0000000000..b602535db1 --- /dev/null +++ b/hugo/content/components/cms/_index.md @@ -0,0 +1,5 @@ +--- +title: CMS Client +subtitle: C++ Messaging API +layout: cms +--- diff --git a/hugo/content/components/cms/configuring.md b/hugo/content/components/cms/configuring.md new file mode 100644 index 0000000000..7cf3709f0a --- /dev/null +++ b/hugo/content/components/cms/configuring.md @@ -0,0 +1,90 @@ +--- +title: Configuring ActiveMQ-CPP +layout: cms-page +--- + +All configuration is achieved via URI-encoded parameters, either on the connection or destinations. + +### Connection URI Parameters + +##### Example Configuration + +``` +cf = new ActiveMQConnectionFactory( + "tcp://localhost:61616?wireFormat=openwire&wireFormat.tightEncodingEnabled=true"); +``` + +For a more reliable connection use the Failover Transport: + +``` +cf = new ActiveMQConnectionFactory( + "failover://(tcp://localhost:61616,tcp://anotherhost:61616)?connection.useAsyncSend=true"); +``` + +### Protocol Options + +| Option | Description | +|---|---| +|tcp|Uses TCP/IP Sockets to connect to the broker.| +|ssl|Uses OpenSSL to secure TCP/IP sockets. (Since v3.2.0)| +|failover|Composite transport; reconnects to the next URI on failure.| + +#### Socket Options + +| Option | Default | Description | +|---|---|---| +|inputBufferSize|10000|Bytes in the buffered input stream's buffer| +|outputBufferSize|10000|Bytes in the buffered output stream's buffer| +|soLinger|0|Socket SOLinger value| +|soKeepAlive|false|Socket SOKeepAlive value| +|soReceiveBufferSize|-1|Socket receive buffer (-1 = OS default)| +|soSendBufferSize|-1|Socket send buffer (-1 = OS default)| +|soConnectTimeout|-1|Connection timeout in microseconds (-1 = OS default)| +|tcpNoDelay|true|Sets TCP_NODELAY| + +#### Failover Transport Options + +| Option | Default | Description | +|---|---|---| +|initialReconnectDelay|10|Wait time (ms) before first reconnect attempt| +|maxReconnectDelay|30000|Maximum wait between reconnect attempts| +|useExponentialBackOff|true|Grow delay on each retry up to maxReconnectDelay| +|maxReconnectAttempts|0|Max reconnect attempts (0 = forever)| +|randomize|true|Connect to broker URIs in random order| +|timeout|-1|How long a blocked send waits before failing (-1 = forever)| + +#### Connection Options + +| Option | Default | Description | +|---|---|---| +|connection.sendTimeout|0|Time to wait on sends for a response (0 = forever)| +|connection.useAsyncSend|false|Force async sends (may lose messages on crash)| +|connection.alwaysSyncSend|false|Force all sends to be synchronous| +|connection.useCompression|false|Compress message bodies with ZLib (Since v3.2.0)| +|connection.dispatchAsync|true|Broker dispatches messages asynchronously (Since v3.2.0)| + +#### Wire Format Options + +| Option | Default | Description | +|---|---|---| +|wireFormat|openwire|Wire format: `stomp` or `openwire`| +|wireFormat.tightEncodingEnabled|false|Optimize wire size over CPU| +|wireFormat.maxInactivityDuration|30000|Max inactivity before socket considered dead (ms)| + +### Destination URI Parameters + +##### Example Configuration + +``` +d = session->createTopic("com.foo?consumer.prefetchSize=2000&consumer.noLocal=true"); +``` + +#### General Options + +| Option | Default | Description | +|---|---|---| +|consumer.prefetchSize|1000|Number of messages to prefetch| +|consumer.noLocal|false|Suppress messages from this connection| +|consumer.dispatchAsync|false|Broker dispatches asynchronously to this consumer| +|consumer.selector|null|JMS Selector| +|consumer.exclusive|false|Exclusive consumer| diff --git a/hugo/content/components/cms/developers/building.md b/hugo/content/components/cms/developers/building.md new file mode 100644 index 0000000000..d317af65b9 --- /dev/null +++ b/hugo/content/components/cms/developers/building.md @@ -0,0 +1,43 @@ +--- +title: Building ActiveMQ-CPP +layout: cms-page +--- + +### Dependencies + +**libuuid** — Required on \*nix. Part of the `e2fsprogs` package. +- Fedora/RHEL: `e2fsprogs`, `e2fsprogs-devel` +- Debian/Ubuntu: `uuid`, `uuid-dev` + +**CppUnit** — Required to build and run tests. See [cppunit.sourceforge.net](http://cppunit.sourceforge.net/cppunit-wiki). + +**APR** — Required for ActiveMQ-CPP 2.2+. See [apr.apache.org](http://apr.apache.org). + +### Building on \*nix + +Required tools: `autoconf >= 2.59`, `automake >= 1.9.6`, `libtool >= 1.5.22`. + +```bash +./autogen.sh +./configure +make +``` + +For build options: `./configure --help` + +#### Running Tests + +```bash +make check +``` + +#### Integration Tests (requires a running broker) + +```bash +cd src/test-integration +./activemq-test-integration +``` + +### Building on Windows (MSVC) + +The project supports MSVC. Ensure APR and CppUnit are installed and their paths are referenced in the project settings. For MSVC < 2008, install the Platform SDK and set `INCLUDE` and `LIB` environment variables accordingly. diff --git a/hugo/content/components/cms/developers/creating-distributions.md b/hugo/content/components/cms/developers/creating-distributions.md new file mode 100644 index 0000000000..5e178ae9da --- /dev/null +++ b/hugo/content/components/cms/developers/creating-distributions.md @@ -0,0 +1,33 @@ +--- +title: Creating ActiveMQ-CPP Distributions +layout: cms-page +--- + +### Background + +Apache mirrors everything under `/www/www.apache.org/dist`. Release archives go under `activemq/activemq-cpp/source/`. Allow ~24 hours for mirrors to sync before announcing. + +Download links use the Apache CGI mirror script: + +``` +http://www.apache.org/dyn/closer.cgi/activemq/activemq-cpp/source/activemq-cpp-X.Y-src.zip +``` + +### Creating a Distribution (step-by-step) + +1. Create a pre-release download page with a disclaimer and temporary link. +2. Call a vote on the dev list (`[VOTE]` in subject). Wait 3 days; proceed with ≥3 +1s and no -1s. +3. Create source archives (`.zip`, `.tar.gz`). Remove `.svn` directories first: + ```bash + rm -rf `find . -type d -name .svn` + ``` +4. Sign the archives: + ```bash + gpg --armor --output foo.tar.gz.asc --detach-sig foo.tar.gz + gpg --armor --output foo.zip.asc --detach-sig foo.zip + ``` +5. Copy archives to `/www/www.apache.org/dist/activemq/activemq-cpp/source/` on the Apache server. +6. Wait 24 hours for mirrors to sync. +7. Update download page links to use the CGI mirror script path. +8. Generate Doxygen API docs and place under `/www/activemq.apache.org/cms/api_docs/`. +9. Announce on the `dev` and `users` mailing lists. diff --git a/hugo/content/components/cms/developers/source.md b/hugo/content/components/cms/developers/source.md new file mode 100644 index 0000000000..fa80d4dfb5 --- /dev/null +++ b/hugo/content/components/cms/developers/source.md @@ -0,0 +1,26 @@ +--- +title: ActiveMQ-CPP Source +layout: cms-page +--- + +The ActiveMQ-CPP client code is maintained in a Git repository. + +### Web Browsing + +``` +https://gitbox.apache.org/repos/asf?p=activemq-cpp.git +``` + +### Checking Out + +``` +git clone https://gitbox.apache.org/repos/asf/activemq-cpp.git +``` + +Only project developers can commit to the Git tree via this method. + +### Branches + +The `master` branch targets the next main release. Bug fixes for the previous major release use a dedicated branch. + +To build the code after checking out, see [Building](building). diff --git a/hugo/content/components/cms/documentation/index.md b/hugo/content/components/cms/documentation/index.md new file mode 100644 index 0000000000..d580fe5678 --- /dev/null +++ b/hugo/content/components/cms/documentation/index.md @@ -0,0 +1,35 @@ +--- +title: CMS Documentation +layout: cms-page +--- + +### Overview + +CMS (C++ Messaging Service) is a JMS-like API for C++ for interfacing with Message Brokers such as Apache ActiveMQ. ActiveMQ-CPP is a client only library — a message broker such as Apache ActiveMQ is still needed for your clients to communicate. + +ActiveMQ-CPP supports pluggable transports and wire formats, including OpenWire and STOMP over TCP and SSL, plus a Failover Transport for reliable client operation. It is released under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0.html). + +- [Configuring](../configuring) +- [Example](../example) + +### API Reference {#api} + +- [ActiveMQ-CPP 3.9.x](../api_docs/activemqcpp-3.9.0/html/) +- [ActiveMQ-CPP 3.6.x](../api_docs/activemqcpp-3.6.0/html/) +- [ActiveMQ-CPP 3.4.x](../api_docs/activemqcpp-3.4.0/html/) +- [ActiveMQ-CPP 3.3.x](../api_docs/activemqcpp-3.3.0/html/) + +### Connectivity + +- [STOMP](../stomp-support) +- [OpenWire](../openwire-support) + +### Tutorials + +- [Handling Advisory Messages](../tutorials/handling-advisory-messages) + +### Developers + +- [Source](../developers/source) +- [Building](../developers/building) +- [Creating Distributions](../developers/creating-distributions) diff --git a/hugo/content/components/cms/download/index.md b/hugo/content/components/cms/download/index.md new file mode 100644 index 0000000000..27ac63ce02 --- /dev/null +++ b/hugo/content/components/cms/download/index.md @@ -0,0 +1,60 @@ +--- +title: CMS Downloads +layout: cms-page +--- + +### Latest Release + +The current stable release is **ActiveMQ-CPP 3.9.5**. + +### All Releases + +- [ActiveMQ-CPP 3.9.5](https://archive.apache.org/dist/activemq/activemq-cpp/3.9.5/) +- [ActiveMQ-CPP 3.9.4](https://archive.apache.org/dist/activemq/activemq-cpp/3.9.4/) +- [ActiveMQ-CPP 3.9.3](https://archive.apache.org/dist/activemq/activemq-cpp/3.9.3/) +- [ActiveMQ-CPP 3.9.2](https://archive.apache.org/dist/activemq/activemq-cpp/3.9.2/) +- [ActiveMQ-CPP 3.9.1](https://archive.apache.org/dist/activemq/activemq-cpp/3.9.1/) +- [ActiveMQ-CPP 3.9.0](https://archive.apache.org/dist/activemq/activemq-cpp/3.9.0/) +- [ActiveMQ-CPP 3.8.4](https://archive.apache.org/dist/activemq/activemq-cpp/3.8.4/) +- [ActiveMQ-CPP 3.8.3](https://archive.apache.org/dist/activemq/activemq-cpp/3.8.3/) +- [ActiveMQ-CPP 3.8.2](https://archive.apache.org/dist/activemq/activemq-cpp/3.8.2/) +- [ActiveMQ-CPP 3.8.1](https://archive.apache.org/dist/activemq/activemq-cpp/3.8.1/) +- [ActiveMQ-CPP 3.8.0](https://archive.apache.org/dist/activemq/activemq-cpp/3.8.0/) +- [ActiveMQ-CPP 3.7.1](https://archive.apache.org/dist/activemq/activemq-cpp/3.7.1/) +- [ActiveMQ-CPP 3.7.0](https://archive.apache.org/dist/activemq/activemq-cpp/3.7.0/) +- [ActiveMQ-CPP 3.6.0](https://archive.apache.org/dist/activemq/activemq-cpp/3.6.0/) +- [ActiveMQ-CPP 3.5.0](https://archive.apache.org/dist/activemq/activemq-cpp/3.5.0/) +- [ActiveMQ-CPP 3.4.5](https://archive.apache.org/dist/activemq/activemq-cpp/3.4.5/) +- [ActiveMQ-CPP 3.4.4](https://archive.apache.org/dist/activemq/activemq-cpp/3.4.4/) +- [ActiveMQ-CPP 3.4.3](https://archive.apache.org/dist/activemq/activemq-cpp/3.4.3/) +- [ActiveMQ-CPP 3.4.2](https://archive.apache.org/dist/activemq/activemq-cpp/3.4.2/) +- [ActiveMQ-CPP 3.4.1](https://archive.apache.org/dist/activemq/activemq-cpp/3.4.1/) +- [ActiveMQ-CPP 3.4.0](https://archive.apache.org/dist/activemq/activemq-cpp/3.4.0/) +- [ActiveMQ-CPP 3.3.0](https://archive.apache.org/dist/activemq/activemq-cpp/3.3.0/) +- [ActiveMQ-CPP 3.2.5](https://archive.apache.org/dist/activemq/activemq-cpp/3.2.5/) +- [ActiveMQ-CPP 3.2.4](https://archive.apache.org/dist/activemq/activemq-cpp/3.2.4/) +- [ActiveMQ-CPP 3.2.3](https://archive.apache.org/dist/activemq/activemq-cpp/3.2.3/) +- [ActiveMQ-CPP 3.2.2](https://archive.apache.org/dist/activemq/activemq-cpp/3.2.2/) +- [ActiveMQ-CPP 3.2.1](https://archive.apache.org/dist/activemq/activemq-cpp/3.2.1/) +- [ActiveMQ-CPP 3.2.0](https://archive.apache.org/dist/activemq/activemq-cpp/3.2.0/) +- [ActiveMQ-CPP 3.1.3](https://archive.apache.org/dist/activemq/activemq-cpp/3.1.3/) +- [ActiveMQ-CPP 3.1.2](https://archive.apache.org/dist/activemq/activemq-cpp/3.1.2/) +- [ActiveMQ-CPP 3.1.1](https://archive.apache.org/dist/activemq/activemq-cpp/3.1.1/) +- [ActiveMQ-CPP 3.1.0](https://archive.apache.org/dist/activemq/activemq-cpp/3.1.0/) +- [ActiveMQ-CPP 3.0.1](https://archive.apache.org/dist/activemq/activemq-cpp/3.0.1/) +- [ActiveMQ-CPP 3.0](https://archive.apache.org/dist/activemq/activemq-cpp/3.0/) +- [ActiveMQ-CPP 2.2.6](https://archive.apache.org/dist/activemq/activemq-cpp/2.2.6/) +- [ActiveMQ-CPP 2.2.5](https://archive.apache.org/dist/activemq/activemq-cpp/2.2.5/) +- [ActiveMQ-CPP 2.2.4](https://archive.apache.org/dist/activemq/activemq-cpp/2.2.4/) +- [ActiveMQ-CPP 2.2.3](https://archive.apache.org/dist/activemq/activemq-cpp/2.2.3/) +- [ActiveMQ-CPP 2.2.2](https://archive.apache.org/dist/activemq/activemq-cpp/2.2.2/) +- [ActiveMQ-CPP 2.2.1](https://archive.apache.org/dist/activemq/activemq-cpp/2.2.1/) +- [ActiveMQ-CPP 2.2](https://archive.apache.org/dist/activemq/activemq-cpp/2.2/) +- [ActiveMQ-CPP 2.1.3](https://archive.apache.org/dist/activemq/activemq-cpp/2.1.3/) +- [ActiveMQ-CPP 2.1.2](https://archive.apache.org/dist/activemq/activemq-cpp/2.1.2/) +- [ActiveMQ-CPP 2.1.1](https://archive.apache.org/dist/activemq/activemq-cpp/2.1.1/) +- [ActiveMQ-CPP 2.1](https://archive.apache.org/dist/activemq/activemq-cpp/2.1/) +- [ActiveMQ-CPP 2.0.1](https://archive.apache.org/dist/activemq/activemq-cpp/2.0.1/) +- [ActiveMQ-CPP 2.0](https://archive.apache.org/dist/activemq/activemq-cpp/2.0/) +- [ActiveMQ-CPP 1.1](https://archive.apache.org/dist/activemq/activemq-cpp/1.1/) +- [ActiveMQ-CPP 1.0](https://archive.apache.org/dist/activemq/activemq-cpp/1.0/) diff --git a/hugo/content/components/cms/example.md b/hugo/content/components/cms/example.md new file mode 100644 index 0000000000..0e1d13fb3c --- /dev/null +++ b/hugo/content/components/cms/example.md @@ -0,0 +1,103 @@ +--- +title: ActiveMQ-CPP Example +layout: cms-page +--- + +The example below creates two classes — `HelloWorldConsumer` and `HelloWorldProducer` — each running in its own thread. The Producer sends `TextMessage` objects to the broker; the Consumer receives them asynchronously. + +```cpp +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace activemq::core; +using namespace decaf::util::concurrent; +using namespace decaf::lang; +using namespace cms; +using namespace std; + +class HelloWorldProducer : public Runnable { + string brokerURI; + int numMessages; + bool useTopic; +public: + HelloWorldProducer(const string& uri, int n, bool topic = false) + : brokerURI(uri), numMessages(n), useTopic(topic) {} + + virtual void run() { + auto_ptr cf( + ConnectionFactory::createCMSConnectionFactory(brokerURI)); + auto_ptr connection(cf->createConnection()); + connection->start(); + auto_ptr session(connection->createSession(Session::AUTO_ACKNOWLEDGE)); + auto_ptr dest(useTopic + ? session->createTopic("TEST.FOO") + : session->createQueue("TEST.FOO")); + auto_ptr producer(session->createProducer(dest.get())); + producer->setDeliveryMode(DeliveryMode::NON_PERSISTENT); + for (int i = 0; i < numMessages; ++i) { + auto_ptr msg(session->createTextMessage("Hello world!")); + producer->send(msg.get()); + } + connection->close(); + } +}; + +class HelloWorldConsumer : public MessageListener, public Runnable { + string brokerURI; + int numMessages; + bool useTopic; + CountDownLatch latch; + CountDownLatch doneLatch; +public: + HelloWorldConsumer(const string& uri, int n, bool topic = false) + : brokerURI(uri), numMessages(n), useTopic(topic), latch(1), doneLatch(n) {} + + void waitUntilReady() { latch.await(); } + + virtual void run() { + auto_ptr cf( + ConnectionFactory::createCMSConnectionFactory(brokerURI)); + auto_ptr connection(cf->createConnection()); + connection->start(); + auto_ptr session(connection->createSession(Session::AUTO_ACKNOWLEDGE)); + auto_ptr dest(useTopic + ? session->createTopic("TEST.FOO") + : session->createQueue("TEST.FOO")); + auto_ptr consumer(session->createConsumer(dest.get())); + consumer->setMessageListener(this); + latch.countDown(); + doneLatch.await(30000); + connection->close(); + } + + virtual void onMessage(const Message* message) { + const TextMessage* tm = dynamic_cast(message); + if (tm) cout << "Received: " << tm->getText() << endl; + doneLatch.countDown(); + } +}; + +int main() { + activemq::library::ActiveMQCPP::initializeLibrary(); + string brokerURI = "failover:(tcp://localhost:61616)"; + HelloWorldProducer producer(brokerURI, 2000, true); + HelloWorldConsumer consumer(brokerURI, 2000, true); + Thread consumerThread(&consumer); + consumerThread.start(); + consumer.waitUntilReady(); + Thread producerThread(&producer); + producerThread.start(); + producerThread.join(); + consumerThread.join(); + activemq::library::ActiveMQCPP::shutdownLibrary(); +} +``` diff --git a/hugo/content/components/cms/openwire-support.md b/hugo/content/components/cms/openwire-support.md new file mode 100644 index 0000000000..971c6aa139 --- /dev/null +++ b/hugo/content/components/cms/openwire-support.md @@ -0,0 +1,8 @@ +--- +title: OpenWire Support +layout: cms-page +--- + +[OpenWire](http://activemq.apache.org/openwire.html) is the native protocol used by the ActiveMQ 5.x broker. As of version 2.0, ActiveMQ-CPP supports the OpenWire protocol, with one exception: + +- **ObjectMessage** — C++ cannot reconstruct Java objects, so `ObjectMessage` payloads are received but cannot be extracted. diff --git a/hugo/content/components/cms/stomp-support.md b/hugo/content/components/cms/stomp-support.md new file mode 100644 index 0000000000..9545f7cec9 --- /dev/null +++ b/hugo/content/components/cms/stomp-support.md @@ -0,0 +1,22 @@ +--- +title: STOMP Support +layout: cms-page +--- + +[STOMP](https://stomp.github.io/) is a simple text-based protocol supported by the ActiveMQ broker that allows communication from a variety of clients (C++, Java, .NET, Ruby, Python, etc). + +### Message Properties in STOMP CMS + +Since STOMP is strictly text-based, it does not support typed message properties. A property sent as an integer may be read as a string, integer, short, long, etc. The underlying wire value is always a string. + +### Temporary Topics and Queues + +The STOMP protocol does not support temporary topics or queues. Calling `createTemporaryTopic` or `createTemporaryQueue` on a `cms::Session` throws a `NotSupportedException`. Use standard Topics and Queues for request/reply semantics instead. + +### Selectors with STOMP + +STOMP allows only one session per connection. ActiveMQ-CPP creates virtual sessions, but only the first session's selector has any effect — subsequent sessions ignore any selector passed at creation time. + +### STOMP and Failover + +STOMP v1.0 lacks the protocol features needed for reliable Failover. Until STOMP v1.1 support is added, combining the STOMP transport with the Failover transport is not recommended. diff --git a/hugo/content/components/cms/tutorials/handling-advisory-messages.md b/hugo/content/components/cms/tutorials/handling-advisory-messages.md new file mode 100644 index 0000000000..34b27e1d4d --- /dev/null +++ b/hugo/content/components/cms/tutorials/handling-advisory-messages.md @@ -0,0 +1,73 @@ +--- +title: Handling Advisory Messages +layout: cms-page +--- + +ActiveMQ supports advisory messages that let you watch the system using regular CMS messages: + +- See consumers, producers and connections starting and stopping +- See temporary destinations being created and destroyed +- Get notified when messages expire on topics and queues +- Observe brokers sending messages to destinations with no consumers + +### Subscribing to Advisory Topics + +Subscribe to an advisory topic the same way as any other destination. Use the correct topic name for the advisory you want: + +| Advisory Topic | Description | +|---|---| +|ActiveMQ.Advisory.Connection|Connection start & stop| +|ActiveMQ.Advisory.Producer.Queue|Producer start & stop on a Queue| +|ActiveMQ.Advisory.Producer.Topic|Producer start & stop on a Topic| +|ActiveMQ.Advisory.Consumer.Queue|Consumer start & stop on a Queue| +|ActiveMQ.Advisory.Consumer.Topic|Consumer start & stop on a Topic| + +For example, to watch for producers on `TOPIC.FOO`: + +```cpp +auto_ptr advisories( + session->createTopic("ActiveMQ.Advisory.Producer.Topic.TOPIC.FOO")); +auto_ptr consumer(session->createConsumer(advisories.get())); +consumer->setMessageListener(this); +``` + +### Processing Advisory Messages + +All advisory messages have CMS type `"Advisory"`. Check `getCMSType()` and then inspect message properties: + +```cpp +void onMessage(const cms::Message* message) { + if (message->getCMSType() == "Advisory") { + if (message->propertyExists("consumerCount")) { + string count = message->getStringProperty("consumerCount"); + cout << "Consumers: " << count << endl; + } + } +} +``` + +### Composite Advisory Subscriptions + +Subscribe to multiple advisory topics in one consumer using a comma-separated name: + +```cpp +auto_ptr advisories(session->createTopic( + "ActiveMQ.Advisory.TempTopic,ActiveMQ.Advisory.TempQueue")); +auto_ptr consumer(session->createConsumer(advisories.get())); +consumer->setMessageListener(this); +``` + +### Accessing Embedded Command Objects + +Some advisories carry an embedded command object accessible via `ActiveMQMessage::getDataStructure()`: + +```cpp +const ActiveMQMessage* amqMsg = dynamic_cast(message); +if (amqMsg && amqMsg->getDataStructure() != NULL) { + Pointer info = + amqMsg->getDataStructure().dynamicCast(); + if (info->getOperationType() == ActiveMQConstants::DESTINATION_ADD_OPERATION) { + cout << "Created: " << info->getDestination()->getPhysicalName() << endl; + } +} +``` diff --git a/hugo/content/components/nms/_index.md b/hugo/content/components/nms/_index.md new file mode 100644 index 0000000000..bc3220d7aa --- /dev/null +++ b/hugo/content/components/nms/_index.md @@ -0,0 +1,5 @@ +--- +title: NMS Clients +subtitle: .NET Messaging API +layout: nms +--- diff --git a/hugo/content/components/nms/documentation.md b/hugo/content/components/nms/documentation.md new file mode 100644 index 0000000000..4c24c9d49c --- /dev/null +++ b/hugo/content/components/nms/documentation.md @@ -0,0 +1,37 @@ +--- +title: NMS Documentation +layout: nms-download +--- + +### API Overview + +The [NMS API](../nms-api) (_.Net Message Service API_) provides a standard .NET interface to Messaging Systems. There are multiple implementations for different [providers](#providers). The NMS API allows you to build .NET applications in C#, VB, or any other .NET language, using a single API to connect to multiple different providers using a JMS style API. + +NMS API currently supports all of the features of JMS in a simple pure C# API and implementation apart from XA. Current features include: + +* Creating & disposing of connections, sessions, producers, consumers +* Sending of messages to topics, queues with durable or non durable along with temporary destination support +* Synchronous consuming (blocking receive, receive with no wait or receive with a timeout) +* Asynchronous consuming (adding a MessageListener to be dispatched in the thread pool) +* Message header support along with custom properties +* Text, Bytes, Stream and Map message support +* Support for transactions (sending and acknowledging multiple messages in an atomic transaction) +* Redelivery of messages in rollbacks up to some configured maximum redelivery count +* Optional Queue browser interface for providers that can support it +* Optional .NET Distributed Transaction Support for providers that can support that + +--- + +### Providers {#providers} + +An NMS Provider is a .NET Assembly that provides an implementation of the NMS API for connectivity with a particular Messaging Service or protocol. Currently, the following providers are available: + +* [AMQP](../providers/amqp) — AMQP 1.0 protocol, compatible with ActiveMQ 5.x, ActiveMQ Artemis and any other AMQP 1.0 compliant broker. +* [ActiveMQ (OpenWire)](../providers/activemq) — communicates with ActiveMQ 5.x using its native wire protocol with many advanced features beyond the standard NMS API. + +--- + +### Examples {#examples} + +* [NMS Simple Asynchronous Consumer Example](../examples/nms-simple-asynchronous-consumer-example) +* [NMS Simple Synchronous Consumer Example](../examples/nms-simple-synchronous-consumer-example) diff --git a/hugo/content/components/nms/download.md b/hugo/content/components/nms/download.md new file mode 100644 index 0000000000..e02880c2e3 --- /dev/null +++ b/hugo/content/components/nms/download.md @@ -0,0 +1,9 @@ +--- +title: NMS Downloads +layout: nms-download +--- + +- [NMS API Downloads](../nms-api-downloads) +- Providers + - [AMQP](../providers/amqp/downloads) + - [ActiveMQ (OpenWire)](../providers/activemq/downloads) diff --git a/hugo/content/components/nms/nms-api-downloads.md b/hugo/content/components/nms/nms-api-downloads.md new file mode 100644 index 0000000000..9832f3a3f2 --- /dev/null +++ b/hugo/content/components/nms/nms-api-downloads.md @@ -0,0 +1,32 @@ +--- +title: NMS API Downloads +layout: nms-download +--- + +This is the current NMS API release. It is important to verify the integrity of the files you download. + +#### NMS API 2.2.0 (Jul 5th, 2025) + +Adds configurable acknowledgment handling for expired messages via IRedeliveryPolicy. + +| | Package | SHA512 | Signature | +|---|---|---|---| +|Source|[Apache.NMS-2.2.0-src.zip](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-api/2.2.0/Apache.NMS-2.2.0-src.zip&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-api/2.2.0/Apache.NMS-2.2.0-src.zip.sha512)|[ASC](https://downloads.apache.org/activemq/apache-nms-api/2.2.0/Apache.NMS-2.2.0-src.zip.asc)| +|Binary|[Apache.NMS-2.2.0-bin.zip](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-api/2.2.0/Apache.NMS-2.2.0-bin.zip&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-api/2.2.0/Apache.NMS-2.2.0-bin.zip.sha512)|[ASC](https://downloads.apache.org/activemq/apache-nms-api/2.2.0/Apache.NMS-2.2.0-bin.zip.asc)| +|NuGet|[Apache.NMS.2.2.0.nupkg](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-api/2.2.0/Apache.NMS.2.2.0.nupkg&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-api/2.2.0/Apache.NMS.2.2.0.nupkg.sha512)|[ASC](https://downloads.apache.org/activemq/apache-nms-api/2.2.0/Apache.NMS.2.2.0.nupkg.asc)| +|Docs|[Apache.NMS-2.2.0-docs.zip](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-api/2.2.0/Apache.NMS-2.2.0-docs.zip&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-api/2.2.0/Apache.NMS-2.2.0-docs.zip.sha512)|[ASC](https://downloads.apache.org/activemq/apache-nms-api/2.2.0/Apache.NMS-2.2.0-docs.zip.asc)| + +[Release Notes](https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12311201&version=12351670) + +--- + +#### Verify the Integrity of Downloads + +Verify downloaded files using the PGP signature or SHA512 checksums. See the [Apache verification guide](https://www.apache.org/info/verification.html). + +Download the [KEYS](https://downloads.apache.org/activemq/KEYS) file and the `.asc` signature for your download, then run: + +``` +gpg --import KEYS +gpg --verify Apache.NMS-*.asc +``` diff --git a/hugo/content/components/nms/providers/activemq/_index.md b/hugo/content/components/nms/providers/activemq/_index.md new file mode 100644 index 0000000000..394aaa67a0 --- /dev/null +++ b/hugo/content/components/nms/providers/activemq/_index.md @@ -0,0 +1,10 @@ +--- +title: Apache.NMS.ActiveMQ +layout: nms-download +--- + +The ActiveMQ NMS client is a .NET client that communicates with the ActiveMQ broker using its native OpenWire protocol. This client supports advanced features such as Failover, Discovery, SSL, and Message Compression. + +- [Advanced Features](advanced-features) +- [Downloads](downloads) +- [URI Configuration](uri-configuration) diff --git a/hugo/content/components/nms/providers/activemq/downloads.md b/hugo/content/components/nms/providers/activemq/downloads.md new file mode 100644 index 0000000000..2279c2d683 --- /dev/null +++ b/hugo/content/components/nms/providers/activemq/downloads.md @@ -0,0 +1,34 @@ +--- +title: Apache.NMS.ActiveMQ Downloads +layout: nms-download +--- + +| Release | Date | NMS API | +|---|---|---| +|[Apache.NMS.ActiveMQ v2.2.0](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-openwire/2.2.0/Apache.NMS.ActiveMQ-2.2.0-bin.zip&action=download)|11/27/2025|v2.2.0| +|[Apache.NMS.ActiveMQ v2.1.1](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-openwire/2.1.1/Apache.NMS.ActiveMQ-2.1.1-bin.zip&action=download)|02/16/2025|v2.1.1| +|[Apache.NMS.ActiveMQ v2.1.0](https://archive.apache.org/dist/activemq/apache-nms-openwire/2.1.0/Apache.NMS.ActiveMQ-2.1.0-bin.zip)|03/12/2023|v2.1.0| +|[Apache.NMS.ActiveMQ v2.0.1](https://archive.apache.org/dist/activemq/apache-nms-openwire/2.0.1/Apache.NMS.ActiveMQ-2.0.1-bin.zip)|02/14/2023|v2.0.1| +|[Apache.NMS.ActiveMQ v2.0.0](https://archive.apache.org/dist/activemq/apache-nms-openwire/2.0.0/Apache.NMS.ActiveMQ-2.0.0-bin.zip)|07/07/2022|v2.0.0| +|[Apache.NMS.ActiveMQ v1.8.0](https://archive.apache.org/dist/activemq/apache-nms-openwire/1.8.0/Apache.NMS.ActiveMQ-1.8.0-bin.zip)|01/03/2021|v1.8.0| +|Apache.NMS.ActiveMQ v1.7.2|04/07/2016|v1.7.2| +|Apache.NMS.ActiveMQ v1.7.1|10/05/2015|v1.7.1| +|Apache.NMS.ActiveMQ v1.7.0|01/16/2015|v1.7.0| +|Apache.NMS.ActiveMQ v1.6.5|02/05/2015|v1.6.0| +|Apache.NMS.ActiveMQ v1.6.4|09/14/2014|v1.6.0| +|Apache.NMS.ActiveMQ v1.6.3|07/21/2014|v1.6.0| +|Apache.NMS.ActiveMQ v1.6.2|12/23/2013|v1.6.0| +|Apache.NMS.ActiveMQ v1.6.1|10/19/2013|v1.6.0| +|Apache.NMS.ActiveMQ v1.6.0|06/06/2013|v1.6.0| +|Apache.NMS.ActiveMQ v1.5.6|07/12/2012|v1.5.1| +|Apache.NMS.ActiveMQ v1.5.5|05/03/2012|v1.5.0| +|Apache.NMS.ActiveMQ v1.5.4|04/13/2012|v1.5.0| +|Apache.NMS.ActiveMQ v1.5.3|01/27/2012|v1.5.0| +|Apache.NMS.ActiveMQ v1.5.2|11/18/2011|v1.5.0| +|Apache.NMS.ActiveMQ v1.5.1|06/04/2011|v1.5.0| +|Apache.NMS.ActiveMQ v1.5.0|02/17/2011|v1.5.0| +|Apache.NMS.ActiveMQ v1.4.1|10/04/2010|v1.4.0| +|Apache.NMS.ActiveMQ v1.4.0|09/17/2010|v1.4.0| +|Apache.NMS.ActiveMQ v1.3.0|05/21/2010|v1.3.0| +|Apache.NMS.ActiveMQ v1.2.0|02/12/2010|v1.2.0| +|Apache.NMS ActiveMQ v1.1.0|07/12/2009|v1.1.0| diff --git a/hugo/content/components/nms/providers/amqp/_index.md b/hugo/content/components/nms/providers/amqp/_index.md new file mode 100644 index 0000000000..513fbe244f --- /dev/null +++ b/hugo/content/components/nms/providers/amqp/_index.md @@ -0,0 +1,30 @@ +--- +title: Apache.NMS.AMQP +layout: nms-download +--- + +### Overview + +The goal of this project is to combine the [.NET Message Service API](../../) (NMS) with the [Advanced Message Queuing Protocol (AMQP)](https://www.amqp.org/) 1.0 standard wireline protocol. + +The NMS API gives the flexibility to write .NET applications in C#, VB or any other .NET language, all while using a single API to connect to any number of messaging providers. AMQP is an open and standardized internet protocol for reliably passing messages between applications or organizations. + +- **More Choice:** As more message brokers and services implement the AMQP 1.0 standard wireline, .NET developers will have more options for messaging technology. +- **No Migration Risk:** Since AMQP 1.0 is a wireline standard, you won't run into problems when switching between implementations. +- **Innovation:** Competition forces vendors to innovate and differentiate. + +### Download + +See the [downloads](downloads) page. + +### Configuration + +See the [URI configuration](uri-configuration) page. + +### Contributing + +Grab the source from GitHub: [activemq-nms-amqp](https://github.com/apache/activemq-nms-amqp) + +#### Architecture + +Apache-NMS-AMQP bridges NMS concepts to AMQP protocol concepts as described in [amqp-bindmap-jms-v1.0-wd09.pdf](https://www.oasis-open.org/committees/download.php/60574/amqp-bindmap-jms-v1.0-wd09.pdf). Top-level classes implementing the NMS interface (_Connection, Session, MessageProducer_, etc.) create and manage the [AmqpNetLite](https://github.com/Azure/amqpnetlite) equivalent objects. diff --git a/hugo/content/components/nms/providers/amqp/downloads.md b/hugo/content/components/nms/providers/amqp/downloads.md new file mode 100644 index 0000000000..9de6801b82 --- /dev/null +++ b/hugo/content/components/nms/providers/amqp/downloads.md @@ -0,0 +1,29 @@ +--- +title: Apache.NMS.AMQP Downloads +layout: nms-download +--- + +This is the current NMS.AMQP release. It is important to verify the integrity of the files you download. + +#### NMS AMQP 2.4.0 (Aug 24th, 2025) + +[Release Notes](https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12311201&version=12356027) | [Release Page](../../../../../news/nms-amqp-02-04-00-release/) + +| | Package | SHA512 | Signature | +|---|---|---|---| +|Source|[Apache.NMS.AMQP-2.4.0-src.zip](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-amqp/2.4.0/Apache.NMS.AMQP-2.4.0-src.zip&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-amqp/2.4.0/Apache.NMS.AMQP-2.4.0-src.zip.sha512)|[ASC](https://downloads.apache.org/activemq/apache-nms-amqp/2.4.0/Apache.NMS.AMQP-2.4.0-src.zip.asc)| +|Binary|[Apache.NMS.AMQP-2.4.0-bin.zip](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-amqp/2.4.0/Apache.NMS.AMQP-2.4.0-bin.zip&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-amqp/2.4.0/Apache.NMS.AMQP-2.4.0-bin.zip.sha512)|[ASC](https://downloads.apache.org/activemq/apache-nms-amqp/2.4.0/Apache.NMS.AMQP-2.4.0-bin.zip.asc)| +|NuGet|[Apache.NMS.AMQP.2.4.0.nupkg](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-amqp/2.4.0/Apache.NMS.AMQP.2.4.0.nupkg&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-amqp/2.4.0/Apache.NMS.AMQP.2.4.0.nupkg.sha512)|[ASC](https://downloads.apache.org/activemq/apache-nms-amqp/2.4.0/Apache.NMS.AMQP.2.4.0.nupkg.asc)| + +--- + +#### Verify the Integrity of Downloads + +Verify downloaded files using the PGP signature or SHA512 checksums. See the [Apache verification guide](https://www.apache.org/info/verification.html). + +Download the [KEYS](https://downloads.apache.org/activemq/KEYS) file and the `.asc` signature for your download, then run: + +``` +gpg --import KEYS +gpg --verify Apache.NMS.AMQP-*.asc +``` diff --git a/hugo/content/download/index.md b/hugo/content/download/index.md new file mode 100644 index 0000000000..dda90097f7 --- /dev/null +++ b/hugo/content/download/index.md @@ -0,0 +1,91 @@ +--- +title: "Download ActiveMQ" +--- + +These are the current ActiveMQ releases. For prior releases, please see the [past releases](../components/classic/documentation/download-archives) page. + +It is important to [verify the integrity](#verify) of the files you download. + +#### Summary Table of ActiveMQ Series Status + + + + + + + + + + + + + + + + + + + +
    SeriesStatusLatest Patch VersionDate of Release
    6.2.xStable - Supported6.2.1Feb 18th, 2026
    6.1.xDeprecated6.1.8Oct 22nd, 2025
    6.0.xDeprecated6.0.1Dec 3rd, 2023
    5.19.xStable - Supported5.19.2Feb 13th, 2026
    5.18.xDeprecated5.18.7Mar 19th, 2025
    5.17.xDeprecated5.17.7Mar 20th, 2025
    5.16.xDeprecated5.16.8Mar 22nd, 2025
    5.15.xDeprecated5.15.16Oct 26th, 2023
    5.14.xDeprecated5.14.5Apr 25th, 2017
    5.13.xDeprecated5.13.5Dec 16th, 2016
    5.12.xDeprecated5.12.3Feb 3rd, 2016
    5.11.xDeprecated5.11.4Feb 3rd, 2016
    + +##### Status Descriptions + +**In Dev**: Actively in development. May not yet be fully stable for production. + +**Stable - Supported**: Actively supported and recommended for production use. Receives regular updates, security patches, and bug fixes. + +**Deprecated**: End-of-life and no longer maintained. Users are encouraged to upgrade to a stable version. + +#### Schedule & Status + +
    + +| Series | Broker JMS API | Client JMS API | Java | Spring | Logging | Web | Status | Last | Next | ETA | +|--------|---------------|----------------|------|--------|---------|-----|--------|------|------|-----| +| 6.2.x | Jakarta JMS 2/3.1 (partial) | Jakarta JMS 2/3.1 | [17,23) | 6.2.16 | Log4j 2.25.3/Slf4j 2.0.17 | Jetty 11.0.26 | **Stable** | 6.2.1 | 6.2.2 | Apr 26 | +| 6.1.x | Jakarta JMS 2/3.1 (partial) | Jakarta JMS 2/3.1 | [17,23) | 6.1.21 | Log4j 2.25.2/Slf4j 2.0.17 | Jetty 11.0.26 | _Deprecated_ | 6.1.8 | | | +| 6.0.x | Jakarta JMS 2/3.1 (partial) | Jakarta JMS 2/3.1 | [17,23) | 6.0.17 | Log4j 2.22.0/Slf4j 2.0.9 | Jetty 11.0.18 | _Deprecated_ | 6.0.1 | | | +| 5.19.x | Javax JMS 1.1 | Javax JMS 1.1/Jakarta JMS 2 | [11,23) | 5.3.39 | Log4j 2.25.3/Slf4j 2.0.17 | Jetty 9.4.58 | **Stable** | 5.19.2 | | | +| 5.18.x | Javax JMS 1.1 | Javax JMS 1.1/Jakarta JMS 2 | [11,23) | 5.3.39 | Log4j 2.24.1/Slf4j 2.0.13 | Jetty 9.4.57 | _Deprecated_ | 5.18.7 | | | +| 5.17.x | Javax JMS 1.1 | Javax JMS 1.1 | [11,23) | 5.3.33 | Log4j 2.23.1/Slf4j 1.7.36 | Jetty 9.4.54 | _Deprecated_ | 5.17.7 | | | +| 5.16.x | Javax JMS 1.1 | Javax JMS 1.1 | 1.8 | 4.3.30 | Reload4j 1.2.24/Slf4j 1.7.36 | Jetty 9.4.53 | _Deprecated_ | 5.16.8 | | | +| 5.15.x | Javax JMS 1.1 | Javax JMS 1.1 | 1.8 | 4.3.30 | Log4j 1.2.17/Slf4j 1.7.32 | Jetty 9.4.39 | _Deprecated_ | 5.15.16 | | | +| 5.14.x | Javax JMS 1.1 | Javax JMS 1.1 | 1.7 | 4.1.9 | Log4j 1.2.17/Slf4j 1.7.13 | Jetty 9.2.13 | _Deprecated_ | 5.14.5 | | | +| 5.13.x | Javax JMS 1.1 | Javax JMS 1.1 | 1.7 | 4.1.9 | Log4j 1.2.17/Slf4j 1.7.13 | Jetty 9.2.13 | _Deprecated_ | 5.13.5 | | | +| 5.12.x | Javax JMS 1.1 | Javax JMS 1.1 | 1.7 | 3.2.16 | Log4j 1.2.17/Slf4j 1.7.10 | Jetty 9.2.6 | _Deprecated_ | 5.12.3 | | | +| 5.11.x | Javax JMS 1.1 | Javax JMS 1.1 | 1.7 | 3.2.16 | Log4j 1.2.17/Slf4j 1.7.10 | Jetty 9.2.6 | _Deprecated_ | 5.11.4 | | | + +
    + +#### ActiveMQ Classic 6.2.1 (Feb 18th, 2026) + +[Release Notes](https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12311210&version=12356338) | [Documentation](../components/classic/documentation) | Java: **17+** + +| Platform | Package | SHA512 | Signature | +|----------|---------|--------|-----------| +| Windows | [apache-activemq-6.2.1-bin.zip](https://www.apache.org/dyn/closer.cgi?filename=/activemq/6.2.1/apache-activemq-6.2.1-bin.zip&action=download) | [SHA512](https://downloads.apache.org/activemq/6.2.1/apache-activemq-6.2.1-bin.zip.sha512) | [ASC](https://downloads.apache.org/activemq/6.2.1/apache-activemq-6.2.1-bin.zip.asc) | +| Unix/Linux | [apache-activemq-6.2.1-bin.tar.gz](https://www.apache.org/dyn/closer.cgi?filename=/activemq/6.2.1/apache-activemq-6.2.1-bin.tar.gz&action=download) | [SHA512](https://downloads.apache.org/activemq/6.2.1/apache-activemq-6.2.1-bin.tar.gz.sha512) | [ASC](https://downloads.apache.org/activemq/6.2.1/apache-activemq-6.2.1-bin.tar.gz.asc) | +| Source | [activemq-parent-6.2.1-source-release.zip](https://www.apache.org/dyn/closer.cgi?filename=/activemq/6.2.1/activemq-parent-6.2.1-source-release.zip&action=download) | [SHA512](https://downloads.apache.org/activemq/6.2.1/activemq-parent-6.2.1-source-release.zip.sha512) | [ASC](https://downloads.apache.org/activemq/6.2.1/activemq-parent-6.2.1-source-release.zip.asc) | + +#### ActiveMQ Classic 5.19.2 (Feb 13th, 2026) + +[Release Notes](https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12311210&version=12355593) | [Documentation](../components/classic/documentation) | Java: **11+** + +| Platform | Package | SHA512 | Signature | +|----------|---------|--------|-----------| +| Windows | [apache-activemq-5.19.2-bin.zip](https://www.apache.org/dyn/closer.cgi?filename=/activemq/5.19.2/apache-activemq-5.19.2-bin.zip&action=download) | [SHA512](https://downloads.apache.org/activemq/5.19.2/apache-activemq-5.19.2-bin.zip.sha512) | [ASC](https://downloads.apache.org/activemq/5.19.2/apache-activemq-5.19.2-bin.zip.asc) | +| Unix/Linux | [apache-activemq-5.19.2-bin.tar.gz](https://www.apache.org/dyn/closer.cgi?filename=/activemq/5.19.2/apache-activemq-5.19.2-bin.tar.gz&action=download) | [SHA512](https://downloads.apache.org/activemq/5.19.2/apache-activemq-5.19.2-bin.tar.gz.sha512) | [ASC](https://downloads.apache.org/activemq/5.19.2/apache-activemq-5.19.2-bin.tar.gz.asc) | +| Source | [activemq-parent-5.19.2-source-release.zip](https://www.apache.org/dyn/closer.cgi?filename=/activemq/5.19.2/activemq-parent-5.19.2-source-release.zip&action=download) | [SHA512](https://downloads.apache.org/activemq/5.19.2/activemq-parent-5.19.2-source-release.zip.sha512) | [ASC](https://downloads.apache.org/activemq/5.19.2/activemq-parent-5.19.2-source-release.zip.asc) | + +--- + +#### Verify the Integrity of Downloads {#verify} + +Verify downloaded files using the PGP signature or SHA512 checksums. See the [Apache verification guide](https://www.apache.org/info/verification.html). + +Download the [KEYS](https://downloads.apache.org/activemq/KEYS) file and the `.asc` signature for your download, then run: + +``` +gpg --import KEYS +gpg --verify apache-activemq-*.asc +``` diff --git a/hugo/content/news/_index.md b/hugo/content/news/_index.md new file mode 100644 index 0000000000..1fdbe0b24f --- /dev/null +++ b/hugo/content/news/_index.md @@ -0,0 +1,3 @@ +--- +title: "News" +--- diff --git a/hugo/content/news/apachenmsactivemq-v180.md b/hugo/content/news/apachenmsactivemq-v180.md new file mode 100644 index 0000000000..ee58fca636 --- /dev/null +++ b/hugo/content/news/apachenmsactivemq-v180.md @@ -0,0 +1,25 @@ +--- +title: "Apache.NMS.ActiveMQ v1.8.0" +date: 2021-03-01 +--- + +New and Noteworthy +------------------ + +This is the first provider implementation which adds .NET Standard 2.0 support, as well provides nuget packages. + +API Documentation +----------------- + +Refer to the API for this release [here](../../../nms-api) + +Download Here +------------- + +Apache.NMS.ActiveMQ Source code|[Apache.NMS.ActiveMQ-1.8.0-src.zip ](https://archive.apache.org/dist/activemq/apache-nms-activemq/1.8.0/Apache.NMS.ActiveMQ-1.8.0-src.zip)|[SHA512](https://archive.apache.org/dist/activemq/apache-nms-activemq/1.8.0/Apache.NMS.ActiveMQ-1.8.0-src.zip.sha512)|[PGP Signature](https://archive.apache.org/dist/activemq/apache-nms-activemq/1.8.0/Apache.NMS.ActiveMQ-1.8.0-src.zip.asc) +Apache.NMS.ActiveMQ Binary Assemblies|[Apache.NMS.ActiveMQ-1.8.0-bin.zip](https://archive.apache.org/dist/activemq/apache-nms-activemq/1.8.0/Apache.NMS.ActiveMQ-1.8.0-bin.zip)|[SHA512](https://archive.apache.org/dist/activemq/apache-nms-activemq/1.8.0/Apache.NMS.ActiveMQ-1.8.0-bin.zip.sha512)|[PGP Signature](https://archive.apache.org/dist/activemq/apache-nms-activemq/1.8.0/Apache.NMS.ActiveMQ-1.8.0-bin.zip.asc) + +Changelog +--------- + +- AMQNET-565: Dotnet core port diff --git a/hugo/content/news/apachenmsactivemq-v200.md b/hugo/content/news/apachenmsactivemq-v200.md new file mode 100644 index 0000000000..f3233116c7 --- /dev/null +++ b/hugo/content/news/apachenmsactivemq-v200.md @@ -0,0 +1,18 @@ +--- +title: "Apache.NMS.ActiveMQ 2.0.0 Release" +date: 2022-07-07 +description: "NMS 2.0 implementation and bug fixes." +--- + +Apache NMS.ActiveMQ was released on . This release adds an NMS 2.0 implementation as well as some bug fixes. + +Download Here +------------- + +Apache.NMS.ActiveMQ Source code|[Apache.NMS.ActiveMQ-2.0.0-src.zip ](https://archive.apache.org/dist/activemq/apache-nms-activemq/2.0.0/Apache.NMS.ActiveMQ-2.0.0-src.zip)|[SHA512](https://downloads.apache.org/activemq/apache-nms-activemq/2.0.0/Apache.NMS.ActiveMQ-2.0.0-src.zip.sha512)|[PGP Signature](https://downloads.apache.org/activemq/apache-nms-activemq/2.0.0/Apache.NMS.ActiveMQ-2.0.0-src.zip.asc) +Apache.NMS.ActiveMQ Binary Assemblies|[Apache.NMS.ActiveMQ-2.0.0-bin.zip](https://archive.apache.org/dist/activemq/apache-nms-activemq/2.0.0/Apache.NMS.ActiveMQ-2.0.0-bin.zip)|[SHA512](https://downloads.apache.org/activemq/apache-nms-activemq/2.0.0/Apache.NMS.ActiveMQ-2.0.0-bin.zip.sha512)|[PGP Signature](https://downloads.apache.org/activemq/apache-nms-activemq/2.0.0/Apache.NMS.ActiveMQ-2.0.0-bin.zip.asc) + +Changelog +--------- + +For a more detailed view of new features and bug fixes, see the [release notes](). diff --git a/hugo/content/news/apachenmsactivemq-v201.md b/hugo/content/news/apachenmsactivemq-v201.md new file mode 100644 index 0000000000..1fba974e13 --- /dev/null +++ b/hugo/content/news/apachenmsactivemq-v201.md @@ -0,0 +1,18 @@ +--- +title: "Apache.NMS.ActiveMQ 2.0.1 Release" +date: 2023-02-14 +description: "Deadlock fix in WinForms environment." +--- + +Apache NMS.ActiveMQ was released on . This release contains a single bug fix. + +Download Here +------------- + +Apache.NMS.ActiveMQ Source code|[Apache.NMS.ActiveMQ-2.0.1-src.zip ](https://archive.apache.org/dist/activemq/apache-nms-activemq/2.0.1/Apache.NMS.ActiveMQ-2.0.1-src.zip)|[SHA512](https://downloads.apache.org/activemq/apache-nms-activemq/2.0.1/Apache.NMS.ActiveMQ-2.0.1-src.zip.sha512)|[PGP Signature](https://downloads.apache.org/activemq/apache-nms-activemq/2.0.1/Apache.NMS.ActiveMQ-2.0.1-src.zip.asc) +Apache.NMS.ActiveMQ Binary Assemblies|[Apache.NMS.ActiveMQ-2.0.1-bin.zip](https://archive.apache.org/dist/activemq/apache-nms-activemq/2.0.1/Apache.NMS.ActiveMQ-2.0.1-bin.zip)|[SHA512](https://downloads.apache.org/activemq/apache-nms-activemq/2.0.1/Apache.NMS.ActiveMQ-2.0.1-bin.zip.sha512)|[PGP Signature](https://downloads.apache.org/activemq/apache-nms-activemq/2.0.1/Apache.NMS.ActiveMQ-2.0.1-bin.zip.asc) + +Changelog +--------- + +For a more detailed view of new features and bug fixes, see the [release notes](). diff --git a/hugo/content/news/apachenmsactivemq-v210.md b/hugo/content/news/apachenmsactivemq-v210.md new file mode 100644 index 0000000000..80a5dd5a00 --- /dev/null +++ b/hugo/content/news/apachenmsactivemq-v210.md @@ -0,0 +1,18 @@ +--- +title: "Apache.NMS.ActiveMQ 2.1.0 Release" +date: 2023-03-12 +description: "Security enhancement for binary serialization by adding allow/deny list of types." +--- + +Apache NMS.ActiveMQ was released on . This release contains a single bug fix. + +Download Here +------------- + +Apache.NMS.ActiveMQ Source code|[Apache.NMS.ActiveMQ-2.1.0-src.zip ](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-activemq/2.1.0/Apache.NMS.ActiveMQ-2.1.0-src.zip&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-activemq/2.1.0/Apache.NMS.ActiveMQ-2.1.0-src.zip.sha512)|[PGP Signature](https://downloads.apache.org/activemq/apache-nms-activemq/2.1.0/Apache.NMS.ActiveMQ-2.1.0-src.zip.asc) +Apache.NMS.ActiveMQ Binary Assemblies|[Apache.NMS.ActiveMQ-2.1.0-bin.zip](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-activemq/2.1.0/Apache.NMS.ActiveMQ-2.1.0-bin.zip&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-activemq/2.1.0/Apache.NMS.ActiveMQ-2.1.0-bin.zip.sha512)|[PGP Signature](https://downloads.apache.org/activemq/apache-nms-activemq/2.1.0/Apache.NMS.ActiveMQ-2.1.0-bin.zip.asc) + +Changelog +--------- + +For a more detailed view of new features and bug fixes, see the [release notes](). diff --git a/hugo/content/news/apachenmsactivemq-v211.md b/hugo/content/news/apachenmsactivemq-v211.md new file mode 100644 index 0000000000..9d51b71177 --- /dev/null +++ b/hugo/content/news/apachenmsactivemq-v211.md @@ -0,0 +1,18 @@ +--- +title: "Apache.NMS.ActiveMQ 2.1.1 Release" +date: 2025-02-16 +description: "Various enhancements and fixes, including SSL buffer size support and nested parameters for failover transport." +--- + +Apache NMS.ActiveMQ was released on . This release includes several enhancements and bug fixes. + +Download Here +------------- + +Apache.NMS.ActiveMQ Source code|[Apache.NMS.ActiveMQ-2.1.1-src.zip ](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-activemq/2.1.1/Apache.NMS.ActiveMQ-2.1.1-src.zip&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-activemq/2.1.1/Apache.NMS.ActiveMQ-2.1.1-src.zip.sha512)|[PGP Signature](https://downloads.apache.org/activemq/apache-nms-activemq/2.1.1/Apache.NMS.ActiveMQ-2.1.1-src.zip.asc) +Apache.NMS.ActiveMQ Binary Assemblies|[Apache.NMS.ActiveMQ-2.1.1-bin.zip](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-activemq/2.1.1/Apache.NMS.ActiveMQ-2.1.1-bin.zip&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-activemq/2.1.1/Apache.NMS.ActiveMQ-2.1.1-bin.zip.sha512)|[PGP Signature](https://downloads.apache.org/activemq/apache-nms-activemq/2.1.1/Apache.NMS.ActiveMQ-2.1.1-bin.zip.asc) + +Changelog +--------- + +For a more detailed view of new features and bug fixes, see the [release notes](). diff --git a/hugo/content/news/apachenmsactivemq-v220.md b/hugo/content/news/apachenmsactivemq-v220.md new file mode 100644 index 0000000000..48761877a0 --- /dev/null +++ b/hugo/content/news/apachenmsactivemq-v220.md @@ -0,0 +1,18 @@ +--- +title: "Apache.NMS.ActiveMQ 2.2.0 Release" +date: 2025-11-27 +description: "Dependency upgrade to Apache.NMS version 2.2.0." +--- + +Apache NMS.ActiveMQ was released on . This release includes a dependency upgrade. + +Download Here +------------- + +Apache.NMS.ActiveMQ Source code|[Apache.NMS.ActiveMQ-2.2.0-src.zip ](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-activemq/2.2.0/Apache.NMS.ActiveMQ-2.2.0-src.zip&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-activemq/2.2.0/Apache.NMS.ActiveMQ-2.2.0-src.zip.sha512)|[PGP Signature](https://downloads.apache.org/activemq/apache-nms-activemq/2.2.0/Apache.NMS.ActiveMQ-2.2.0-src.zip.asc) +Apache.NMS.ActiveMQ Binary Assemblies|[Apache.NMS.ActiveMQ-2.2.0-bin.zip](https://www.apache.org/dyn/closer.lua?filename=/activemq/apache-nms-activemq/2.2.0/Apache.NMS.ActiveMQ-2.2.0-bin.zip&action=download)|[SHA512](https://downloads.apache.org/activemq/apache-nms-activemq/2.2.0/Apache.NMS.ActiveMQ-2.2.0-bin.zip.sha512)|[PGP Signature](https://downloads.apache.org/activemq/apache-nms-activemq/2.2.0/Apache.NMS.ActiveMQ-2.2.0-bin.zip.asc) + +Changelog +--------- + +For a more detailed view of new features and bug fixes, see the [release notes](). diff --git a/hugo/content/news/artemis-tlp.md b/hugo/content/news/artemis-tlp.md new file mode 100644 index 0000000000..aa568eb19c --- /dev/null +++ b/hugo/content/news/artemis-tlp.md @@ -0,0 +1,13 @@ +--- +title: "Apache Artemis Project" +date: 2025-11-19 +description: "ActiveMQ PMC voted to establish Apache Artemis Project." +--- + +In order to provide greater clarity and dedicated focus for our communities, the Apache ActiveMQ PMC has decided to establish two distinct Apache Top-Level Projects: **Apache ActiveMQ** and **Apache Artemis**. + +Both projects are highly active with vibrant communities, and this separation will grant each project better visibility and autonomy. Moving forward, each project will evolve independently with dedicated governance, fostering their unique development paths. + +The new [Apache Artemis](https://artemis.apache.org) website is now live. + +— The Apache ActiveMQ PMC diff --git a/hugo/content/news/classic-05-15-14.md b/hugo/content/news/classic-05-15-14.md new file mode 100644 index 0000000000..b07f9d1292 --- /dev/null +++ b/hugo/content/news/classic-05-15-14.md @@ -0,0 +1,6 @@ +--- +title: "ActiveMQ Classic 5.15.14 Release" +date: 2020-12-09 +--- + +Apache ActiveMQ Classic was released on and includes several resolved [issues]() and bug fixes. diff --git a/hugo/content/news/classic-05-15-15.md b/hugo/content/news/classic-05-15-15.md new file mode 100644 index 0000000000..5a38ee38a5 --- /dev/null +++ b/hugo/content/news/classic-05-15-15.md @@ -0,0 +1,11 @@ +--- +title: "ActiveMQ Classic 5.15.15 Release" +date: 2021-04-28 +description: ">" +--- + +Apache ActiveMQ Classic was released on and includes several resolved [issues]() and bug fixes. + +
    +This is the last intended 5.15.x release. Users should upgrade to the current stream for ongoing releases, as noted in April 2021. +
    diff --git a/hugo/content/news/classic-05-15-16.md b/hugo/content/news/classic-05-15-16.md new file mode 100644 index 0000000000..7c93179d83 --- /dev/null +++ b/hugo/content/news/classic-05-15-16.md @@ -0,0 +1,11 @@ +--- +title: "ActiveMQ Classic 5.15.16 Release" +date: 2023-10-26 +description: ">" +--- + +Apache ActiveMQ Classic was released on and includes several resolved [issues]() and bug fixes. + +
    +This is the last intended 5.15.x release. Users should upgrade to the current stream for ongoing releases, as noted in April 2021. +
    diff --git a/hugo/content/news/classic-05-16-01.md b/hugo/content/news/classic-05-16-01.md new file mode 100644 index 0000000000..7aec6ee122 --- /dev/null +++ b/hugo/content/news/classic-05-16-01.md @@ -0,0 +1,10 @@ +--- +title: "ActiveMQ Classic 5.16.1 Release" +date: 2021-01-20 +--- + +Apache ActiveMQ Classic was released on . It fully supports JDK 9+ at runtime and includes several resolved [issues]() and bug fixes. + +This release addresses the following CVEs: +- [CVE-2021-26117: LDAP-Authentication does not verify passwords on servers with anonymous bind.](../security-advisories.data/CVE-2021-26117-announcement.txt) +- [CVE-2020-13947: XSS in WebConsole.](../security-advisories.data/CVE-2020-13947-announcement.txt) diff --git a/hugo/content/news/classic-05-16-02.md b/hugo/content/news/classic-05-16-02.md new file mode 100644 index 0000000000..cadc2232a3 --- /dev/null +++ b/hugo/content/news/classic-05-16-02.md @@ -0,0 +1,7 @@ +--- +title: "ActiveMQ Classic 5.16.2 Release" +date: 2021-04-28 +description: "Apache ActiveMQ Classic 5.16.2 was released on Apr 28th, 2021. It fully supports JDK 9+ at runtime and includes several resolved issues and bug fixes." +--- + +Apache ActiveMQ Classic was released on . It fully supports JDK 9+ at runtime and includes several resolved [issues]() and bug fixes. diff --git a/hugo/content/news/classic-05-16-03.md b/hugo/content/news/classic-05-16-03.md new file mode 100644 index 0000000000..18c1706af6 --- /dev/null +++ b/hugo/content/news/classic-05-16-03.md @@ -0,0 +1,7 @@ +--- +title: "ActiveMQ Classic 5.16.3 Release" +date: 2021-08-17 +description: "Fully supports JDK 9+ at runtime and includes 10 bug fixes, 15 dependency upgrades, and 3 enhancements." +--- + +Apache ActiveMQ Classic was released on . It fully supports JDK 9+ at runtime and includes several resolved [issues]() and bug fixes. diff --git a/hugo/content/news/classic-05-16-04.md b/hugo/content/news/classic-05-16-04.md new file mode 100644 index 0000000000..1e1eecb5bb --- /dev/null +++ b/hugo/content/news/classic-05-16-04.md @@ -0,0 +1,7 @@ +--- +title: "ActiveMQ Classic 5.16.4 Release" +date: 2022-02-15 +description: "Important release, switching from log4j 1.x to reload4j, and including several improvements and dependency updates." +--- + +Apache ActiveMQ Classic was released on . It's an important release, switching from log4j 1.x to reload4j, and including several resolved [issues]() and bug fixes. diff --git a/hugo/content/news/classic-05-16-05.md b/hugo/content/news/classic-05-16-05.md new file mode 100644 index 0000000000..1d3a177621 --- /dev/null +++ b/hugo/content/news/classic-05-16-05.md @@ -0,0 +1,11 @@ +--- +title: "ActiveMQ Classic 5.16.5 Release" +date: 2022-05-02 +description: "Important release, switching from log4j 1.x to reload4j, and including several improvements and dependency updates." +--- + +Apache ActiveMQ Classic was released on . It's an important release, switching from log4j 1.x to reload4j, and including several resolved [issues]() and bug fixes. + +
    +This is the last intended Classic 5.16.x release. Users should upgrade to the current stream for ongoing releases, as noted in May 2022. +
    diff --git a/hugo/content/news/classic-05-16-06.md b/hugo/content/news/classic-05-16-06.md new file mode 100644 index 0000000000..64f4c63dfd --- /dev/null +++ b/hugo/content/news/classic-05-16-06.md @@ -0,0 +1,11 @@ +--- +title: "ActiveMQ Classic 5.16.6 Release" +date: 2023-02-16 +description: "Important release, including several improvements, fixes, and dependency updates." +--- + +Apache ActiveMQ Classic was released on . It's an important release, switching including several resolved [issues](). + +
    +This is the last intended Classic 5.16.x release. Users should upgrade to the current stream for ongoing releases, as noted in May 2022. +
    diff --git a/hugo/content/news/classic-05-16-07.md b/hugo/content/news/classic-05-16-07.md new file mode 100644 index 0000000000..e003fb9c5e --- /dev/null +++ b/hugo/content/news/classic-05-16-07.md @@ -0,0 +1,11 @@ +--- +title: "ActiveMQ Classic 5.16.7 Release" +date: 2023-10-26 +description: ">" +--- + +Apache ActiveMQ Classic was released on . It's an important release, switching including several resolved [issues](). + +
    +This is the last intended Classic 5.16.x release. Users should upgrade to the current stream for ongoing releases, as noted in May 2022. +
    diff --git a/hugo/content/news/classic-05-16-08.md b/hugo/content/news/classic-05-16-08.md new file mode 100644 index 0000000000..2e6dc71877 --- /dev/null +++ b/hugo/content/news/classic-05-16-08.md @@ -0,0 +1,11 @@ +--- +title: "ActiveMQ Classic 5.16.8 Release" +date: 2025-03-22 +description: ">" +--- + +Apache ActiveMQ Classic was released on . It's an important release, including several resolved [issues](). + +
    +This is the last intended Classic 5.16.x release. Users should upgrade to the current stream for ongoing releases, as noted in May 2022. +
    diff --git a/hugo/content/news/classic-05-17-00.md b/hugo/content/news/classic-05-17-00.md new file mode 100644 index 0000000000..1c4e45684d --- /dev/null +++ b/hugo/content/news/classic-05-17-00.md @@ -0,0 +1,7 @@ +--- +title: "ActiveMQ Classic 5.17.0 Release" +date: 2022-03-14 +description: "Important release, using Spring 5.x, Log4j 2.x, JDK 11+, and other major updates and fixes." +--- + +Apache ActiveMQ Classic was released on . It's a major milestone for ActiveMQ Classic, now using Spring 5.x, Log4j 2.x, and other major updates and resolved [issues]() and bug fixes. diff --git a/hugo/content/news/classic-05-17-01.md b/hugo/content/news/classic-05-17-01.md new file mode 100644 index 0000000000..c9587acd8f --- /dev/null +++ b/hugo/content/news/classic-05-17-01.md @@ -0,0 +1,7 @@ +--- +title: "ActiveMQ Classic 5.17.1 Release" +date: 2022-04-29 +description: "Maintenance release on Classic 5.17.x series, containing Spring 5.3.19, XBean 4.21, and a lot of other changes." +--- + +Apache ActiveMQ Classic was released on . It's a major milestone for ActiveMQ Classic, now using Spring 5.x, Log4j 2.x, and other major updates and resolved [issues]() and bug fixes. diff --git a/hugo/content/news/classic-05-17-02.md b/hugo/content/news/classic-05-17-02.md new file mode 100644 index 0000000000..9a8c1bdc01 --- /dev/null +++ b/hugo/content/news/classic-05-17-02.md @@ -0,0 +1,7 @@ +--- +title: "ActiveMQ Classic 5.17.2 Release" +date: 2022-09-02 +description: "Maintenance release on Classic 5.17.x series, containing Spring 5.3.22, Log4J 2.18.0, and a lot of other changes." +--- + +Apache ActiveMQ Classic was released on . It's a major milestone for ActiveMQ Classic, now using Spring 5.x, Log4j 2.x, and other major updates and resolved [issues]() and bug fixes. diff --git a/hugo/content/news/classic-05-17-03.md b/hugo/content/news/classic-05-17-03.md new file mode 100644 index 0000000000..ac47f19709 --- /dev/null +++ b/hugo/content/news/classic-05-17-03.md @@ -0,0 +1,7 @@ +--- +title: "ActiveMQ Classic 5.17.3 Release" +date: 2022-12-04 +description: "Maintenance release on Classic 5.17.x series, containing Spring 5.3.23, Log4J 2.19.0, and a lot of other fixes and improvements." +--- + +Apache ActiveMQ Classic was released on . It's a major milestone for ActiveMQ Classic, now using Spring 5.x, Log4j 2.x, and other major updates and resolved [issues]() and bug fixes. diff --git a/hugo/content/news/classic-05-17-04.md b/hugo/content/news/classic-05-17-04.md new file mode 100644 index 0000000000..92b893c962 --- /dev/null +++ b/hugo/content/news/classic-05-17-04.md @@ -0,0 +1,7 @@ +--- +title: "ActiveMQ Classic 5.17.4 Release" +date: 2023-02-25 +description: "Maintenance release on Classic 5.17.x series, containing Spring 5.3.25, xstream 1.4.20, and a lot of other fixes and improvements." +--- + +Apache ActiveMQ Classic was released on . It's a major milestone for ActiveMQ Classic, now using Spring 5.x, Log4j 2.x, and other major updates and resolved [issues]() and bug fixes. diff --git a/hugo/content/news/classic-05-17-05.md b/hugo/content/news/classic-05-17-05.md new file mode 100644 index 0000000000..7d856ad431 --- /dev/null +++ b/hugo/content/news/classic-05-17-05.md @@ -0,0 +1,16 @@ +--- +title: "ActiveMQ Classic 5.17.5 Release" +date: 2023-07-02 +description: "Maintenance release on Classic 5.17.x series" +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release on the ActiveMQ Classic 5.17.x series, bringing: +- fix on stale queues when a connection is long to shutdown +- fix on KahaDB where the db files may be larger than the maxLength configuration +- fix on composite consumers on a Network of Brokers +- fix memory leak on STOMP transport when client unsubscribe +- a bunch of dependency updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-17-06.md b/hugo/content/news/classic-05-17-06.md new file mode 100644 index 0000000000..47f033a06d --- /dev/null +++ b/hugo/content/news/classic-05-17-06.md @@ -0,0 +1,15 @@ +--- +title: "ActiveMQ Classic 5.17.6 Release" +date: 2023-10-25 +description: "Maintenance release on Classic 5.17.x series" +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release on the ActiveMQ Classic 5.17.x series, bringing: +- improvement on KahaDB memory consumption +- add additional fields on JMX Connection MBean +- improvement on OpenWire marshaller on Throwable class type +- a lot of dependency updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-17-07.md b/hugo/content/news/classic-05-17-07.md new file mode 100644 index 0000000000..d100288567 --- /dev/null +++ b/hugo/content/news/classic-05-17-07.md @@ -0,0 +1,17 @@ +--- +title: "ActiveMQ Classic 5.17.7 Release" +date: 2025-03-20 +description: "Maintenance release on Classic 5.17.x series" +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release on the ActiveMQ Classic 5.17.x series, bringing: +- fix Out Of Memory error reported on ActiveMQ client during openwire unmarshalling +- fix concurrent modification in ActiveMQServiceFactory +- fix websocket transport options do not get applied +- fix Jolokia throws exception during Windows service startup +- fix queue creation during browse in the WebConsole +- several dependency updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-18-00.md b/hugo/content/news/classic-05-18-00.md new file mode 100644 index 0000000000..10265de50a --- /dev/null +++ b/hugo/content/news/classic-05-18-00.md @@ -0,0 +1,17 @@ +--- +title: "ActiveMQ Classic 5.18.0 Release" +date: 2023-03-24 +description: "Classic 5.18.0 brings initial JMS 2.0 (javax.jms API) and Jakarta Messaging 3.1 (jakarta.jms API) client support, Spring 5.3.x, and various dependency updates, fixes and improvements." +--- + +Apache ActiveMQ Classic was released on . It's a major milestone for the ActiveMQ Classic. +ActiveMQ Classic 5.18.x brings: +* It brings initial JMS 2.0 (javax.jms API namespace) and Jakarta Messaging 3.1 (jakarta.jms API namespace) client support. See the [JMS 2.0 page](/components/classic/documentation/jms2) for more details on the available functionality and how to use the Jakarta Messaging support. +* Spring 5.3.x +* optimized LDAP use in LDAP JAAS login module +* improved REST API +* improved redelivery policy +* a lot of dependency updates +* and much more! + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-18-01.md b/hugo/content/news/classic-05-18-01.md new file mode 100644 index 0000000000..04976d09a0 --- /dev/null +++ b/hugo/content/news/classic-05-18-01.md @@ -0,0 +1,11 @@ +--- +title: "ActiveMQ Classic 5.18.1 Release" +date: 2023-04-14 +description: "Maintenance release on Classic 5.18.x series. It fixes an issue on the activemq-client-jakarta artifact." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release on the ActiveMQ Classic 5.18.x series, fixing an issue on the `activemq-client-jakarta` artifact. + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-18-02.md b/hugo/content/news/classic-05-18-02.md new file mode 100644 index 0000000000..2739fb0af1 --- /dev/null +++ b/hugo/content/news/classic-05-18-02.md @@ -0,0 +1,15 @@ +--- +title: "ActiveMQ Classic 5.18.2 Release" +date: 2023-07-02 +description: "Maintenance release on Classic 5.18.x series. It fixes an issue on the activemq-client-jakarta artifact." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release on the ActiveMQ Classic 5.18.x series, bringing: +- fix potential NPE when removing consumer with selector +- fix composite consumers in a Network of Brokers +- fix memory leak on the STOMP transport when client unsubscribe +- a bunch of dependency updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-18-03.md b/hugo/content/news/classic-05-18-03.md new file mode 100644 index 0000000000..fd873b699d --- /dev/null +++ b/hugo/content/news/classic-05-18-03.md @@ -0,0 +1,18 @@ +--- +title: "ActiveMQ Classic 5.18.3 Release" +date: 2023-10-25 +description: "Maintenance release on Classic 5.18.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release on the ActiveMQ Classic 5.18.x series, bringing: +- fix on destinations create when message is delayed +- fix on moving message to DLQ when produce via HTTP and TTL is reached +- improvement on KahaDB memory consumption +- improvement on OpenWire marshaller on Throwable class type +- implementation of JMS 2.x XA methods +- fix on JDK17+ support +- a lot of dependency updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-18-04.md b/hugo/content/news/classic-05-18-04.md new file mode 100644 index 0000000000..76b5638093 --- /dev/null +++ b/hugo/content/news/classic-05-18-04.md @@ -0,0 +1,16 @@ +--- +title: "ActiveMQ Classic 5.18.4 Release" +date: 2024-04-11 +description: "Maintenance release on Classic 5.18.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release on the ActiveMQ Classic 5.18.x series, bringing: +- Spring 5.3.33 update (related to Spring CVEs) +- Jetty 9.4.54.v20240208 update +- Jackson 2.16.2 update +- log4j 2.23.1 update +- several bug fixes/improvements + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-18-05.md b/hugo/content/news/classic-05-18-05.md new file mode 100644 index 0000000000..11d57b3042 --- /dev/null +++ b/hugo/content/news/classic-05-18-05.md @@ -0,0 +1,17 @@ +--- +title: "ActiveMQ Classic 5.18.5 Release" +date: 2024-07-24 +description: "Maintenance release on Classic 5.18.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release on the ActiveMQ Classic 5.18.x series, bringing: +- Fix 500 Server Error while polling empty destination via Message REST +- Fix ClassNotFoundException when using runtimeConfigurationPlugin with Java 17 +- Spring 5.3.37 update +- Jetty 9.4.55.v20240627 update +- Jackson 2.17.2 update +- several bug fixes/improvements + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-18-06.md b/hugo/content/news/classic-05-18-06.md new file mode 100644 index 0000000000..f1b46eded8 --- /dev/null +++ b/hugo/content/news/classic-05-18-06.md @@ -0,0 +1,15 @@ +--- +title: "ActiveMQ Classic 5.18.6 Release" +date: 2024-10-02 +description: "Maintenance release on Classic 5.18.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release on the ActiveMQ Classic 5.18.x series, bringing: +- fixes on the STOMP protocol +- fix on KahaDB (on the recovery files) +- improvements on the WebConsole (e.g. cache control policy) +- dependency updates (spring, jetty, ...) + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-18-07.md b/hugo/content/news/classic-05-18-07.md new file mode 100644 index 0000000000..90974ec70e --- /dev/null +++ b/hugo/content/news/classic-05-18-07.md @@ -0,0 +1,20 @@ +--- +title: "ActiveMQ Classic 5.18.7 Release" +date: 2025-03-19 +description: "Maintenance release on Classic 5.18.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release on the ActiveMQ Classic 5.18.x series, bringing: +- fix potential OutOfMemory error on client during OpenWire unmarshalling +- fix ClassCastException in SelectorAwareVirtualTopicInterceptor if +there is another interceptor +- fix durable subscriber receives acknowledge messages if they are +farther than the maxBatchSize +- fix potential issue with messages can become stuck on Queues +- fix potential issue in WebConsole where a queue can be created with +browse page +- several dependencies updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-19-00.md b/hugo/content/news/classic-05-19-00.md new file mode 100644 index 0000000000..0abf9fd028 --- /dev/null +++ b/hugo/content/news/classic-05-19-00.md @@ -0,0 +1,24 @@ +--- +title: "ActiveMQ Classic 5.19.0 Release" +date: 2025-03-11 +description: "First release on the 5.19.x series." +--- + +Apache ActiveMQ Classic was released on . + +This is the first release on the 5.19.x series. It's based on 5.18.x with additional features. + +This release includes: +- fix potential OutOfMemory error on client during OpenWire unmarshalling +- improvement on double slashes in Unix scripts +- fix ClassCastException in SelectorAwareVirtualTopicInterceptor if +there is another interceptor +- fix on WebConsole, checking if a queue exists before being able to browse it +- fix durable subscriber receives acknowledge messages if they are +farther than the maxBatchSize +- update ConnectionView to include WireFormatInfo +- add the ability to disable connector startup on boot +- add advancedMessageStatistics to destinations +- several dependency updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-19-01.md b/hugo/content/news/classic-05-19-01.md new file mode 100644 index 0000000000..1a03c77833 --- /dev/null +++ b/hugo/content/news/classic-05-19-01.md @@ -0,0 +1,22 @@ +--- +title: "ActiveMQ Classic 5.19.1 Release" +date: 2025-10-11 +description: "Maintenance release on the 5.19.x series." +--- + +Apache ActiveMQ Classic was released on . + +This is a maintenance release on the 5.19.x series, including: +- fix on the network of broker TTL management +- fix expiration of persistent messages on durable subscriptions +- fix maxMessageSize behavior changed for value -1 (since 5.19.0) +- fix performance issues with non-persistent message removal from +topic/durable subscriptions +- fix FilePendingMessageCursor clear() method +- fix Kahadb checkpoint runner thread dies without catching exception +- fix backup only recovers one message +- fix KahaDB error while recovering topics with no pending acks and +TRACE logging enabled +- several dependency updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-05-19-02.md b/hugo/content/news/classic-05-19-02.md new file mode 100644 index 0000000000..b2d646b619 --- /dev/null +++ b/hugo/content/news/classic-05-19-02.md @@ -0,0 +1,19 @@ +--- +title: "ActiveMQ Classic 5.19.2 Release" +date: 2026-02-13 +description: "Maintenance release on the 5.19.x series." +--- + +Apache ActiveMQ Classic was released on . + +This is a maintenance release on the 5.19.x series, including: +- the Docker container now runs with non root user +- fix on the Docker container using ACTIVEMQ_OPTS and ACTIVEMQ_OPTS_MEMORY environment variables +- fix on the Runtime Configuration Plugin keeping the network connectors definition in the right order +- add additional validation for MQTT control packets +- fix incorrect QueueSize if non persistent messages with TTL are used +- fix closed connections leaked in the connection pool +- fix on KahaDBStore ackAndPreparedMap not properly cleared when recovered acks are removed +- several dependencies updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-00-00.md b/hugo/content/news/classic-06-00-00.md new file mode 100644 index 0000000000..4ee4589901 --- /dev/null +++ b/hugo/content/news/classic-06-00-00.md @@ -0,0 +1,19 @@ +--- +title: "ActiveMQ Classic 6.0.0 Release" +date: 2023-11-17 +description: "Classic 6.0.0 is a major release for ActiveMQ Classic, starting the 6.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a major release for the project, especially bringing: +- [Partial Jakarta Messaging 3.1 & JMS 2.0 support](/components/classic/documentation/jms2) (new features will come in the 6.x series) +- Jakarta EE namespace support +- JDK17/20/21 support +- Spring 6.x support +- Jetty 11.x support +- Apache Camel 4.x support +- Jolokia 2.x support +- and much more ! + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-00-01.md b/hugo/content/news/classic-06-00-01.md new file mode 100644 index 0000000000..259bbced91 --- /dev/null +++ b/hugo/content/news/classic-06-00-01.md @@ -0,0 +1,16 @@ +--- +title: "ActiveMQ Classic 6.0.1 Release" +date: 2023-12-03 +description: "Maintenance release on Classic 6.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release on the 6.x series, especially bringing: +- Fix Jakarta support in ActiveMQ RA +- Fix OSGi headers in activemq-jms-pool and activemq-cf +- Fix provided jetty.xml example on the SSL connector +- Fix jolokia conf loading when using Windows service wrapper +- Several dependency updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-01-00.md b/hugo/content/news/classic-06-01-00.md new file mode 100644 index 0000000000..f45f546363 --- /dev/null +++ b/hugo/content/news/classic-06-01-00.md @@ -0,0 +1,17 @@ +--- +title: "ActiveMQ Classic 6.1.0 Release" +date: 2024-03-15 +description: "Classic 6.1.0 is a major release for ActiveMQ Classic, starting the 6.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a major release for the project, especially bringing: +- New JMS 2/3 operations support +- Mapping javax / jakarta exception in openwire protocol +- Add destination field on the job scheduler +- Add org.apache.activemq.broker.BouncyCastleNotAdded property to control the bouncycastle addition in BrokerService classloader +- A lot of dependency upgrades (Spring 6.1.4, log4j 2.23.0, Jetty 11.0.20, ...) +- and much more ! + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-01-01.md b/hugo/content/news/classic-06-01-01.md new file mode 100644 index 0000000000..574d54935d --- /dev/null +++ b/hugo/content/news/classic-06-01-01.md @@ -0,0 +1,16 @@ +--- +title: "ActiveMQ Classic 6.1.1 Release" +date: 2024-04-05 +description: "Classic 6.1.1 is a maintanance release for ActiveMQ Classic, on the 6.1.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a major release for the project, especially bringing: +- add firstMessageTimestamp in the StatisticsPlugin +- fix on Docker images authentication +- add sun.nio.* opens classes required for some transports +- important dependency updates, especially Spring 6.1.5 +- and much more ! + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-01-02.md b/hugo/content/news/classic-06-01-02.md new file mode 100644 index 0000000000..6dd23e721e --- /dev/null +++ b/hugo/content/news/classic-06-01-02.md @@ -0,0 +1,15 @@ +--- +title: "ActiveMQ Classic 6.1.2 Release" +date: 2024-04-15 +description: "Classic 6.1.2 is a maintanance release for ActiveMQ Classic, on the 6.1.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a major release for the project, especially bringing: +- secure Jolokia and REST Message API by default +- fix on runtimeConfigurationPlugin JMX MBean reload operation +- fix when consuming empty destination via REST Message API +- fix client/server SSL socket configuration via URI + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-01-03.md b/hugo/content/news/classic-06-01-03.md new file mode 100644 index 0000000000..77a6c184c5 --- /dev/null +++ b/hugo/content/news/classic-06-01-03.md @@ -0,0 +1,16 @@ +--- +title: "ActiveMQ Classic 6.1.3 Release" +date: 2024-08-08 +description: "Classic 6.1.3 is a maintanance release for ActiveMQ Classic, on the 6.1.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release especially bringing: +- add a BoM +- fixes on the Message REST API, especially concurrent access +- Spring 6.1.11 update +- fix NoClassDefFound on bin/activemq export command line +- several dependency updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-01-04.md b/hugo/content/news/classic-06-01-04.md new file mode 100644 index 0000000000..3c2330c444 --- /dev/null +++ b/hugo/content/news/classic-06-01-04.md @@ -0,0 +1,16 @@ +--- +title: "ActiveMQ Classic 6.1.4 Release" +date: 2024-11-12 +description: "Classic 6.1.4 is a maintanance release for ActiveMQ Classic, on the 6.1.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release especially bringing: +- fix message corruption when using 4-bytes Unicode message from JMS to STOMP +- prevent ClassCastException in SelectorAwareVirtualTopicInterceptor if there is another interceptor +- fix KahaDB PageFile can call setLength() on the recovery file which always throws an exception +- fix Durable Subscriber receives acknowledge messages if they are farther than the maxBatchSize +- ... a bunch of dependency updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-01-05.md b/hugo/content/news/classic-06-01-05.md new file mode 100644 index 0000000000..cf145f669f --- /dev/null +++ b/hugo/content/news/classic-06-01-05.md @@ -0,0 +1,14 @@ +--- +title: "ActiveMQ Classic 6.1.5 Release" +date: 2025-01-13 +description: "Classic 6.1.5 is a maintanance release for ActiveMQ Classic, on the 6.1.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release especially bringing: +- messages (in specific circumstances) can become stuck in queues +- remove commons-io use (replaced by JDK methods) +- several dependency updates, especially Spring 6.1.16, Jackson 2.18.2, Jolokia 2.1.2 (removing json-simple dependency), xstream 1.4.21 + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-01-06.md b/hugo/content/news/classic-06-01-06.md new file mode 100644 index 0000000000..60a6cc3d9a --- /dev/null +++ b/hugo/content/news/classic-06-01-06.md @@ -0,0 +1,17 @@ +--- +title: "ActiveMQ Classic 6.1.6 Release" +date: 2025-03-07 +description: "ActiveMQ Classic 6.1.6 is a maintanance release on the 6.1.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release especially bringing: +- fix potential OutOfMemory error on client during OpenWire unmarshalling +- improvement on double slash issue in Unix script +- fix TcpTransport volatile receiveCounter (not increased automatically) +- improvement on WebConsole, checking if a queue exists before being +able to browse it +- several dependency updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-01-07.md b/hugo/content/news/classic-06-01-07.md new file mode 100644 index 0000000000..e8c81fa1cd --- /dev/null +++ b/hugo/content/news/classic-06-01-07.md @@ -0,0 +1,23 @@ +--- +title: "ActiveMQ Classic 6.1.7 Release" +date: 2025-06-22 +description: "ActiveMQ Classic 6.1.7 is a maintanance release on the 6.1.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release especially bringing: +- improvements on the HTTP connector working with XA +- fix deadlock in RA ServerSessionImpl +- fix empty virtualName from broken queue name +- fixes and improvements on Network of Broker durable sync TTL +- fix expiration of persistent messages on durable subscriptions +- fix maxMessageSize behavior changed for value -1 +- fix performance issues with non-persistent message removal from +topic/durable subscriptions +- add Security Content Policy header to the Web Console +- add an wireFormat option on the HTTP transport to not send the full +stack trace to the client +- a bunch of dependencies updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-01-08.md b/hugo/content/news/classic-06-01-08.md new file mode 100644 index 0000000000..5cf751a2e7 --- /dev/null +++ b/hugo/content/news/classic-06-01-08.md @@ -0,0 +1,14 @@ +--- +title: "ActiveMQ Classic 6.1.8 Release" +date: 2025-10-22 +description: "ActiveMQ Classic 6.1.8 is a maintanance release on the 6.1.x series." +--- + +Apache ActiveMQ Classic was released on . + +It's a maintenance release especially bringing: +- fixes on the webconsole (columns sorting, assets resolution in HTTP, ...) +- fixes on KahaDB (checkpoint runner thread was diying without catching exception, error while recovering topics with no pending acks and TRACE logging enabled, ...) +- a bunch of dependencies updates (jolokia, jetty, log4j, jackson, ...) + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-02-00.md b/hugo/content/news/classic-06-02-00.md new file mode 100644 index 0000000000..dcc8249175 --- /dev/null +++ b/hugo/content/news/classic-06-02-00.md @@ -0,0 +1,19 @@ +--- +title: "ActiveMQ Classic 6.2.0 Release" +date: 2025-11-14 +description: "ActiveMQ Classic 6.2.0 is a new milestone for the project, starting the 6.2.x series." +--- + +Apache ActiveMQ Classic was released on . + +This is a new milestone for the project, starting the 6.2.x series. +This release especially brings: +- several fixes and improvements on KahaDB +- several fixes and improvements on the client and openwire protocol +- several improvements on the Web Console +- a fix on the runtime config plugin, dealing with the network connectors ordering +- performance improvements +- a bunch of dependency updates, especially Spring 6.2.12, Jetty 11.0.26, Shiro 2.0.6, Camel 4.14.2, Jackson 2.20.1, Jolokia 2.4.0 and more +- and much much more + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-06-02-01.md b/hugo/content/news/classic-06-02-01.md new file mode 100644 index 0000000000..3b097c8d8f --- /dev/null +++ b/hugo/content/news/classic-06-02-01.md @@ -0,0 +1,19 @@ +--- +title: "ActiveMQ Classic 6.2.1 Release" +date: 2026-02-18 +description: "ActiveMQ Classic 6.2.1 is a new milestone for the project, starting the 6.2.x series." +--- + +Apache ActiveMQ Classic was released on . + +This is a new milestone for the project, starting the 6.2.x series. +This release especially includes: +- running Docker container with non root user +- fix on environment variables propagation in the Docker container +- additional validation on MQTT control packets +- fix incorrect QueueSize if Non-Persistent messages with TTL is used +- fix KahaDBStore ackAndPreparedMap is not properly cleared when recovered acks are removed +- fix ManagementContext unregister race condition +- a lot of dependencies updates + +You can find details on the [release notes](). diff --git a/hugo/content/news/classic-5-19-1-release.md b/hugo/content/news/classic-5-19-1-release.md new file mode 100644 index 0000000000..6cabbb32bb --- /dev/null +++ b/hugo/content/news/classic-5-19-1-release.md @@ -0,0 +1,17 @@ +--- +title: "ActiveMQ Classic 5.19.1 Release" +date: 2025-10-11 +description: "Maintenance release on the 5.19.x series." +--- + +Apache ActiveMQ Classic 5.19.1 was released on October 11th, 2025. + +This is a maintenance release on the 5.19.x series, including: + +- Fix on the network of broker TTL management +- Fix expiration of persistent messages on durable subscriptions +- Fix maxMessageSize behavior for value -1 +- Fix performance issues with non-persistent message removal +- Several dependency updates + +See the [release notes](https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12311210&version=12355592) for full details. diff --git a/hugo/content/news/classic-6-2-1-release.md b/hugo/content/news/classic-6-2-1-release.md new file mode 100644 index 0000000000..20812a372f --- /dev/null +++ b/hugo/content/news/classic-6-2-1-release.md @@ -0,0 +1,19 @@ +--- +title: "ActiveMQ Classic 6.2.1 Release" +date: 2026-02-18 +description: "ActiveMQ Classic 6.2.1 is a new milestone for the project, starting the 6.2.x series." +--- + +Apache ActiveMQ Classic 6.2.1 was released on February 18th, 2026. + +This is a new milestone for the project, starting the 6.2.x series. This release includes: + +- Running Docker container with non-root user +- Fix on environment variables propagation in the Docker container +- Additional validation on MQTT control packets +- Fix incorrect QueueSize if non-persistent messages with TTL is used +- Fix KahaDBStore ackAndPreparedMap not properly cleared when recovered acks are removed +- Fix ManagementContext unregister race condition +- Dependency updates + +See the [release notes](https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12311210&version=12356338) for full details. diff --git a/hugo/content/news/cve-2021-44228.md b/hugo/content/news/cve-2021-44228.md new file mode 100644 index 0000000000..733c62dde8 --- /dev/null +++ b/hugo/content/news/cve-2021-44228.md @@ -0,0 +1,11 @@ +--- +title: "Update on CVE-2021-44228" +date: 2021-12-14 +description: "CVE-2021-44228 (Log4Shell) has no impact on any ActiveMQ broker. No action required." +--- + +[CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) (Log4Shell) has **no impact on any ActiveMQ broker**. No ActiveMQ broker uses Log4j2. + +ActiveMQ Classic uses Log4j 1.2.17 (since 5.7.0), which is not affected. ActiveMQ Artemis does not use Log4j for logging at all. + +**No action is required to mitigate CVE-2021-44228.** diff --git a/hugo/content/news/cve-2023-46604.md b/hugo/content/news/cve-2023-46604.md new file mode 100644 index 0000000000..0520c4c3ed --- /dev/null +++ b/hugo/content/news/cve-2023-46604.md @@ -0,0 +1,16 @@ +--- +title: "Update on CVE-2023-46604" +date: 2023-11-03 +description: "Remote Code Execution vulnerability in the OpenWire protocol marshaller. Upgrade recommended." +--- + +[CVE-2023-46604](https://nvd.nist.gov/vuln/detail/CVE-2023-46604) affects the Java OpenWire protocol marshaller and may allow a remote attacker with network access to run arbitrary shell commands. + +**Users of both ActiveMQ Classic and ActiveMQ Artemis brokers are recommended to upgrade.** + +Fixed releases: + +- ActiveMQ Classic: 6.0.0, 5.18.3, 5.17.6, 5.16.7, 5.15.16 +- ActiveMQ Artemis: 2.31.2 + +The only known exploit uses `ClassPathXmlApplicationContext` to load a malicious XML configuration file over HTTP. Upgrading to a patched release fully mitigates the issue. diff --git a/hugo/content/news/news-feed.md b/hugo/content/news/news-feed.md new file mode 100644 index 0000000000..fd058cdebc --- /dev/null +++ b/hugo/content/news/news-feed.md @@ -0,0 +1,7 @@ +--- +title: "ActiveMQ News Feed" +date: 2021-08-30 +description: "Checkout the new news feed!" +--- + +The ActiveMQ website now has this handy dandy news feed where you'll find the latest releases, CVEs, blogs, articles, roadmaps, etc. diff --git a/hugo/content/news/nms-amqp-01-08-00-release.md b/hugo/content/news/nms-amqp-01-08-00-release.md new file mode 100644 index 0000000000..a2357ffe26 --- /dev/null +++ b/hugo/content/news/nms-amqp-01-08-00-release.md @@ -0,0 +1,22 @@ +--- +title: "Apache.NMS.AMQP 1.8.0 Release" +date: 2019-11-04 +--- + +New and Noteworthy +------------------ + +This is the first release of the Apache NMS AMQP client provider. + +It is also the first provider impl which adds .net standard 2.0 support, as well provides nuget packages. + +This NMS provider can be used against both ActiveMQ 5.x as well as ActiveMQ Artemis and any other AMQP 1.0 compliant broker. + +API Documentation +----------------- + +Refer to the API [here](../../../nms-api) + +|Description|Download Link|PGP Signature File|Version| +|---|---|---|---| +|Apache.NMS Documentation |[Apache.NMS-1.8.0-docs.zip](http://www.apache.org/dyn/closer.lua/activemq/apache-nms-api/1.8.0/Apache.NMS-1.8.0-docs.zip)|[Apache.NMS-1.8.0-docs.zip.asc](http://www.apache.org/dist/activemq/apache-nms-api/1.8.0/Apache.NMS-1.8.0-docs.zip.asc)|1.8.0| diff --git a/hugo/content/news/nms-amqp-01-08-01-release.md b/hugo/content/news/nms-amqp-01-08-01-release.md new file mode 100644 index 0000000000..54ccc3452e --- /dev/null +++ b/hugo/content/news/nms-amqp-01-08-01-release.md @@ -0,0 +1,6 @@ +--- +title: "Apache.NMS.AMQP 1.8.1 Release" +date: 2021-04-04 +--- + +Apache NMS.AMQP was released on . For details of the changes see the [release notes](). diff --git a/hugo/content/news/nms-amqp-01-08-02-release.md b/hugo/content/news/nms-amqp-01-08-02-release.md new file mode 100644 index 0000000000..d2bc5abe47 --- /dev/null +++ b/hugo/content/news/nms-amqp-01-08-02-release.md @@ -0,0 +1,7 @@ +--- +title: "Apache.NMS.AMQP 1.8.2 Release" +date: 2021-08-16 +description: "Bug fix release around send timeout." +--- + +Apache NMS.AMQP was released on . For details of the changes see the [release notes](). diff --git a/hugo/content/news/nms-amqp-02-00-00-release.md b/hugo/content/news/nms-amqp-02-00-00-release.md new file mode 100644 index 0000000000..c211432828 --- /dev/null +++ b/hugo/content/news/nms-amqp-02-00-00-release.md @@ -0,0 +1,7 @@ +--- +title: "Apache.NMS.AMQP 2.0.0 Release" +date: 2021-10-27 +description: "NMS 2.0 implementation." +--- + +Apache NMS.AMQP was released on . For details of the changes see the [release notes](). diff --git a/hugo/content/news/nms-amqp-02-01-00-release.md b/hugo/content/news/nms-amqp-02-01-00-release.md new file mode 100644 index 0000000000..47ddb1af75 --- /dev/null +++ b/hugo/content/news/nms-amqp-02-01-00-release.md @@ -0,0 +1,7 @@ +--- +title: "Apache.NMS.AMQP 2.1.0 Release" +date: 2023-03-21 +description: "Security enhancement for binary serialization by adding allow/deny list of types." +--- + +Apache NMS.AMQP was released on . For details of the changes see the [release notes](). diff --git a/hugo/content/news/nms-amqp-02-02-00-release.md b/hugo/content/news/nms-amqp-02-02-00-release.md new file mode 100644 index 0000000000..d20a99b28a --- /dev/null +++ b/hugo/content/news/nms-amqp-02-02-00-release.md @@ -0,0 +1,7 @@ +--- +title: "Apache.NMS.AMQP 2.2.0 Release" +date: 2023-05-14 +description: "Message acknowledgement enhancements with support for multiple AckTypes." +--- + +Apache NMS.AMQP was released on . For details of the changes see the [release notes](). diff --git a/hugo/content/news/nms-amqp-02-03-00-release.md b/hugo/content/news/nms-amqp-02-03-00-release.md new file mode 100644 index 0000000000..ff8a9dfee5 --- /dev/null +++ b/hugo/content/news/nms-amqp-02-03-00-release.md @@ -0,0 +1,7 @@ +--- +title: "Apache.NMS.AMQP 2.3.0 Release" +date: 2025-05-14 +description: "Support for asynchronous message consumption, configurable hostname/vhost in the AMQP Open frame, and includes a fix for NMSContext event handling." +--- + +Apache NMS.AMQP was released on . For details of the changes see the [release notes](). diff --git a/hugo/content/news/nms-amqp-02-04-00-release.md b/hugo/content/news/nms-amqp-02-04-00-release.md new file mode 100644 index 0000000000..b118c7e4fe --- /dev/null +++ b/hugo/content/news/nms-amqp-02-04-00-release.md @@ -0,0 +1,19 @@ +--- +title: "Apache.NMS.AMQP 2.4.0 Release" +date: 2025-08-24 +description: "New acknowledgment customization for expired messages, client-side redelivery delay, and security fix for binary serialization." +--- + +Apache NMS.AMQP was released on . +For details of the changes see the [release notes](). + +## Highlights of this release + +### New Features + +- **Custom acknowledgment for expired messages**: Introduced an option in `IRedeliveryPolicy` to control acknowledgment behavior for expired messages ([AMQNET-846](https://issues.apache.org/jira/browse/AMQNET-846)). +- **Client-side redelivery delay**: Added support for configurable redelivery delays based on the number of redelivery attempts ([AMQNET-847](https://issues.apache.org/jira/browse/AMQNET-847)). + +### Bug Fixes + +- **Serialization security**: Fixed an issue where allow and deny lists of types for binary serialization could be circumvented ([AMQNET-849](https://issues.apache.org/jira/browse/AMQNET-849)). diff --git a/hugo/content/news/nms-api-01-08-00-release.md b/hugo/content/news/nms-api-01-08-00-release.md new file mode 100644 index 0000000000..4ca80dfb48 --- /dev/null +++ b/hugo/content/news/nms-api-01-08-00-release.md @@ -0,0 +1,5 @@ +--- +title: "Apache.NMS.API 1.8.0 Release" +date: 2019-07-01 +description: "This release of the NMS API adds .net standard 2.0 support, and is the first release providing nuget packages." +--- diff --git a/hugo/content/news/nms-api-01-08-01-release.md b/hugo/content/news/nms-api-01-08-01-release.md new file mode 100644 index 0000000000..292c0fb056 --- /dev/null +++ b/hugo/content/news/nms-api-01-08-01-release.md @@ -0,0 +1,5 @@ +--- +title: "Apache.NMS.API 1.8.1 Release" +date: 2022-05-29 +description: "Maintenance release." +--- diff --git a/hugo/content/news/nms-api-02-00-00-release.md b/hugo/content/news/nms-api-02-00-00-release.md new file mode 100644 index 0000000000..316e4e8785 --- /dev/null +++ b/hugo/content/news/nms-api-02-00-00-release.md @@ -0,0 +1,5 @@ +--- +title: "Apache.NMS.API 2.0.0 Release" +date: 2021-07-03 +description: "This release brings NMS 2.0 support." +--- diff --git a/hugo/content/news/nms-api-02-01-00-release.md b/hugo/content/news/nms-api-02-01-00-release.md new file mode 100644 index 0000000000..4607650759 --- /dev/null +++ b/hugo/content/news/nms-api-02-01-00-release.md @@ -0,0 +1,5 @@ +--- +title: "Apache.NMS.API 2.1.0 Release" +date: 2023-09-24 +description: "Asynchronous consumer API" +--- diff --git a/hugo/content/news/nms-api-02-02-00-release.md b/hugo/content/news/nms-api-02-02-00-release.md new file mode 100644 index 0000000000..22d7eb49e6 --- /dev/null +++ b/hugo/content/news/nms-api-02-02-00-release.md @@ -0,0 +1,5 @@ +--- +title: "Apache.NMS.API 2.2.0 Release" +date: 2025-07-05 +description: "Adds configurable acknowledgment handling for expired messages via IRedeliveryPolicy" +--- diff --git a/hugo/data/classic_releases.yaml b/hugo/data/classic_releases.yaml new file mode 100644 index 0000000000..d8cee82fd5 --- /dev/null +++ b/hugo/data/classic_releases.yaml @@ -0,0 +1,149 @@ +current: + - series: "6.2.x" + version: "6.2.1" + date: "Feb 18th, 2026" + status: "stable" + java: "17+" + - series: "5.19.x" + version: "5.19.2" + date: "Feb 13th, 2026" + status: "stable" + java: "11+" + +series: + - series: "6.2.x" + status: "Stable - Supported" + stable: true + latest: "6.2.1" + date: "Feb 18th, 2026" + broker_jms: "Jakarta JMS 2/3.1 (partial)" + client_jms: "Jakarta JMS 2/3.1" + java: "[17,23)" + spring: "6.2.16" + logging: "Log4j 2.25.3/Slf4j 2.0.17" + web: "Jetty 11.0.26" + last: "6.2.1" + next: "6.2.2" + eta: "Apr 26" + - series: "6.1.x" + status: "Deprecated" + latest: "6.1.8" + date: "Oct 22nd, 2025" + broker_jms: "Jakarta JMS 2/3.1 (partial)" + client_jms: "Jakarta JMS 2/3.1" + java: "[17,23)" + spring: "6.1.21" + logging: "Log4j 2.25.2/Slf4j 2.0.17" + web: "Jetty 11.0.26" + last: "6.1.8" + - series: "6.0.x" + status: "Deprecated" + latest: "6.0.1" + date: "Dec 3rd, 2023" + broker_jms: "Jakarta JMS 2/3.1 (partial)" + client_jms: "Jakarta JMS 2/3.1" + java: "[17,23)" + spring: "6.0.17" + logging: "Log4j 2.22.0/Slf4j 2.0.9" + web: "Jetty 11.0.18" + last: "6.0.1" + - series: "5.19.x" + status: "Stable - Supported" + stable: true + latest: "5.19.2" + date: "Feb 13th, 2026" + broker_jms: "Javax JMS 1.1" + client_jms: "Javax JMS 1.1/Jakarta JMS 2" + java: "[11,23)" + spring: "5.3.39" + logging: "Log4j 2.25.3/Slf4j 2.0.17" + web: "Jetty 9.4.58" + last: "5.19.2" + - series: "5.18.x" + status: "Deprecated" + latest: "5.18.7" + date: "Mar 19th, 2025" + broker_jms: "Javax JMS 1.1" + client_jms: "Javax JMS 1.1/Jakarta JMS 2" + java: "[11,23)" + spring: "5.3.39" + logging: "Log4j 2.24.1/Slf4j 2.0.13" + web: "Jetty 9.4.57" + last: "5.18.7" + - series: "5.17.x" + status: "Deprecated" + latest: "5.17.7" + date: "Mar 20th, 2025" + broker_jms: "Javax JMS 1.1" + client_jms: "Javax JMS 1.1" + java: "[11,23)" + spring: "5.3.33" + logging: "Log4j 2.23.1/Slf4j 1.7.36" + web: "Jetty 9.4.54" + last: "5.17.7" + - series: "5.16.x" + status: "Deprecated" + latest: "5.16.8" + date: "Mar 22nd, 2025" + broker_jms: "Javax JMS 1.1" + client_jms: "Javax JMS 1.1" + java: "1.8" + spring: "4.3.30" + logging: "Reload4j 1.2.24/Slf4j 1.7.36" + web: "Jetty 9.4.53" + last: "5.16.8" + - series: "5.15.x" + status: "Deprecated" + latest: "5.15.16" + date: "Oct 26th, 2023" + broker_jms: "Javax JMS 1.1" + client_jms: "Javax JMS 1.1" + java: "1.8" + spring: "4.3.30" + logging: "Log4j 1.2.17/Slf4j 1.7.32" + web: "Jetty 9.4.39" + last: "5.15.16" + - series: "5.14.x" + status: "Deprecated" + latest: "5.14.5" + date: "Apr 25th, 2017" + broker_jms: "Javax JMS 1.1" + client_jms: "Javax JMS 1.1" + java: "1.7" + spring: "4.1.9" + logging: "Log4j 1.2.17/Slf4j 1.7.13" + web: "Jetty 9.2.13" + last: "5.14.5" + - series: "5.13.x" + status: "Deprecated" + latest: "5.13.5" + date: "Dec 16th, 2016" + broker_jms: "Javax JMS 1.1" + client_jms: "Javax JMS 1.1" + java: "1.7" + spring: "4.1.9" + logging: "Log4j 1.2.17/Slf4j 1.7.13" + web: "Jetty 9.2.13" + last: "5.13.5" + - series: "5.12.x" + status: "Deprecated" + latest: "5.12.3" + date: "Feb 3rd, 2016" + broker_jms: "Javax JMS 1.1" + client_jms: "Javax JMS 1.1" + java: "1.7" + spring: "3.2.16" + logging: "Log4j 1.2.17/Slf4j 1.7.10" + web: "Jetty 9.2.6" + last: "5.12.3" + - series: "5.11.x" + status: "Deprecated" + latest: "5.11.4" + date: "Feb 3rd, 2016" + broker_jms: "Javax JMS 1.1" + client_jms: "Javax JMS 1.1" + java: "1.7" + spring: "3.2.16" + logging: "Log4j 1.2.17/Slf4j 1.7.10" + web: "Jetty 9.2.6" + last: "5.11.4" diff --git a/hugo/hugo.toml b/hugo/hugo.toml new file mode 100644 index 0000000000..5d32df7649 --- /dev/null +++ b/hugo/hugo.toml @@ -0,0 +1,6 @@ +baseURL = "https://activemq.apache.org/" +languageCode = "en-us" +title = "ActiveMQ" + +[markup.goldmark.renderer] +unsafe = true diff --git a/hugo/layouts/_default/baseof.html b/hugo/layouts/_default/baseof.html new file mode 100644 index 0000000000..ad7d5c2492 --- /dev/null +++ b/hugo/layouts/_default/baseof.html @@ -0,0 +1,20 @@ + + + + + + {{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} | {{ .Site.Title }}{{ end }} + + {{ with resources.Get "css/main.css" | fingerprint }} + + {{ end }} + + + {{ partial "nav.html" . }} + {{ block "above-main" . }}{{ end }} +
    + {{ block "main" . }}{{ end }} +
    + {{ partial "footer.html" . }} + + diff --git a/hugo/layouts/_default/docs.html b/hugo/layouts/_default/docs.html new file mode 100644 index 0000000000..a54f62666a --- /dev/null +++ b/hugo/layouts/_default/docs.html @@ -0,0 +1,64 @@ +{{ define "above-main" }} +
    +
    +

    {{ .Title }}

    +
    +
    +{{ end }} + +{{ define "main" }} + + + +{{ end }} diff --git a/hugo/layouts/_default/nms-download.html b/hugo/layouts/_default/nms-download.html new file mode 100644 index 0000000000..ff60593dc7 --- /dev/null +++ b/hugo/layouts/_default/nms-download.html @@ -0,0 +1,18 @@ +{{ define "above-main" }} +
    +
    +

    {{ .Title }}

    +
    +
    +{{ end }} + +{{ define "main" }} + +
    + {{ .Content }} +
    +{{ end }} diff --git a/hugo/layouts/_default/single.html b/hugo/layouts/_default/single.html new file mode 100644 index 0000000000..49151c478f --- /dev/null +++ b/hugo/layouts/_default/single.html @@ -0,0 +1,6 @@ +{{ define "main" }} +
    +

    {{ .Title }}

    + {{ .Content }} +
    +{{ end }} diff --git a/hugo/layouts/community/single.html b/hugo/layouts/community/single.html new file mode 100644 index 0000000000..6714e6f2f1 --- /dev/null +++ b/hugo/layouts/community/single.html @@ -0,0 +1,15 @@ +{{ define "above-main" }} +
    +
    +

    {{ .Title }}

    +
    +
    +{{ end }} + +{{ define "main" }} + +{{ .Content }} +{{ end }} diff --git a/hugo/layouts/components/classic-doc.html b/hugo/layouts/components/classic-doc.html new file mode 100644 index 0000000000..460874ba83 --- /dev/null +++ b/hugo/layouts/components/classic-doc.html @@ -0,0 +1,19 @@ +{{ define "above-main" }} +
    +
    +

    {{ .Title }}

    +
    +
    +{{ end }} + +{{ define "main" }} + +
    + {{ .Content }} +
    +{{ end }} diff --git a/hugo/layouts/components/cms-page.html b/hugo/layouts/components/cms-page.html new file mode 100644 index 0000000000..c2aced0c41 --- /dev/null +++ b/hugo/layouts/components/cms-page.html @@ -0,0 +1,18 @@ +{{ define "above-main" }} +
    +
    +

    {{ .Title }}

    +
    +
    +{{ end }} + +{{ define "main" }} + +
    + {{ .Content }} +
    +{{ end }} diff --git a/hugo/layouts/components/cms.html b/hugo/layouts/components/cms.html new file mode 100644 index 0000000000..2f5689a457 --- /dev/null +++ b/hugo/layouts/components/cms.html @@ -0,0 +1,44 @@ +{{ define "above-main" }} +
    +
    +
    +

    {{ .Title }}

    + {{ with .Params.subtitle }}

    {{ . }}

    {{ end }} + +
    + +
    +
    +{{ end }} + +{{ define "main" }} + + +
    +
    +
    +

    Messaging for C++

    +

    JMS-like C++ Messaging API

    +

    The CMS API is a JMS-like API for C++ for interfacing with Message Brokers such as Apache ActiveMQ. CMS helps to make your C++ client code much neater and easier to follow. ActiveMQ-CPP is a client only library — a message broker such as Apache ActiveMQ is still needed for your clients to communicate.

    +
    +
    +
    + +
    +
    +
    +

    ActiveMQ-CPP

    +

    OpenWire and STOMP over TCP/SSL

    +

    ActiveMQ-CPP implements CMS with pluggable transports and wire formats, supporting OpenWire and STOMP protocols over TCP and SSL, including a Failover Transport for reliable client operation.

    + Read the Docs +
    +
    +
    +{{ end }} diff --git a/hugo/layouts/components/list.html b/hugo/layouts/components/list.html new file mode 100644 index 0000000000..d0cdde2db8 --- /dev/null +++ b/hugo/layouts/components/list.html @@ -0,0 +1,26 @@ +{{ define "above-main" }} +
    +
    +
    +

    {{ .Title }}

    + {{ with .Params.subtitle }}

    {{ . }}

    {{ end }} + +
    + +
    +
    +{{ end }} + +{{ define "main" }} + +
    + {{ .Content }} +
    +{{ end }} diff --git a/hugo/layouts/components/nms-download.html b/hugo/layouts/components/nms-download.html new file mode 100644 index 0000000000..ff60593dc7 --- /dev/null +++ b/hugo/layouts/components/nms-download.html @@ -0,0 +1,18 @@ +{{ define "above-main" }} +
    +
    +

    {{ .Title }}

    +
    +
    +{{ end }} + +{{ define "main" }} + +
    + {{ .Content }} +
    +{{ end }} diff --git a/hugo/layouts/components/nms.html b/hugo/layouts/components/nms.html new file mode 100644 index 0000000000..c0dc266a46 --- /dev/null +++ b/hugo/layouts/components/nms.html @@ -0,0 +1,55 @@ +{{ define "above-main" }} +
    +
    +
    +

    {{ .Title }}

    + {{ with .Params.subtitle }}

    {{ . }}

    {{ end }} + +
    + +
    +
    +{{ end }} + +{{ define "main" }} + + +
    +
    +
    +

    Messaging for .NET

    +

    Simple Messaging API for .NET

    +

    The NMS API allows you to build .NET applications in C#, VB, or any other .NET language, using a single API to connect to multiple different providers using a JMS style API.

    +
    +
    +
    + +
    +
    +
    +

    Apache.NMS.AMQP

    +

    AMQP 1.0 the ISO and OASIS Standard Messaging Protocol

    +

    Apache.NMS.AMQP provides AMQP 1.0 connectivity with .NET Standard 2.0 support, enabling connectivity to ActiveMQ 5.x, ActiveMQ Artemis and any other AMQP 1.0 compatible broker.

    + Find out more +
    +
    +
    + +
    +
    +
    +

    Apache.NMS.ActiveMQ

    +

    ActiveMQ 5.x's native OpenWire protocol

    +

    Apache.NMS.ActiveMQ provides OpenWire connectivity using ActiveMQ's native protocol, with .NET Framework support.

    + Find out more +
    +
    +
    +{{ end }} diff --git a/hugo/layouts/components/redirect.html b/hugo/layouts/components/redirect.html new file mode 100644 index 0000000000..69c34ee291 --- /dev/null +++ b/hugo/layouts/components/redirect.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/hugo/layouts/download/list.html b/hugo/layouts/download/list.html new file mode 100644 index 0000000000..75e2211fab --- /dev/null +++ b/hugo/layouts/download/list.html @@ -0,0 +1,14 @@ +{{ define "above-main" }} +
    +
    +

    {{ .Title }}

    +
    +
    +{{ end }} + +{{ define "main" }} + +{{ .Content }} +{{ end }} diff --git a/hugo/layouts/download/single.html b/hugo/layouts/download/single.html new file mode 100644 index 0000000000..75e2211fab --- /dev/null +++ b/hugo/layouts/download/single.html @@ -0,0 +1,14 @@ +{{ define "above-main" }} +
    +
    +

    {{ .Title }}

    +
    +
    +{{ end }} + +{{ define "main" }} + +{{ .Content }} +{{ end }} diff --git a/hugo/layouts/index.html b/hugo/layouts/index.html new file mode 100644 index 0000000000..22f3cf0718 --- /dev/null +++ b/hugo/layouts/index.html @@ -0,0 +1,50 @@ +{{ define "above-main" }} +
    +
    +
    +

    Flexible & Powerful Open Source
    Multi-Protocol Messaging

    + Download + Documentation +
    + +
    +
    +{{ end }} + +{{ define "main" }} +
    +

    Apache ActiveMQ® is the most popular open source, multi-protocol, Java-based message broker. It supports industry standard protocols so users get the benefits of client choices across a broad range of languages and platforms. Connect from clients written in JavaScript, C, C++, Python, .Net, and more. Integrate your multi-platform applications using the ubiquitous AMQP protocol. Exchange messages between your web applications using STOMP over websockets. Manage your IoT devices using MQTT. Support your existing JMS infrastructure and beyond.

    +
    + +
    +
    +

    ActiveMQ Classic 6.2.1 Release

    +

    ActiveMQ Classic 6.2.1 is a new milestone for the project, starting the 6.2.x series.

    + +
    +
    +

    ActiveMQ Classic 5.19.2 Release

    +

    Maintenance release on the 5.19.x series.

    + +
    +
    +

    Apache.NMS.ActiveMQ 2.2.0 Release

    +

    Dependency upgrade to Apache.NMS version 2.2.0.

    + +
    +
    + +
    +

    ActiveMQ

    +

    Long established, endlessly pluggable architecture serving many generations of applications.

    +
      +
    • Partial Jakarta Messaging 3.1 & JMS 2.0 support and full JMS 1.1 support
    • +
    • High availability using shared storage
    • +
    • Familiar JMS-based addressing model
    • +
    • Network of brokers for distributing load
    • +
    • KahaDB & JDBC options for persistence
    • +
    +
    +{{ end }} diff --git a/hugo/layouts/news/list.html b/hugo/layouts/news/list.html new file mode 100644 index 0000000000..d2a48c00b7 --- /dev/null +++ b/hugo/layouts/news/list.html @@ -0,0 +1,22 @@ +{{ define "above-main" }} +
    +
    +

    {{ .Title }}

    +
    +
    +{{ end }} + +{{ define "main" }} + + +{{ range sort .Pages "Date" "desc" }} +
    +

    {{ .Title }}

    + + {{ with .Params.description }}

    {{ . }}

    {{ end }} + Read More +
    +{{ end }} +{{ end }} diff --git a/hugo/layouts/news/single.html b/hugo/layouts/news/single.html new file mode 100644 index 0000000000..26913c364a --- /dev/null +++ b/hugo/layouts/news/single.html @@ -0,0 +1,20 @@ +{{ define "above-main" }} +
    +
    +

    {{ .Title }}

    +
    +
    +{{ end }} + +{{ define "main" }} + + +
    + + {{ .Content }} +
    +{{ end }} diff --git a/hugo/layouts/partials/footer.html b/hugo/layouts/partials/footer.html new file mode 100644 index 0000000000..b6687aac41 --- /dev/null +++ b/hugo/layouts/partials/footer.html @@ -0,0 +1,4 @@ +
    + Copyright © {{ now.Year }} The Apache Software Foundation. + Licensed under the Apache License 2.0. +
    diff --git a/hugo/layouts/partials/nav.html b/hugo/layouts/partials/nav.html new file mode 100644 index 0000000000..3eb5635084 --- /dev/null +++ b/hugo/layouts/partials/nav.html @@ -0,0 +1,28 @@ + diff --git a/hugo/scripts/import_news.py b/hugo/scripts/import_news.py new file mode 100644 index 0000000000..d60bf7c534 --- /dev/null +++ b/hugo/scripts/import_news.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +"""Convert Jekyll release collection files into Hugo news content files.""" +import os, re, glob + +SRC = os.path.join(os.path.dirname(__file__), '..', '..', 'src') +DEST = os.path.join(os.path.dirname(__file__), '..', 'content', 'news') + +COLLECTIONS = [ + '_classic_releases', + '_nms_amqp_releases', + '_nms_api_releases', + '_nms_activemq_releases', + '_nms_stomp_releases', + '_news', +] + +os.makedirs(DEST, exist_ok=True) + +def parse_frontmatter(text): + m = re.match(r'^---\n(.*?)\n---\n?(.*)', text, re.DOTALL) + if not m: + return {}, text + fm, body = {}, m.group(2).strip() + for line in m.group(1).splitlines(): + kv = re.match(r'^(\w[\w_]*):\s*(.*)', line) + if kv: + fm[kv.group(1)] = kv.group(2).strip().strip('"') + return fm, body + +converted = 0 +for collection in COLLECTIONS: + for src_path in sorted(glob.glob(os.path.join(SRC, collection, '*.md'))): + with open(src_path) as f: + text = f.read() + fm, body = parse_frontmatter(text) + + title = fm.get('title', '') + date = fm.get('release_date', fm.get('date', '')) + desc = fm.get('shortDescription', '') + + if not title or not date: + continue + + slug = os.path.splitext(os.path.basename(src_path))[0] + dest_path = os.path.join(DEST, slug + '.md') + + if os.path.exists(dest_path): + continue + + # Strip Jekyll liquid tags from body + body = re.sub(r'\{\{[^}]*\}\}', '', body) + body = re.sub(r'\{%[^%]*%\}', '', body).strip() + + with open(dest_path, 'w') as f: + f.write(f'---\ntitle: "{title}"\ndate: {date}\n') + if desc: + f.write(f'description: "{desc}"\n') + f.write('---\n') + if body: + f.write('\n' + body + '\n') + + converted += 1 + print(f' {slug}') + +print(f'\nDone: {converted} files written to {os.path.abspath(DEST)}') diff --git a/hugo/static/assets/img/ActiveMQConnections.png b/hugo/static/assets/img/ActiveMQConnections.png new file mode 100644 index 0000000000..299d4ad7c1 Binary files /dev/null and b/hugo/static/assets/img/ActiveMQConnections.png differ diff --git a/hugo/static/assets/img/ActiveMQDestinations.png b/hugo/static/assets/img/ActiveMQDestinations.png new file mode 100644 index 0000000000..8bc80a1cc6 Binary files /dev/null and b/hugo/static/assets/img/ActiveMQDestinations.png differ diff --git a/hugo/static/assets/img/Apache_PoweredBy.png b/hugo/static/assets/img/Apache_PoweredBy.png new file mode 100644 index 0000000000..931a5d57be Binary files /dev/null and b/hugo/static/assets/img/Apache_PoweredBy.png differ diff --git a/hugo/static/assets/img/BrokerDiagram.png b/hugo/static/assets/img/BrokerDiagram.png new file mode 100644 index 0000000000..245d6dd0a7 Binary files /dev/null and b/hugo/static/assets/img/BrokerDiagram.png differ diff --git a/hugo/static/assets/img/BrokerSession Library Usage.JPG b/hugo/static/assets/img/BrokerSession Library Usage.JPG new file mode 100644 index 0000000000..7bad5a2faa Binary files /dev/null and b/hugo/static/assets/img/BrokerSession Library Usage.JPG differ diff --git a/hugo/static/assets/img/BrokerTopology-1.png b/hugo/static/assets/img/BrokerTopology-1.png new file mode 100644 index 0000000000..ae82cc8b05 Binary files /dev/null and b/hugo/static/assets/img/BrokerTopology-1.png differ diff --git a/hugo/static/assets/img/Core Library Usage.JPG b/hugo/static/assets/img/Core Library Usage.JPG new file mode 100644 index 0000000000..7f9d59e0af Binary files /dev/null and b/hugo/static/assets/img/Core Library Usage.JPG differ diff --git a/hugo/static/assets/img/DispatchFastConsumers.png b/hugo/static/assets/img/DispatchFastConsumers.png new file mode 100644 index 0000000000..f05c82c102 Binary files /dev/null and b/hugo/static/assets/img/DispatchFastConsumers.png differ diff --git a/hugo/static/assets/img/DispatchSlowConsumers.png b/hugo/static/assets/img/DispatchSlowConsumers.png new file mode 100644 index 0000000000..b2172cdb56 Binary files /dev/null and b/hugo/static/assets/img/DispatchSlowConsumers.png differ diff --git a/hugo/static/assets/img/Example1-DirectoryStructure.jpg b/hugo/static/assets/img/Example1-DirectoryStructure.jpg new file mode 100644 index 0000000000..1e099383ef Binary files /dev/null and b/hugo/static/assets/img/Example1-DirectoryStructure.jpg differ diff --git a/hugo/static/assets/img/Example1-Entry.jpg b/hugo/static/assets/img/Example1-Entry.jpg new file mode 100644 index 0000000000..c2d84bbef2 Binary files /dev/null and b/hugo/static/assets/img/Example1-Entry.jpg differ diff --git a/hugo/static/assets/img/Example1-Topology.jpg b/hugo/static/assets/img/Example1-Topology.jpg new file mode 100644 index 0000000000..55b01b488c Binary files /dev/null and b/hugo/static/assets/img/Example1-Topology.jpg differ diff --git a/hugo/static/assets/img/Example2-DirectoryStructure.jpg b/hugo/static/assets/img/Example2-DirectoryStructure.jpg new file mode 100644 index 0000000000..e241e37113 Binary files /dev/null and b/hugo/static/assets/img/Example2-DirectoryStructure.jpg differ diff --git a/hugo/static/assets/img/Example2-Topology.jpg b/hugo/static/assets/img/Example2-Topology.jpg new file mode 100644 index 0000000000..9ac6acf9d0 Binary files /dev/null and b/hugo/static/assets/img/Example2-Topology.jpg differ diff --git a/hugo/static/assets/img/FileCursor.png b/hugo/static/assets/img/FileCursor.png new file mode 100644 index 0000000000..6fb0113be8 Binary files /dev/null and b/hugo/static/assets/img/FileCursor.png differ diff --git a/hugo/static/assets/img/MasterFailed.png b/hugo/static/assets/img/MasterFailed.png new file mode 100644 index 0000000000..7455f5ae45 Binary files /dev/null and b/hugo/static/assets/img/MasterFailed.png differ diff --git a/hugo/static/assets/img/MasterRestarted.png b/hugo/static/assets/img/MasterRestarted.png new file mode 100644 index 0000000000..b779d6907d Binary files /dev/null and b/hugo/static/assets/img/MasterRestarted.png differ diff --git a/hugo/static/assets/img/NonPersistentMsgs.png b/hugo/static/assets/img/NonPersistentMsgs.png new file mode 100644 index 0000000000..9cbe7b068c Binary files /dev/null and b/hugo/static/assets/img/NonPersistentMsgs.png differ diff --git a/hugo/static/assets/img/Startup.png b/hugo/static/assets/img/Startup.png new file mode 100644 index 0000000000..682c63b55e Binary files /dev/null and b/hugo/static/assets/img/Startup.png differ diff --git a/hugo/static/assets/img/VMCursor.png b/hugo/static/assets/img/VMCursor.png new file mode 100644 index 0000000000..70a393e1f4 Binary files /dev/null and b/hugo/static/assets/img/VMCursor.png differ diff --git a/hugo/static/assets/img/activemq-in-weblogic.png b/hugo/static/assets/img/activemq-in-weblogic.png new file mode 100644 index 0000000000..a7d13016ea Binary files /dev/null and b/hugo/static/assets/img/activemq-in-weblogic.png differ diff --git a/hugo/static/assets/img/activemq-jmx.png b/hugo/static/assets/img/activemq-jmx.png new file mode 100644 index 0000000000..29ac6e53ae Binary files /dev/null and b/hugo/static/assets/img/activemq-jmx.png differ diff --git a/hugo/static/assets/img/activemq_colour_pallette.png b/hugo/static/assets/img/activemq_colour_pallette.png new file mode 100644 index 0000000000..a74b45ce3d Binary files /dev/null and b/hugo/static/assets/img/activemq_colour_pallette.png differ diff --git a/hugo/static/assets/img/activemq_desktop_background_black.png b/hugo/static/assets/img/activemq_desktop_background_black.png new file mode 100644 index 0000000000..77d6207aa6 Binary files /dev/null and b/hugo/static/assets/img/activemq_desktop_background_black.png differ diff --git a/hugo/static/assets/img/activemq_desktop_background_black_logo.png b/hugo/static/assets/img/activemq_desktop_background_black_logo.png new file mode 100644 index 0000000000..10a6d4cba4 Binary files /dev/null and b/hugo/static/assets/img/activemq_desktop_background_black_logo.png differ diff --git a/hugo/static/assets/img/activemq_desktop_background_dark_grey.png b/hugo/static/assets/img/activemq_desktop_background_dark_grey.png new file mode 100644 index 0000000000..39bcaca2c2 Binary files /dev/null and b/hugo/static/assets/img/activemq_desktop_background_dark_grey.png differ diff --git a/hugo/static/assets/img/activemq_desktop_background_white.png b/hugo/static/assets/img/activemq_desktop_background_white.png new file mode 100644 index 0000000000..3c780130a3 Binary files /dev/null and b/hugo/static/assets/img/activemq_desktop_background_white.png differ diff --git a/hugo/static/assets/img/activemq_desktop_background_white_logo.png b/hugo/static/assets/img/activemq_desktop_background_white_logo.png new file mode 100644 index 0000000000..259a7f2efc Binary files /dev/null and b/hugo/static/assets/img/activemq_desktop_background_white_logo.png differ diff --git a/hugo/static/assets/img/activemq_logo_black.png b/hugo/static/assets/img/activemq_logo_black.png new file mode 100644 index 0000000000..76b344d65c Binary files /dev/null and b/hugo/static/assets/img/activemq_logo_black.png differ diff --git a/hugo/static/assets/img/activemq_logo_black.svg b/hugo/static/assets/img/activemq_logo_black.svg new file mode 100644 index 0000000000..fff87cc1fd --- /dev/null +++ b/hugo/static/assets/img/activemq_logo_black.svg @@ -0,0 +1,433 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ACTIVE + APACHE + MQ + ® + + + + + + diff --git a/hugo/static/assets/img/activemq_logo_black_small.png b/hugo/static/assets/img/activemq_logo_black_small.png new file mode 100644 index 0000000000..808a32e9f9 Binary files /dev/null and b/hugo/static/assets/img/activemq_logo_black_small.png differ diff --git a/hugo/static/assets/img/activemq_logo_icon.png b/hugo/static/assets/img/activemq_logo_icon.png new file mode 100644 index 0000000000..c2b43f5207 Binary files /dev/null and b/hugo/static/assets/img/activemq_logo_icon.png differ diff --git a/hugo/static/assets/img/activemq_logo_icon.svg b/hugo/static/assets/img/activemq_logo_icon.svg new file mode 100644 index 0000000000..fbb462a39e --- /dev/null +++ b/hugo/static/assets/img/activemq_logo_icon.svg @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hugo/static/assets/img/activemq_logo_icon_border.png b/hugo/static/assets/img/activemq_logo_icon_border.png new file mode 100644 index 0000000000..b1cf97e3b8 Binary files /dev/null and b/hugo/static/assets/img/activemq_logo_icon_border.png differ diff --git a/hugo/static/assets/img/activemq_logo_white.svg b/hugo/static/assets/img/activemq_logo_white.svg new file mode 100644 index 0000000000..b1b67af3ab --- /dev/null +++ b/hugo/static/assets/img/activemq_logo_white.svg @@ -0,0 +1,433 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ACTIVE + APACHE + MQ + ® + + + + + + diff --git a/hugo/static/assets/img/activemq_logo_white_vertical.png b/hugo/static/assets/img/activemq_logo_white_vertical.png new file mode 100644 index 0000000000..d09cbe8255 Binary files /dev/null and b/hugo/static/assets/img/activemq_logo_white_vertical.png differ diff --git a/hugo/static/assets/img/activemq_logo_white_vertical.svg b/hugo/static/assets/img/activemq_logo_white_vertical.svg new file mode 100644 index 0000000000..6c8c16f183 --- /dev/null +++ b/hugo/static/assets/img/activemq_logo_white_vertical.svg @@ -0,0 +1,497 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ACTIVE + APACHE + MQ + ® + + + + + + diff --git a/hugo/static/assets/img/activemq_logo_white_vertical_small.png b/hugo/static/assets/img/activemq_logo_white_vertical_small.png new file mode 100644 index 0000000000..47eccb13df Binary files /dev/null and b/hugo/static/assets/img/activemq_logo_white_vertical_small.png differ diff --git a/hugo/static/assets/img/amqdir.png b/hugo/static/assets/img/amqdir.png new file mode 100644 index 0000000000..0635bc4455 Binary files /dev/null and b/hugo/static/assets/img/amqdir.png differ diff --git a/hugo/static/assets/img/amqp.png b/hugo/static/assets/img/amqp.png new file mode 100644 index 0000000000..aa40ddbfa4 Binary files /dev/null and b/hugo/static/assets/img/amqp.png differ diff --git a/hugo/static/assets/img/amqstore.png b/hugo/static/assets/img/amqstore.png new file mode 100644 index 0000000000..a372e176a5 Binary files /dev/null and b/hugo/static/assets/img/amqstore.png differ diff --git a/hugo/static/assets/img/apache-feather.png b/hugo/static/assets/img/apache-feather.png new file mode 100644 index 0000000000..744b8d7b82 Binary files /dev/null and b/hugo/static/assets/img/apache-feather.png differ diff --git a/hugo/static/assets/img/asf_logo_wide.png b/hugo/static/assets/img/asf_logo_wide.png new file mode 100644 index 0000000000..71964ba2b4 Binary files /dev/null and b/hugo/static/assets/img/asf_logo_wide.png differ diff --git a/hugo/static/assets/img/check.png b/hugo/static/assets/img/check.png new file mode 100644 index 0000000000..7bbc809a5a Binary files /dev/null and b/hugo/static/assets/img/check.png differ diff --git a/hugo/static/assets/img/competing-consumers.png b/hugo/static/assets/img/competing-consumers.png new file mode 100644 index 0000000000..8478889363 Binary files /dev/null and b/hugo/static/assets/img/competing-consumers.png differ diff --git a/hugo/static/assets/img/core.png b/hugo/static/assets/img/core.png new file mode 100644 index 0000000000..ac2cc0387f Binary files /dev/null and b/hugo/static/assets/img/core.png differ diff --git a/hugo/static/assets/img/customers/ThomsonReuters_Logo.png b/hugo/static/assets/img/customers/ThomsonReuters_Logo.png new file mode 100644 index 0000000000..a97b95e61a Binary files /dev/null and b/hugo/static/assets/img/customers/ThomsonReuters_Logo.png differ diff --git a/hugo/static/assets/img/customers/UBS-LOGO-WHITE.png b/hugo/static/assets/img/customers/UBS-LOGO-WHITE.png new file mode 100644 index 0000000000..20e1f82e72 Binary files /dev/null and b/hugo/static/assets/img/customers/UBS-LOGO-WHITE.png differ diff --git a/hugo/static/assets/img/customers/betfair-logo-large-white.png b/hugo/static/assets/img/customers/betfair-logo-large-white.png new file mode 100644 index 0000000000..44fcaa9e13 Binary files /dev/null and b/hugo/static/assets/img/customers/betfair-logo-large-white.png differ diff --git a/hugo/static/assets/img/customers/bosch-938-logo-png-transparent.png b/hugo/static/assets/img/customers/bosch-938-logo-png-transparent.png new file mode 100644 index 0000000000..c51510947b Binary files /dev/null and b/hugo/static/assets/img/customers/bosch-938-logo-png-transparent.png differ diff --git a/hugo/static/assets/img/customers/cmcmarkets.png b/hugo/static/assets/img/customers/cmcmarkets.png new file mode 100644 index 0000000000..43d179b3ec Binary files /dev/null and b/hugo/static/assets/img/customers/cmcmarkets.png differ diff --git a/hugo/static/assets/img/customers/company-logo.png b/hugo/static/assets/img/customers/company-logo.png new file mode 100644 index 0000000000..4024a93178 Binary files /dev/null and b/hugo/static/assets/img/customers/company-logo.png differ diff --git a/hugo/static/assets/img/customers/creditsuisse.png b/hugo/static/assets/img/customers/creditsuisse.png new file mode 100644 index 0000000000..af56044498 Binary files /dev/null and b/hugo/static/assets/img/customers/creditsuisse.png differ diff --git a/hugo/static/assets/img/customers/dominoes.png b/hugo/static/assets/img/customers/dominoes.png new file mode 100644 index 0000000000..c469e8769c Binary files /dev/null and b/hugo/static/assets/img/customers/dominoes.png differ diff --git a/hugo/static/assets/img/customers/ge.png b/hugo/static/assets/img/customers/ge.png new file mode 100644 index 0000000000..d88c3ce4b7 Binary files /dev/null and b/hugo/static/assets/img/customers/ge.png differ diff --git a/hugo/static/assets/img/customers/igindex.png b/hugo/static/assets/img/customers/igindex.png new file mode 100644 index 0000000000..b4f01e09be Binary files /dev/null and b/hugo/static/assets/img/customers/igindex.png differ diff --git a/hugo/static/assets/img/customers/logo-aws-white.png b/hugo/static/assets/img/customers/logo-aws-white.png new file mode 100644 index 0000000000..6c8b58e64e Binary files /dev/null and b/hugo/static/assets/img/customers/logo-aws-white.png differ diff --git a/hugo/static/assets/img/customers/redhatlogo.png b/hugo/static/assets/img/customers/redhatlogo.png new file mode 100644 index 0000000000..8a87503b45 Binary files /dev/null and b/hugo/static/assets/img/customers/redhatlogo.png differ diff --git a/hugo/static/assets/img/customers/savoir.png b/hugo/static/assets/img/customers/savoir.png new file mode 100644 index 0000000000..cd7045819d Binary files /dev/null and b/hugo/static/assets/img/customers/savoir.png differ diff --git a/hugo/static/assets/img/customers/wildfly_white.png b/hugo/static/assets/img/customers/wildfly_white.png new file mode 100644 index 0000000000..ca0673767e Binary files /dev/null and b/hugo/static/assets/img/customers/wildfly_white.png differ diff --git a/hugo/static/assets/img/error.png b/hugo/static/assets/img/error.png new file mode 100644 index 0000000000..b73a36c108 Binary files /dev/null and b/hugo/static/assets/img/error.png differ diff --git a/hugo/static/assets/img/example-diagram.png b/hugo/static/assets/img/example-diagram.png new file mode 100644 index 0000000000..7a644741ec Binary files /dev/null and b/hugo/static/assets/img/example-diagram.png differ diff --git a/hugo/static/assets/img/favicon.png b/hugo/static/assets/img/favicon.png new file mode 100644 index 0000000000..21367c2372 Binary files /dev/null and b/hugo/static/assets/img/favicon.png differ diff --git a/hugo/static/assets/img/features/ha-replicated.png b/hugo/static/assets/img/features/ha-replicated.png new file mode 100644 index 0000000000..ef9648b296 Binary files /dev/null and b/hugo/static/assets/img/features/ha-replicated.png differ diff --git a/hugo/static/assets/img/features/protocol-translation.png b/hugo/static/assets/img/features/protocol-translation.png new file mode 100644 index 0000000000..d95c9cba33 Binary files /dev/null and b/hugo/static/assets/img/features/protocol-translation.png differ diff --git a/hugo/static/assets/img/features/protocols.png b/hugo/static/assets/img/features/protocols.png new file mode 100644 index 0000000000..3db8e81b2a Binary files /dev/null and b/hugo/static/assets/img/features/protocols.png differ diff --git a/hugo/static/assets/img/help.png b/hugo/static/assets/img/help.png new file mode 100644 index 0000000000..c3c4f63d8c Binary files /dev/null and b/hugo/static/assets/img/help.png differ diff --git a/hugo/static/assets/img/mqtt.png b/hugo/static/assets/img/mqtt.png new file mode 100644 index 0000000000..f499604854 Binary files /dev/null and b/hugo/static/assets/img/mqtt.png differ diff --git a/hugo/static/assets/img/nav-logo.png b/hugo/static/assets/img/nav-logo.png new file mode 100644 index 0000000000..7bbedd09b7 Binary files /dev/null and b/hugo/static/assets/img/nav-logo.png differ diff --git a/hugo/static/assets/img/openwire.png b/hugo/static/assets/img/openwire.png new file mode 100644 index 0000000000..fb7cae74d9 Binary files /dev/null and b/hugo/static/assets/img/openwire.png differ diff --git a/hugo/static/assets/img/reloadLog4jProperties1.png b/hugo/static/assets/img/reloadLog4jProperties1.png new file mode 100644 index 0000000000..c1e27b672d Binary files /dev/null and b/hugo/static/assets/img/reloadLog4jProperties1.png differ diff --git a/hugo/static/assets/img/reloadLog4jProperties2.png b/hugo/static/assets/img/reloadLog4jProperties2.png new file mode 100644 index 0000000000..35de1d4a6f Binary files /dev/null and b/hugo/static/assets/img/reloadLog4jProperties2.png differ diff --git a/hugo/static/assets/img/replicated-leveldb-store.png b/hugo/static/assets/img/replicated-leveldb-store.png new file mode 100644 index 0000000000..560244994b Binary files /dev/null and b/hugo/static/assets/img/replicated-leveldb-store.png differ diff --git a/hugo/static/assets/img/rest.png b/hugo/static/assets/img/rest.png new file mode 100644 index 0000000000..6426dda171 Binary files /dev/null and b/hugo/static/assets/img/rest.png differ diff --git a/hugo/static/assets/img/step1.png b/hugo/static/assets/img/step1.png new file mode 100644 index 0000000000..04a60f5d87 Binary files /dev/null and b/hugo/static/assets/img/step1.png differ diff --git a/hugo/static/assets/img/step2.png b/hugo/static/assets/img/step2.png new file mode 100644 index 0000000000..1649c73655 Binary files /dev/null and b/hugo/static/assets/img/step2.png differ diff --git a/hugo/static/assets/img/step3.png b/hugo/static/assets/img/step3.png new file mode 100644 index 0000000000..e7d22a81e4 Binary files /dev/null and b/hugo/static/assets/img/step3.png differ diff --git a/hugo/static/assets/img/step4.png b/hugo/static/assets/img/step4.png new file mode 100644 index 0000000000..f5e0caca2d Binary files /dev/null and b/hugo/static/assets/img/step4.png differ diff --git a/hugo/static/assets/img/step5.png b/hugo/static/assets/img/step5.png new file mode 100644 index 0000000000..a4675af42c Binary files /dev/null and b/hugo/static/assets/img/step5.png differ diff --git a/hugo/static/assets/img/step6-new.png b/hugo/static/assets/img/step6-new.png new file mode 100644 index 0000000000..0ccc1c5763 Binary files /dev/null and b/hugo/static/assets/img/step6-new.png differ diff --git a/hugo/static/assets/img/step7-new.png b/hugo/static/assets/img/step7-new.png new file mode 100644 index 0000000000..8375886d47 Binary files /dev/null and b/hugo/static/assets/img/step7-new.png differ diff --git a/hugo/static/assets/img/step8.png b/hugo/static/assets/img/step8.png new file mode 100644 index 0000000000..620beb280e Binary files /dev/null and b/hugo/static/assets/img/step8.png differ diff --git a/hugo/static/assets/img/stomp.png b/hugo/static/assets/img/stomp.png new file mode 100644 index 0000000000..1f6485f3d7 Binary files /dev/null and b/hugo/static/assets/img/stomp.png differ diff --git a/hugo/static/assets/img/warning.png b/hugo/static/assets/img/warning.png new file mode 100644 index 0000000000..17cd4b1dfd Binary files /dev/null and b/hugo/static/assets/img/warning.png differ diff --git a/hugo/static/assets/img/web_console.png b/hugo/static/assets/img/web_console.png new file mode 100644 index 0000000000..97e89cc8f8 Binary files /dev/null and b/hugo/static/assets/img/web_console.png differ diff --git a/hugo/static/assets/img/yklogo.png b/hugo/static/assets/img/yklogo.png new file mode 100644 index 0000000000..dccf574320 Binary files /dev/null and b/hugo/static/assets/img/yklogo.png differ