first commit

This commit is contained in:
lnk
2026-07-10 14:13:02 +08:00
commit b61388443f
459 changed files with 143602 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
BasedOnStyle: Chromium
ColumnLimit: 120
TabWidth: 2

View File

@@ -0,0 +1,48 @@
---
name: ISSUE_TEMPLATE
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
The issue tracker is **ONLY** used for the CPP/C client (feature request of RocketMQ need to follow [RIP process](https://github.com/apache/rocketmq/wiki/RocketMQ-Improvement-Proposal)). Keep in mind, please check whether there is an existing same report before your raise a new one.
Alternately (especially if your communication is not a bug report), you can send mail to our [mailing lists](http://rocketmq.apache.org/about/contact/). We welcome any friendly suggestions, bug fixes, collaboration, and other improvements.
Please ensure that your bug report is clear and that it is complete. Otherwise, we may be unable to understand it or to reproduce it, either of which would prevent us from fixing the bug. We strongly recommend the report(bug report or feature request) could include some hints as to the following:
**BUG REPORT**
1. Please describe the issue you observed:
- What did you do (The steps to reproduce)?
- What did you expect to see?
- What did you see instead?
2. Please tell us about your environment:
- What is your OS?
- What is your client version?
- What is your RocketMQ version?
3. Other information (e.g. detailed explanation, logs, related issues, suggestions on how to fix, etc):
**FEATURE REQUEST**
1. Please describe the feature you are requesting.
2. Provide any additional detail on your proposed use case for this feature.
2. Indicate the importance of this issue to you (blocker, must-have, should-have, nice-to-have). Are you currently using any workarounds to address this issue?
4. If there are some sub-tasks using -[] for each subtask and create a corresponding issue to map to the sub task:
- [sub-task1-issue-number](example_sub_issue1_link_here): sub-task1 description here,
- [sub-task2-issue-number](example_sub_issue2_link_here): sub-task2 description here,
- ...

View File

@@ -0,0 +1,8 @@
.idea
cmake-build-debug/
bin
build
libs/signature/lib
tmp_*
Testing
.vscode

View File

@@ -0,0 +1,59 @@
language: cpp
sudo: required
dist: trusty
addons:
apt:
packages: lcov
install:
- sudo apt-get update
- sudo apt-get install -y git gcc-4.8 g++-4.8 autoconf cmake libtool wget unzip libbz2-dev zlib1g-dev
- echo 'MAVEN_OPTS="$MAVEN_OPTS -Xmx1024m -XX:MaxPermSize=512m -XX:+BytecodeVerificationLocal"' >> ~/.mavenrc
- cat ~/.mavenrc
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then export JAVA_HOME=$(/usr/libexec/java_home); fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then jdk_switcher use "$CUSTOM_JDK"; fi
before_script:
- wget https://archive.apache.org/dist/rocketmq/4.3.2/rocketmq-all-4.3.2-bin-release.zip
- unzip rocketmq-all-4.3.2-bin-release.zip
- cd rocketmq-all-4.3.2-bin-release
- perl -i -pe's/-Xms8g -Xmx8g -Xmn4g/-Xms2g -Xmx2g -Xmn1g/g' bin/runbroker.sh
- nohup sh bin/mqnamesrv &
- nohup sh bin/mqbroker -n localhost:9876 &
- sleep 10
- ./bin/mqadmin updateTopic -b '127.0.0.1:10911' n '127.0.0.1:9876' -t test
- ./bin/mqadmin updateSubGroup -b '127.0.0.1:10911' n '127.0.0.1:9876' -g testGroup
- cd ..
script:
- ./build.sh test codecov noVerbose
after_success:
# Create lcov report
# capture coverage info
- lcov --directory . --capture --output-file coverage.info
# filter out system and extra files.
# To also not include test code in coverage add them with full path to the patterns: '*/tests/*'
- lcov --remove coverage.info '/usr/*' '/home/travis/build/*/rocketmq-client-cpp/bin/*' '/home/travis/build/*/rocketmq-client-cpp/libs/*' --output-file coverage.info
# output coverage data for debugging (optional)
- lcov --list coverage.info
# Uploading to CodeCov
# '-f' specifies file(s) to use and disables manual coverage gathering and file search which has already been done above
- bash <(curl -s https://codecov.io/bash) -f coverage.info || echo "Codecov did not collect coverage reports"
matrix:
include:
- os: linux
env: CUSTOM_JDK="oraclejdk8"
# This is the job to check code format.
- os: linux
dist: trusty
env: LINT=1 PYTHON=2.7
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq clang-format-3.8
install: []
script:
- sudo sh .travis/check-git-clang-format.sh

View File

@@ -0,0 +1,32 @@
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#!/bin/bash
if [ "$TRAVIS_PULL_REQUEST" = "true" ]; then
base_commit="$TRAVIS_BRANCH"
else
base_commit="HEAD^"
fi
output="$(sudo python .travis/git-clang-format --binary clang-format-3.8 --commit $base_commit --diff)"
if [ "$output" = "no modified files to format" ] || [ "$output" = "clang-format did not modify any files" ]; then
echo "clang-format passed."
exit 0
else
echo "clang-format failed."
echo "$output"
exit 1
fi

View File

@@ -0,0 +1,490 @@
#!/usr/bin/env python
#
#===- git-clang-format - ClangFormat Git Integration ---------*- python -*--===#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#
r"""
clang-format git integration
============================
This file provides a clang-format integration for git. Put it somewhere in your
path and ensure that it is executable. Then, "git clang-format" will invoke
clang-format on the changes in current files or a specific commit.
For further details, run:
git clang-format -h
Requires Python 2.7
"""
import argparse
import collections
import contextlib
import errno
import os
import re
import subprocess
import sys
usage = 'git clang-format [OPTIONS] [<commit>] [--] [<file>...]'
desc = '''
Run clang-format on all lines that differ between the working directory
and <commit>, which defaults to HEAD. Changes are only applied to the working
directory.
The following git-config settings set the default of the corresponding option:
clangFormat.binary
clangFormat.commit
clangFormat.extension
clangFormat.style
'''
# Name of the temporary index file in which save the output of clang-format.
# This file is created within the .git directory.
temp_index_basename = 'clang-format-index'
Range = collections.namedtuple('Range', 'start, count')
def main():
config = load_git_config()
# In order to keep '--' yet allow options after positionals, we need to
# check for '--' ourselves. (Setting nargs='*' throws away the '--', while
# nargs=argparse.REMAINDER disallows options after positionals.)
argv = sys.argv[1:]
try:
idx = argv.index('--')
except ValueError:
dash_dash = []
else:
dash_dash = argv[idx:]
argv = argv[:idx]
default_extensions = ','.join([
# From clang/lib/Frontend/FrontendOptions.cpp, all lower case
'c', 'h', # C
'm', # ObjC
'mm', # ObjC++
'cc', 'cp', 'cpp', 'c++', 'cxx', 'hpp', # C++
# Other languages that clang-format supports
'proto', 'protodevel', # Protocol Buffers
'js', # JavaScript
'ts', # TypeScript
])
p = argparse.ArgumentParser(
usage=usage, formatter_class=argparse.RawDescriptionHelpFormatter,
description=desc)
p.add_argument('--binary',
default=config.get('clangformat.binary', 'clang-format'),
help='path to clang-format'),
p.add_argument('--commit',
default=config.get('clangformat.commit', 'HEAD'),
help='default commit to use if none is specified'),
p.add_argument('--diff', action='store_true',
help='print a diff instead of applying the changes')
p.add_argument('--extensions',
default=config.get('clangformat.extensions',
default_extensions),
help=('comma-separated list of file extensions to format, '
'excluding the period and case-insensitive')),
p.add_argument('--exclude', help='Exclude files matching this regex.')
p.add_argument('-f', '--force', action='store_true',
help='allow changes to unstaged files')
p.add_argument('-p', '--patch', action='store_true',
help='select hunks interactively')
p.add_argument('-q', '--quiet', action='count', default=0,
help='print less information')
p.add_argument('--style',
default=config.get('clangformat.style', None),
help='passed to clang-format'),
p.add_argument('-v', '--verbose', action='count', default=0,
help='print extra information')
# We gather all the remaining positional arguments into 'args' since we need
# to use some heuristics to determine whether or not <commit> was present.
# However, to print pretty messages, we make use of metavar and help.
p.add_argument('args', nargs='*', metavar='<commit>',
help='revision from which to compute the diff')
p.add_argument('ignored', nargs='*', metavar='<file>...',
help='if specified, only consider differences in these files')
opts = p.parse_args(argv)
opts.verbose -= opts.quiet
del opts.quiet
commit, files = interpret_args(opts.args, dash_dash, opts.commit)
changed_lines = compute_diff_and_extract_lines(commit, files)
if opts.verbose >= 1:
ignored_files = set(changed_lines)
filter_by_extension(changed_lines, opts.extensions.lower().split(','))
if opts.exclude:
for filename in changed_lines.keys():
if re.match(opts.exclude, filename):
del changed_lines[filename]
if opts.verbose >= 1:
ignored_files.difference_update(changed_lines)
if ignored_files:
print 'Ignoring changes in the following files:'
for filename in ignored_files:
print ' ', filename
if changed_lines:
print 'Running clang-format on the following files:'
for filename in changed_lines:
print ' ', filename
if not changed_lines:
print 'no modified files to format'
return
# The computed diff outputs absolute paths, so we must cd before accessing
# those files.
cd_to_toplevel()
old_tree = create_tree_from_workdir(changed_lines)
new_tree = run_clang_format_and_save_to_tree(changed_lines,
binary=opts.binary,
style=opts.style)
if opts.verbose >= 1:
print 'old tree:', old_tree
print 'new tree:', new_tree
if old_tree == new_tree:
if opts.verbose >= 0:
print 'clang-format did not modify any files'
elif opts.diff:
print_diff(old_tree, new_tree)
else:
changed_files = apply_changes(old_tree, new_tree, force=opts.force,
patch_mode=opts.patch)
if (opts.verbose >= 0 and not opts.patch) or opts.verbose >= 1:
print 'changed files:'
for filename in changed_files:
print ' ', filename
def load_git_config(non_string_options=None):
"""Return the git configuration as a dictionary.
All options are assumed to be strings unless in `non_string_options`, in which
is a dictionary mapping option name (in lower case) to either "--bool" or
"--int"."""
if non_string_options is None:
non_string_options = {}
out = {}
for entry in run('git', 'config', '--list', '--null').split('\0'):
if entry:
name, value = entry.split('\n', 1)
if name in non_string_options:
value = run('git', 'config', non_string_options[name], name)
out[name] = value
return out
def interpret_args(args, dash_dash, default_commit):
"""Interpret `args` as "[commit] [--] [files...]" and return (commit, files).
It is assumed that "--" and everything that follows has been removed from
args and placed in `dash_dash`.
If "--" is present (i.e., `dash_dash` is non-empty), the argument to its
left (if present) is taken as commit. Otherwise, the first argument is
checked if it is a commit or a file. If commit is not given,
`default_commit` is used."""
if dash_dash:
if len(args) == 0:
commit = default_commit
elif len(args) > 1:
die('at most one commit allowed; %d given' % len(args))
else:
commit = args[0]
object_type = get_object_type(commit)
if object_type not in ('commit', 'tag'):
if object_type is None:
die("'%s' is not a commit" % commit)
else:
die("'%s' is a %s, but a commit was expected" % (commit, object_type))
files = dash_dash[1:]
elif args:
if disambiguate_revision(args[0]):
commit = args[0]
files = args[1:]
else:
commit = default_commit
files = args
else:
commit = default_commit
files = []
return commit, files
def disambiguate_revision(value):
"""Returns True if `value` is a revision, False if it is a file, or dies."""
# If `value` is ambiguous (neither a commit nor a file), the following
# command will die with an appropriate error message.
run('git', 'rev-parse', value, verbose=False)
object_type = get_object_type(value)
if object_type is None:
return False
if object_type in ('commit', 'tag'):
return True
die('`%s` is a %s, but a commit or filename was expected' %
(value, object_type))
def get_object_type(value):
"""Returns a string description of an object's type, or None if it is not
a valid git object."""
cmd = ['git', 'cat-file', '-t', value]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
return None
return stdout.strip()
def compute_diff_and_extract_lines(commit, files):
"""Calls compute_diff() followed by extract_lines()."""
diff_process = compute_diff(commit, files)
changed_lines = extract_lines(diff_process.stdout)
diff_process.stdout.close()
diff_process.wait()
if diff_process.returncode != 0:
# Assume error was already printed to stderr.
sys.exit(2)
return changed_lines
def compute_diff(commit, files):
"""Return a subprocess object producing the diff from `commit`.
The return value's `stdin` file object will produce a patch with the
differences between the working directory and `commit`, filtered on `files`
(if non-empty). Zero context lines are used in the patch."""
cmd = ['git', 'diff-index', '-p', '-U0', commit, '--']
cmd.extend(files)
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p.stdin.close()
return p
def extract_lines(patch_file):
"""Extract the changed lines in `patch_file`.
The return value is a dictionary mapping filename to a list of (start_line,
line_count) pairs.
The input must have been produced with ``-U0``, meaning unidiff format with
zero lines of context. The return value is a dict mapping filename to a
list of line `Range`s."""
matches = {}
for line in patch_file:
match = re.search(r'^\+\+\+\ [^/]+/(.*)', line)
if match:
filename = match.group(1).rstrip('\r\n')
match = re.search(r'^@@ -[0-9,]+ \+(\d+)(,(\d+))?', line)
if match:
start_line = int(match.group(1))
line_count = 1
if match.group(3):
line_count = int(match.group(3))
if line_count > 0:
matches.setdefault(filename, []).append(Range(start_line, line_count))
return matches
def filter_by_extension(dictionary, allowed_extensions):
"""Delete every key in `dictionary` that doesn't have an allowed extension.
`allowed_extensions` must be a collection of lowercase file extensions,
excluding the period."""
allowed_extensions = frozenset(allowed_extensions)
for filename in dictionary.keys():
base_ext = filename.rsplit('.', 1)
if len(base_ext) == 1 or base_ext[1].lower() not in allowed_extensions:
del dictionary[filename]
def cd_to_toplevel():
"""Change to the top level of the git repository."""
toplevel = run('git', 'rev-parse', '--show-toplevel')
os.chdir(toplevel)
def create_tree_from_workdir(filenames):
"""Create a new git tree with the given files from the working directory.
Returns the object ID (SHA-1) of the created tree."""
return create_tree(filenames, '--stdin')
def run_clang_format_and_save_to_tree(changed_lines, binary='clang-format',
style=None):
"""Run clang-format on each file and save the result to a git tree.
Returns the object ID (SHA-1) of the created tree."""
def index_info_generator():
for filename, line_ranges in changed_lines.iteritems():
mode = oct(os.stat(filename).st_mode)
blob_id = clang_format_to_blob(filename, line_ranges, binary=binary,
style=style)
yield '%s %s\t%s' % (mode, blob_id, filename)
return create_tree(index_info_generator(), '--index-info')
def create_tree(input_lines, mode):
"""Create a tree object from the given input.
If mode is '--stdin', it must be a list of filenames. If mode is
'--index-info' is must be a list of values suitable for "git update-index
--index-info", such as "<mode> <SP> <sha1> <TAB> <filename>". Any other mode
is invalid."""
assert mode in ('--stdin', '--index-info')
cmd = ['git', 'update-index', '--add', '-z', mode]
with temporary_index_file():
p = subprocess.Popen(cmd, stdin=subprocess.PIPE)
for line in input_lines:
p.stdin.write('%s\0' % line)
p.stdin.close()
if p.wait() != 0:
die('`%s` failed' % ' '.join(cmd))
tree_id = run('git', 'write-tree')
return tree_id
def clang_format_to_blob(filename, line_ranges, binary='clang-format',
style=None):
"""Run clang-format on the given file and save the result to a git blob.
Returns the object ID (SHA-1) of the created blob."""
clang_format_cmd = [binary, filename]
if style:
clang_format_cmd.extend(['-style='+style])
clang_format_cmd.extend([
'-lines=%s:%s' % (start_line, start_line+line_count-1)
for start_line, line_count in line_ranges])
try:
clang_format = subprocess.Popen(clang_format_cmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
except OSError as e:
if e.errno == errno.ENOENT:
die('cannot find executable "%s"' % binary)
else:
raise
clang_format.stdin.close()
hash_object_cmd = ['git', 'hash-object', '-w', '--path='+filename, '--stdin']
hash_object = subprocess.Popen(hash_object_cmd, stdin=clang_format.stdout,
stdout=subprocess.PIPE)
clang_format.stdout.close()
stdout = hash_object.communicate()[0]
if hash_object.returncode != 0:
die('`%s` failed' % ' '.join(hash_object_cmd))
if clang_format.wait() != 0:
die('`%s` failed' % ' '.join(clang_format_cmd))
return stdout.rstrip('\r\n')
@contextlib.contextmanager
def temporary_index_file(tree=None):
"""Context manager for setting GIT_INDEX_FILE to a temporary file and deleting
the file afterward."""
index_path = create_temporary_index(tree)
old_index_path = os.environ.get('GIT_INDEX_FILE')
os.environ['GIT_INDEX_FILE'] = index_path
try:
yield
finally:
if old_index_path is None:
del os.environ['GIT_INDEX_FILE']
else:
os.environ['GIT_INDEX_FILE'] = old_index_path
os.remove(index_path)
def create_temporary_index(tree=None):
"""Create a temporary index file and return the created file's path.
If `tree` is not None, use that as the tree to read in. Otherwise, an
empty index is created."""
gitdir = run('git', 'rev-parse', '--git-dir')
path = os.path.join(gitdir, temp_index_basename)
if tree is None:
tree = '--empty'
run('git', 'read-tree', '--index-output='+path, tree)
return path
def print_diff(old_tree, new_tree):
"""Print the diff between the two trees to stdout."""
# We use the porcelain 'diff' and not plumbing 'diff-tree' because the output
# is expected to be viewed by the user, and only the former does nice things
# like color and pagination.
subprocess.check_call(['git', 'diff', old_tree, new_tree, '--'])
def apply_changes(old_tree, new_tree, force=False, patch_mode=False):
"""Apply the changes in `new_tree` to the working directory.
Bails if there are local changes in those files and not `force`. If
`patch_mode`, runs `git checkout --patch` to select hunks interactively."""
changed_files = run('git', 'diff-tree', '-r', '-z', '--name-only', old_tree,
new_tree).rstrip('\0').split('\0')
if not force:
unstaged_files = run('git', 'diff-files', '--name-status', *changed_files)
if unstaged_files:
print >>sys.stderr, ('The following files would be modified but '
'have unstaged changes:')
print >>sys.stderr, unstaged_files
print >>sys.stderr, 'Please commit, stage, or stash them first.'
sys.exit(2)
if patch_mode:
# In patch mode, we could just as well create an index from the new tree
# and checkout from that, but then the user will be presented with a
# message saying "Discard ... from worktree". Instead, we use the old
# tree as the index and checkout from new_tree, which gives the slightly
# better message, "Apply ... to index and worktree". This is not quite
# right, since it won't be applied to the user's index, but oh well.
with temporary_index_file(old_tree):
subprocess.check_call(['git', 'checkout', '--patch', new_tree])
index_tree = old_tree
else:
with temporary_index_file(new_tree):
run('git', 'checkout-index', '-a', '-f')
return changed_files
def run(*args, **kwargs):
stdin = kwargs.pop('stdin', '')
verbose = kwargs.pop('verbose', True)
strip = kwargs.pop('strip', True)
for name in kwargs:
raise TypeError("run() got an unexpected keyword argument '%s'" % name)
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
stdout, stderr = p.communicate(input=stdin)
if p.returncode == 0:
if stderr:
if verbose:
print >>sys.stderr, '`%s` printed to stderr:' % ' '.join(args)
print >>sys.stderr, stderr.rstrip()
if strip:
stdout = stdout.rstrip('\r\n')
return stdout
if verbose:
print >>sys.stderr, '`%s` returned %s' % (' '.join(args), p.returncode)
if stderr:
print >>sys.stderr, stderr.rstrip()
sys.exit(2)
def die(message):
print >>sys.stderr, 'error:', message
sys.exit(2)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,284 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 2.8)
if (APPLE)
set(CMAKE_MACOSX_RPATH 1)
endif (APPLE)
# CMake complains if we don't have this.
if (COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif ()
# We're escaping quotes in the Windows version number, because
# for some reason CMake won't do it at config version 2.4.7
# It seems that this restores the newer behaviour where define
# args are not auto-escaped.
if (COMMAND cmake_policy)
cmake_policy(SET CMP0005 NEW)
endif ()
# First, declare project (important for prerequisite checks).
project(rocketmq-client-cpp)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif ()
set(CMAKE_CONFIGURATION_TYPES "Release")
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
set(CMAKE_VERBOSE_MAKEFILE 1)
option(BUILD_ROCKETMQ_STATIC "build rocketmq-client static library" ON)
option(BUILD_ROCKETMQ_SHARED "build rocketmq-client shared library" ON)
option(OPENSSL_USE_STATIC_LIBS "only find openssl static libs" ON) # only find static libs
if (WIN32)
find_package(OpenSSL 1.1.1 REQUIRED COMPONENTS)
if (OPENSSL_FOUND)
include_directories(${OPENSSL_INCLUDE_DIR})
message(STATUS "** OpenSSL Include dir: ${OPENSSL_INCLUDE_DIR}")
message(STATUS "** OpenSSL Libraries: ${OPENSSL_LIBRARIES}")
endif ()
else ()
#find_package(OpenSSL 1.1.1 REQUIRED COMPONENTS)
set(OPENSSL_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/bin/include)
set(OPENSSL_LIBRARIES_DIR ${PROJECT_SOURCE_DIR}/bin/lib)
set(OPENSSL_LIBRARIES ${OPENSSL_LIBRARIES_DIR}/libssl.a;${OPENSSL_LIBRARIES_DIR}/libcrypto.a)
include_directories(${OPENSSL_INCLUDE_DIR})
endif ()
message(STATUS "** OpenSSL_INCLUDE_DIR: ${OPENSSL_INCLUDE_DIR}")
message(STATUS "** OpenSSL_LIBRARIES: ${OPENSSL_LIBRARIES}")
#Find dependency
option(Boost_USE_STATIC_LIBS "only find boost static libs" ON) # only find static libs
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME ON)
if (WIN32)
find_package(Boost 1.56 REQUIRED COMPONENTS atomic thread system chrono date_time
log log_setup regex serialization filesystem locale iostreams zlib)
if (Boost_FOUND)
message(STATUS "** Boost Include dir: ${Boost_INCLUDE_DIR}")
message(STATUS "** Boost Libraries dir: ${Boost_LIBRARY_DIRS}")
message(STATUS "** Boost Libraries: ${Boost_LIBRARIES}")
include_directories(${Boost_INCLUDE_DIRS})
endif ()
else ()
#find_package(Boost 1.56 REQUIRED COMPONENTS atomic thread system chrono date_time log log_setup regex serialization filesystem locale iostreams)
set(Boost_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/bin/include)
set(Boost_LIBRARY_DIRS ${PROJECT_SOURCE_DIR}/bin/lib)
set(Boost_LIBRARIES ${Boost_LIBRARY_DIRS}/libboost_atomic.a;${Boost_LIBRARY_DIRS}/libboost_thread.a;${Boost_LIBRARY_DIRS}/libboost_system.a;
${Boost_LIBRARY_DIRS}/libboost_chrono.a;${Boost_LIBRARY_DIRS}/libboost_date_time.a;${Boost_LIBRARY_DIRS}/libboost_log.a;
${Boost_LIBRARY_DIRS}/libboost_log_setup.a;${Boost_LIBRARY_DIRS}/libboost_regex.a;${Boost_LIBRARY_DIRS}/libboost_serialization.a;
${Boost_LIBRARY_DIRS}/libboost_filesystem.a;${Boost_LIBRARY_DIRS}/libboost_locale.a;${Boost_LIBRARY_DIRS}/libboost_iostreams.a)
include_directories(${Boost_INCLUDE_DIR})
endif ()
message(STATUS "** Boost_INCLUDE_DIR: ${Boost_INCLUDE_DIR}")
message(STATUS "** Boost_LIBRARIES: ${Boost_LIBRARIES}")
option(Libevent_USE_STATIC_LIBS "only find libevent static libs" ON) # only find static libs
if (WIN32)
find_package(Libevent 2.0.22 REQUIRED COMPONENTS)
if (LIBEVENT_FOUND)
include_directories(${LIBEVENT_INCLUDE_DIRS})
message(STATUS "** libevent Include dir: ${LIBEVENT_INCLUDE_DIRS}")
message(STATUS "** libevent Libraries: ${LIBEVENT_LIBRARIES}")
endif ()
else ()
#find_package(Libevent 2.0.22 REQUIRED COMPONENTS)
set(LIBEVENT_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/bin/include)
set(LIBEVENT_LIBRARIES_DIR ${PROJECT_SOURCE_DIR}/bin/lib)
set(LIBEVENT_LIBRARIES ${LIBEVENT_LIBRARIES_DIR}/libevent.a;${LIBEVENT_LIBRARIES_DIR}/libevent_core.a;${LIBEVENT_LIBRARIES_DIR}/libevent_extra.a;
${LIBEVENT_LIBRARIES_DIR}/libevent_pthreads.a;${LIBEVENT_LIBRARIES_DIR}/libevent_openssl.a)
include_directories(${LIBEVENT_INCLUDE_DIRS})
endif ()
message(STATUS "** LIBEVENT_INCLUDE_DIR: ${LIBEVENT_INCLUDE_DIRS}")
message(STATUS "** LIBEVENT_LIBRARIES: ${LIBEVENT_LIBRARIES}")
option(JSONCPP_USE_STATIC_LIBS "only find jsoncpp static libs" ON) # only find static libs
if (WIN32)
find_package(Jsoncpp 0.10.6)
if (JSONCPP_FOUND)
include_directories(${JSONCPP_INCLUDE_DIRS})
endif ()
else ()
set(JSONCPP_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/bin/include/jsoncpp)
set(JSONCPP_LIBRARIES_DIR ${PROJECT_SOURCE_DIR}/bin/lib)
set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARIES_DIR}/libjsoncpp.a)
include_directories(${JSONCPP_INCLUDE_DIRS})
endif ()
message(STATUS "** JSONCPP_INCLUDE_DIRS: ${JSONCPP_INCLUDE_DIRS}")
message(STATUS "** JSONCPP_LIBRARIES: ${JSONCPP_LIBRARIES}")
# put binaries in a different dir to make them easier to find.
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# for unix, put debug files in a separate bin "debug" dir.
# release bin files should stay in the root of the bin dir.
# if (CMAKE_GENERATOR STREQUAL "Unix Makefiles")
# if (CMAKE_BUILD_TYPE STREQUAL Debug)
# set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/debug)
# set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/debug)
# endif()
# endif()
IF (WIN32)
add_definitions(-DWIN32 -DROCKETMQCLIENT_EXPORTS)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
ELSE ()
set(C_FLAGS
#-g
-Wall
-Wno-deprecated
-fPIC
-fno-strict-aliasing
)
set(CXX_FLAGS
#-g
-Wall
-Wno-deprecated
-fPIC
-fno-strict-aliasing
-std=c++11
-Wno-unused-local-typedef
-Wno-expansion-to-defined
# -finline-limit=1000
# -Wextra
# -pedantic
# -pedantic-errors
# -D_FILE_OFFSET_BITS=64
# -DVALGRIND
# -DCHECK_PTHREAD_RETURN_VALUE
# -Werror
# -Wconversion
# -Wno-unused-parameter
# -Wunused-but-set-variable
# -Wold-style-cast
# -Woverloaded-virtual
# -Wpointer-arith
# -Wshadow
# -Wwrite-strings
# -Wdeprecated-declarations
# -march=native
# -MMD
# -std=c++0x
# -rdynamic
)
if (CMAKE_BUILD_BITS EQUAL 32)
list(APPEND CXX_FLAGS "-m32")
else () #not-condition
list(APPEND CXX_FLAGS "-m64")
endif ()
string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}")
string(REPLACE ";" " " CMAKE_C_FLAGS "${C_FLAGS}")
option(ENABLE_ASAN "Enable asan reporting" OFF)
if (ENABLE_ASAN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -static-libasan")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -static-libasan")
message(STATUS "** ENABLE_ASAN: ${ENABLE_ASAN} Enable asan reporting")
endif ()
option(ENABLE_LSAN "Enable lsan reporting" OFF)
if (ENABLE_LSAN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak -fno-omit-frame-pointer -static-liblsan")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=leak -fno-omit-frame-pointer -static-liblsan")
message(STATUS "** ENABLE_LSAN: ${ENABLE_LSAN} Enable lsan reporting")
endif ()
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set(CMAKE_C_FLAGS_DEBUG "-g -O0 -DDEBUG")
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
# Declare deplibs, so we can use list in linker later. There's probably
# a more elegant way of doing this; with SCons, when you check for the
# lib, it is automatically passed to the linker.
set(deplibs)
# For some reason, the check_function_exists macro doesn't detect
# the inet_aton on some pure Unix platforms (e.g. sunos5). So we
# need to do a more detailed check and also include some extra deplibs.
list(APPEND deplibs dl)
list(APPEND deplibs pthread)
if (NOT APPLE)
list(APPEND deplibs rt)
endif ()
list(APPEND deplibs z)
option(CODE_COVERAGE "Enable coverage reporting" OFF)
if (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
# Add required flags (GCC & LLVM/Clang)
# Code Coverage Configuration
add_library(coverage_config INTERFACE)
target_compile_options(coverage_config INTERFACE
-O0 # no optimization
-g # generate debug info
--coverage # sets all required flags
)
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.13)
target_link_options(coverage_config INTERFACE --coverage)
else ()
target_link_libraries(coverage_config INTERFACE --coverage)
endif ()
list(APPEND deplibs coverage_config)
endif (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
# add include dir for bsd (posix uses /usr/include/)
set(CMAKE_INCLUDE_PATH "${CMAKE_INCLUDE_PATH}:/usr/local/include")
ENDIF ()
# For config.h, set some static values; it may be a good idea to make
# these values dynamic for non-standard UNIX compilers.
set(ACCEPT_TYPE_ARG3 socklen_t)
set(HAVE_CXX_BOOL 1)
set(HAVE_CXX_CASTS 1)
set(HAVE_CXX_EXCEPTIONS 1)
set(HAVE_CXX_MUTABLE 1)
set(HAVE_CXX_STDLIB 1)
set(HAVE_PTHREAD_SIGNAL 1)
set(SELECT_TYPE_ARG1 int)
set(SELECT_TYPE_ARG234 "(fd_set *)")
set(SELECT_TYPE_ARG5 "(struct timeval *)")
set(STDC_HEADERS 1)
set(TIME_WITH_SYS_TIME 1)
set(HAVE_SOCKLEN_T 1)
# For config.h, save the results based on a template (config.h.in).
# configure_file(res/config.h.in ${root_dir}/config.h)
# add_definitions(-DSYSAPI_UNIX=1 -DHAVE_CONFIG_H)
add_subdirectory(libs)
add_subdirectory(project)
add_subdirectory(example)
option(RUN_UNIT_TEST "RUN_UNIT_TEST" OFF)
if (RUN_UNIT_TEST)
message(STATUS "** RUN_UNIT_TEST: ${RUN_UNIT_TEST} Do execution testing")
enable_testing()
add_subdirectory(test)
endif ()

View File

@@ -0,0 +1,2 @@
## How to Contribute
Contributions are warmly welcome! Be it trivial cleanup, major new feature or other suggestion. Read this [how to contribute](http://rocketmq.apache.org/docs/how-to-contribute/) guide for more details.

View File

@@ -0,0 +1,263 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (properties) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
------
This product has a bundle disruptor--, which is available under BSD License.
The source code of disruptor-- can be found at https://github.com/fsaintjacques/disruptor--.
Copyright (c) 2011, François Saint-Jacques
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the disruptor-- nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL FRANÇOIS SAINT-JACQUES BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------
This product has a bundle of big_endian.h and big_endian.cpp, which is available under BSD License.
The source code of them can be found at https://github.com/chromium/chromium/tree/master/base.
Copyright 2015 The Chromium Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,5 @@
Apache RocketMQ
Copyright 2016-2020 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

View File

@@ -0,0 +1,19 @@
## What is the purpose of the change
XXXXX
## Brief changelog
XX
## Verifying this change
XXXX
Follow this checklist to help us incorporate your contribution quickly and easily. Notice, `it would be helpful if you could finish the following 5 checklist(the last one is not necessary)before request the community to review your PR`.
- [x] Make sure there is a [Github issue](https://github.com/apache/rocketmq/issues) filed for the change (usually before you start working on it). Trivial changes like typos do not require a Github issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
- [x] Format the pull request title like `[ISSUE #123] Fix UnknownException when host config not exist`. Each commit in the pull request should have a meaningful subject line and body.
- [x] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
- [x] Write necessary unit-test(over 80% coverage) to verify your logic correction, more mock a little better when a cross-module dependency exists.
- [ ] If this contribution is large, please file an [Apache Individual Contributor License Agreement](http://www.apache.org/licenses/#clas).

View File

@@ -0,0 +1,76 @@
# RocketMQ-Client-CPP
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![TravisCI](https://travis-ci.org/apache/rocketmq-client-cpp.svg)](https://travis-ci.org/apache/rocketmq-client-cpp)
[![CodeCov](https://codecov.io/gh/apache/rocketmq-client-cpp/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/rocketmq-client-cpp)
[![GitHub release](https://img.shields.io/badge/release-download-default.svg)](https://github.com/apache/rocketmq-client-cpp/releases)
![Twitter Follow](https://img.shields.io/twitter/follow/ApacheRocketMQ?style=social)
RocketMQ-Client-CPP is the C/C++ client of Apache RocketMQ, a distributed messaging and streaming platform with low latency, high performance and reliability, trillion-level capacity and flexible scalability.
## Features
- produce messages, including normal and delayed messages, synchronously or asynchronously.
- consume messages, in cluster or broadcast model, concurrently or orderly
- c and c++ style API.
- cross-platform, all features are supported on Windows, Linux and Mac OS.
- automatically rebalanced, both in producing and consuming process.
- reliability, any downtime broker or name server has no impact on the client.
## Build and Install
### Linux and Mac OS
**note**: make sure the following compile tools or libraries have been installed before running the build script **build.sh**.
- compile tools:
- gcc-c++ 4.8.2: c++ compiler while need support C++11
- cmake 2.8.0: build jsoncpp require it
- automake 1.11.1: build libevent require it
- autoconf 2.65: build libevent require it
- libtool 2.2.6: build libevent require it
- libraries:
- bzip2-devel 1.0.6: boost depend it
- zlib-devel
The **build.sh** script will automatically download and build the dependency libraries including libevent, json and boost. It will save libraries under rocketmq-client-cpp folder, and then build both static and shared libraries for rocketmq-client. If the dependent libraries are built failed, you could try to build it manually with sources [libevent 2.0.22](https://github.com/libevent/libevent/archive/release-2.0.22-stable.zip "lib event 2.0.22"), [jsoncpp 0.10.7](https://github.com/open-source-parsers/jsoncpp/archive/0.10.7.zip "jsoncpp 0.10.7"), [boost 1.58.0](http://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.gz "boost 1.58.0")
If your host is not available to internet to download the three library source files, you can copy the three library source files (release-2.0.22-stable.zip 0.10.7.zip and boost_1_58_0.tar.gz) to rocketmq-client-cpp root dir, then the build.sh will automatically use the three library source files to build rocketmq-client-cpp:
sh build.sh
Finally, both librocketmq.a and librocketmq.so are saved in rocketmq-client-cpp/bin. when using them to build application or library, besides rocketmq you should also link with following libraries -lpthread -lz -ldl -lrt. Here is an example:
g++ -o consumer_example consumer_example.cpp -lrocketmq -lpthread -lz -ldl -lrt
### Windows
**note**: make sure the following compile tools or libraries have been installed before running the build script **win32_build.bat**:
- compile tools:
- vs2015: libevent,jsoncpp,zlib,boost rocket-client require it
- git: download source code
The build script will automatically download dependent libraries including libevent json and boost to build shared library:
win32_build.bat
If your host is not available to internet to download the four library source files by build script, you can copy the four library source files
[zlib-1.2.3-src](https://codeload.github.com/jsj020122/zlib-1.2.3-src/zip/master "zlib-1.2.3-src") Extract to $(rocketmq-client-cpp root dir)/thirdparty/zlib-1.2.3-src
[libevent-release-2.0.22](https://codeload.github.com/jsj020122/libevent-release-2.0.22/zip/master "libevent-release-2.0.22") Extract to $(rocketmq-client-cpp root dir)/thirdparty/libevent-release-2.0.22
[boost_1_58_0](https://codeload.github.com/jsj020122/boost_1_58_0/zip/master "boost_1_58_0") Extract to $(rocketmq-client-cpp root dir)/thirdparty/boost_1_58_0
[jsoncpp-0.10.6](https://codeload.github.com/jsj020122/jsoncpp-0.10.6/zip/master "jsoncpp-0.10.6") Extract to $(rocketmq-client-cpp root dir)/thirdparty/jsoncpp-0.10.6
And then run following command to build x86 rocketmq-client:
win32_build.bat build
to build x64 rocketmq-client:
win32_build.bat build64

View File

@@ -0,0 +1,188 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rocketmq-client-cpp", "rocketmq-client-cpp.vcxproj", "{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AsyncProducer", "AsyncProducer.vcxproj", "{AC059D17-1D30-4D83-AE00-5FFFE3ED50A9}"
ProjectSection(ProjectDependencies) = postProject
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AsyncPushConsumer", "AsyncPushConsumer.vcxproj", "{19D42952-0418-4162-92EA-6B601B11847C}"
ProjectSection(ProjectDependencies) = postProject
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OrderlyPushConsumer", "OrderlyPushConsumer.vcxproj", "{F1657573-16CB-440E-9CAD-E6333141377D}"
ProjectSection(ProjectDependencies) = postProject
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "COrderlyAsyncProducer", "COrderlyAsyncProducer.vcxproj", "{F1657573-16CB-440E-9CAD-E6333141387D}"
ProjectSection(ProjectDependencies) = postProject
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OrderProducer", "OrderProducer.vcxproj", "{7BB3595B-CF36-4F12-8F12-897342C643CD}"
ProjectSection(ProjectDependencies) = postProject
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Producer", "Producer.vcxproj", "{52063BCB-8547-463D-AADA-A086B5339167}"
ProjectSection(ProjectDependencies) = postProject
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PullConsumer", "PullConsumer.vcxproj", "{B167E18F-71BE-4873-A806-6B340C5838EF}"
ProjectSection(ProjectDependencies) = postProject
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PushConsumeMessage", "PushConsumeMessage.vcxproj", "{00DA7C52-1EB6-46B5-9D2A-177E6A81F598}"
ProjectSection(ProjectDependencies) = postProject
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PushConsumer", "PushConsumer.vcxproj", "{07CA501C-90B7-45A5-BC89-886ACB3B30CC}"
ProjectSection(ProjectDependencies) = postProject
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SendDelayMsg", "SendDelayMsg.vcxproj", "{0B156CC7-A991-4554-A29D-8CD0ED982773}"
ProjectSection(ProjectDependencies) = postProject
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SyncProducer", "SyncProducer.vcxproj", "{C281AB41-79DE-49DD-AEEF-F300C0580D18}"
ProjectSection(ProjectDependencies) = postProject
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "example", "example", "{9B81E85B-7438-4B55-8BE0-798B4A7C8775}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{097B656C-BF7C-445B-9C2B-57292DF0BD92}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}.Debug|x64.ActiveCfg = Debug|x64
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}.Debug|x64.Build.0 = Debug|x64
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}.Debug|x86.ActiveCfg = Debug|Win32
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}.Debug|x86.Build.0 = Debug|Win32
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}.Release|x64.ActiveCfg = Release|x64
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}.Release|x64.Build.0 = Release|x64
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}.Release|x86.ActiveCfg = Release|Win32
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}.Release|x86.Build.0 = Release|Win32
{AC059D17-1D30-4D83-AE00-5FFFE3ED50A9}.Debug|x64.ActiveCfg = Debug|x64
{AC059D17-1D30-4D83-AE00-5FFFE3ED50A9}.Debug|x64.Build.0 = Debug|x64
{AC059D17-1D30-4D83-AE00-5FFFE3ED50A9}.Debug|x86.ActiveCfg = Debug|Win32
{AC059D17-1D30-4D83-AE00-5FFFE3ED50A9}.Debug|x86.Build.0 = Debug|Win32
{AC059D17-1D30-4D83-AE00-5FFFE3ED50A9}.Release|x64.ActiveCfg = Release|x64
{AC059D17-1D30-4D83-AE00-5FFFE3ED50A9}.Release|x64.Build.0 = Release|x64
{AC059D17-1D30-4D83-AE00-5FFFE3ED50A9}.Release|x86.ActiveCfg = Release|Win32
{AC059D17-1D30-4D83-AE00-5FFFE3ED50A9}.Release|x86.Build.0 = Release|Win32
{19D42952-0418-4162-92EA-6B601B11847C}.Debug|x64.ActiveCfg = Debug|x64
{19D42952-0418-4162-92EA-6B601B11847C}.Debug|x64.Build.0 = Debug|x64
{19D42952-0418-4162-92EA-6B601B11847C}.Debug|x86.ActiveCfg = Debug|Win32
{19D42952-0418-4162-92EA-6B601B11847C}.Debug|x86.Build.0 = Debug|Win32
{19D42952-0418-4162-92EA-6B601B11847C}.Release|x64.ActiveCfg = Release|x64
{19D42952-0418-4162-92EA-6B601B11847C}.Release|x64.Build.0 = Release|x64
{19D42952-0418-4162-92EA-6B601B11847C}.Release|x86.ActiveCfg = Release|Win32
{19D42952-0418-4162-92EA-6B601B11847C}.Release|x86.Build.0 = Release|Win32
{F1657573-16CB-440E-9CAD-E6333141377D}.Debug|x64.ActiveCfg = Debug|x64
{F1657573-16CB-440E-9CAD-E6333141377D}.Debug|x64.Build.0 = Debug|x64
{F1657573-16CB-440E-9CAD-E6333141377D}.Debug|x86.ActiveCfg = Debug|Win32
{F1657573-16CB-440E-9CAD-E6333141377D}.Debug|x86.Build.0 = Debug|Win32
{F1657573-16CB-440E-9CAD-E6333141377D}.Release|x64.ActiveCfg = Release|x64
{F1657573-16CB-440E-9CAD-E6333141377D}.Release|x64.Build.0 = Release|x64
{F1657573-16CB-440E-9CAD-E6333141377D}.Release|x86.ActiveCfg = Release|Win32
{F1657573-16CB-440E-9CAD-E6333141377D}.Release|x86.Build.0 = Release|Win32
{F1657573-16CB-440E-9CAD-E6333141387D}.Debug|x64.ActiveCfg = Debug|x64
{F1657573-16CB-440E-9CAD-E6333141387D}.Debug|x64.Build.0 = Debug|x64
{F1657573-16CB-440E-9CAD-E6333141387D}.Debug|x86.ActiveCfg = Debug|Win32
{F1657573-16CB-440E-9CAD-E6333141387D}.Debug|x86.Build.0 = Debug|Win32
{F1657573-16CB-440E-9CAD-E6333141387D}.Release|x64.ActiveCfg = Release|x64
{F1657573-16CB-440E-9CAD-E6333141387D}.Release|x64.Build.0 = Release|x64
{F1657573-16CB-440E-9CAD-E6333141387D}.Release|x86.ActiveCfg = Release|Win32
{F1657573-16CB-440E-9CAD-E6333141387D}.Release|x86.Build.0 = Release|Win32
{7BB3595B-CF36-4F12-8F12-897342C643CD}.Debug|x64.ActiveCfg = Debug|x64
{7BB3595B-CF36-4F12-8F12-897342C643CD}.Debug|x64.Build.0 = Debug|x64
{7BB3595B-CF36-4F12-8F12-897342C643CD}.Debug|x86.ActiveCfg = Debug|Win32
{7BB3595B-CF36-4F12-8F12-897342C643CD}.Debug|x86.Build.0 = Debug|Win32
{7BB3595B-CF36-4F12-8F12-897342C643CD}.Release|x64.ActiveCfg = Release|x64
{7BB3595B-CF36-4F12-8F12-897342C643CD}.Release|x64.Build.0 = Release|x64
{7BB3595B-CF36-4F12-8F12-897342C643CD}.Release|x86.ActiveCfg = Release|Win32
{7BB3595B-CF36-4F12-8F12-897342C643CD}.Release|x86.Build.0 = Release|Win32
{52063BCB-8547-463D-AADA-A086B5339167}.Debug|x64.ActiveCfg = Debug|x64
{52063BCB-8547-463D-AADA-A086B5339167}.Debug|x64.Build.0 = Debug|x64
{52063BCB-8547-463D-AADA-A086B5339167}.Debug|x86.ActiveCfg = Debug|Win32
{52063BCB-8547-463D-AADA-A086B5339167}.Debug|x86.Build.0 = Debug|Win32
{52063BCB-8547-463D-AADA-A086B5339167}.Release|x64.ActiveCfg = Release|x64
{52063BCB-8547-463D-AADA-A086B5339167}.Release|x64.Build.0 = Release|x64
{52063BCB-8547-463D-AADA-A086B5339167}.Release|x86.ActiveCfg = Release|Win32
{52063BCB-8547-463D-AADA-A086B5339167}.Release|x86.Build.0 = Release|Win32
{B167E18F-71BE-4873-A806-6B340C5838EF}.Debug|x64.ActiveCfg = Debug|x64
{B167E18F-71BE-4873-A806-6B340C5838EF}.Debug|x64.Build.0 = Debug|x64
{B167E18F-71BE-4873-A806-6B340C5838EF}.Debug|x86.ActiveCfg = Debug|Win32
{B167E18F-71BE-4873-A806-6B340C5838EF}.Debug|x86.Build.0 = Debug|Win32
{B167E18F-71BE-4873-A806-6B340C5838EF}.Release|x64.ActiveCfg = Release|x64
{B167E18F-71BE-4873-A806-6B340C5838EF}.Release|x64.Build.0 = Release|x64
{B167E18F-71BE-4873-A806-6B340C5838EF}.Release|x86.ActiveCfg = Release|Win32
{B167E18F-71BE-4873-A806-6B340C5838EF}.Release|x86.Build.0 = Release|Win32
{00DA7C52-1EB6-46B5-9D2A-177E6A81F598}.Debug|x64.ActiveCfg = Debug|x64
{00DA7C52-1EB6-46B5-9D2A-177E6A81F598}.Debug|x64.Build.0 = Debug|x64
{00DA7C52-1EB6-46B5-9D2A-177E6A81F598}.Debug|x86.ActiveCfg = Debug|Win32
{00DA7C52-1EB6-46B5-9D2A-177E6A81F598}.Debug|x86.Build.0 = Debug|Win32
{00DA7C52-1EB6-46B5-9D2A-177E6A81F598}.Release|x64.ActiveCfg = Release|x64
{00DA7C52-1EB6-46B5-9D2A-177E6A81F598}.Release|x64.Build.0 = Release|x64
{00DA7C52-1EB6-46B5-9D2A-177E6A81F598}.Release|x86.ActiveCfg = Release|Win32
{00DA7C52-1EB6-46B5-9D2A-177E6A81F598}.Release|x86.Build.0 = Release|Win32
{07CA501C-90B7-45A5-BC89-886ACB3B30CC}.Debug|x64.ActiveCfg = Debug|x64
{07CA501C-90B7-45A5-BC89-886ACB3B30CC}.Debug|x64.Build.0 = Debug|x64
{07CA501C-90B7-45A5-BC89-886ACB3B30CC}.Debug|x86.ActiveCfg = Debug|Win32
{07CA501C-90B7-45A5-BC89-886ACB3B30CC}.Debug|x86.Build.0 = Debug|Win32
{07CA501C-90B7-45A5-BC89-886ACB3B30CC}.Release|x64.ActiveCfg = Release|x64
{07CA501C-90B7-45A5-BC89-886ACB3B30CC}.Release|x64.Build.0 = Release|x64
{07CA501C-90B7-45A5-BC89-886ACB3B30CC}.Release|x86.ActiveCfg = Release|Win32
{07CA501C-90B7-45A5-BC89-886ACB3B30CC}.Release|x86.Build.0 = Release|Win32
{0B156CC7-A991-4554-A29D-8CD0ED982773}.Debug|x64.ActiveCfg = Debug|x64
{0B156CC7-A991-4554-A29D-8CD0ED982773}.Debug|x64.Build.0 = Debug|x64
{0B156CC7-A991-4554-A29D-8CD0ED982773}.Debug|x86.ActiveCfg = Debug|Win32
{0B156CC7-A991-4554-A29D-8CD0ED982773}.Debug|x86.Build.0 = Debug|Win32
{0B156CC7-A991-4554-A29D-8CD0ED982773}.Release|x64.ActiveCfg = Release|x64
{0B156CC7-A991-4554-A29D-8CD0ED982773}.Release|x64.Build.0 = Release|x64
{0B156CC7-A991-4554-A29D-8CD0ED982773}.Release|x86.ActiveCfg = Release|Win32
{0B156CC7-A991-4554-A29D-8CD0ED982773}.Release|x86.Build.0 = Release|Win32
{C281AB41-79DE-49DD-AEEF-F300C0580D18}.Debug|x64.ActiveCfg = Debug|x64
{C281AB41-79DE-49DD-AEEF-F300C0580D18}.Debug|x64.Build.0 = Debug|x64
{C281AB41-79DE-49DD-AEEF-F300C0580D18}.Debug|x86.ActiveCfg = Debug|Win32
{C281AB41-79DE-49DD-AEEF-F300C0580D18}.Debug|x86.Build.0 = Debug|Win32
{C281AB41-79DE-49DD-AEEF-F300C0580D18}.Release|x64.ActiveCfg = Release|x64
{C281AB41-79DE-49DD-AEEF-F300C0580D18}.Release|x64.Build.0 = Release|x64
{C281AB41-79DE-49DD-AEEF-F300C0580D18}.Release|x86.ActiveCfg = Release|Win32
{C281AB41-79DE-49DD-AEEF-F300C0580D18}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13} = {097B656C-BF7C-445B-9C2B-57292DF0BD92}
{AC059D17-1D30-4D83-AE00-5FFFE3ED50A9} = {9B81E85B-7438-4B55-8BE0-798B4A7C8775}
{19D42952-0418-4162-92EA-6B601B11847C} = {9B81E85B-7438-4B55-8BE0-798B4A7C8775}
{F1657573-16CB-440E-9CAD-E6333141377D} = {9B81E85B-7438-4B55-8BE0-798B4A7C8775}
{7BB3595B-CF36-4F12-8F12-897342C643CD} = {9B81E85B-7438-4B55-8BE0-798B4A7C8775}
{52063BCB-8547-463D-AADA-A086B5339167} = {9B81E85B-7438-4B55-8BE0-798B4A7C8775}
{B167E18F-71BE-4873-A806-6B340C5838EF} = {9B81E85B-7438-4B55-8BE0-798B4A7C8775}
{00DA7C52-1EB6-46B5-9D2A-177E6A81F598} = {9B81E85B-7438-4B55-8BE0-798B4A7C8775}
{07CA501C-90B7-45A5-BC89-886ACB3B30CC} = {9B81E85B-7438-4B55-8BE0-798B4A7C8775}
{0B156CC7-A991-4554-A29D-8CD0ED982773} = {9B81E85B-7438-4B55-8BE0-798B4A7C8775}
{C281AB41-79DE-49DD-AEEF-F300C0580D18} = {9B81E85B-7438-4B55-8BE0-798B4A7C8775}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,308 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{DFF2BED1-4A9E-4B0B-B1EC-F01D70457E13}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(WindowsSdk_71A_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)..\thirdparty\boost_1_58_0;$(SolutionDir)..\include;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\include;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\WIN32-Code\;$(SolutionDir)..\src\common;$(SolutionDir)..\src\consumer;$(SolutionDir)..\src\log;$(SolutionDir)..\src\message;$(SolutionDir)..\src\producer;$(SolutionDir)..\src\protocol;$(SolutionDir)..\src\thread;$(SolutionDir)..\src\transport;$(SolutionDir)..\thirdparty\jsoncpp-0.10.6\;$(SolutionDir)..\src;$(SolutionDir)..\libs\signature\include;$(VC_IncludePath)</IncludePath>
<LibraryPath>$(WindowsSdk_71A_LibraryPath_x86);$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(SolutionDir)thirdparty..\boost_1_58_0\stage\lib</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(WindowsSdk_71A_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)..\thirdparty\boost_1_58_0;$(SolutionDir)..\include;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\include;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\WIN32-Code\;$(SolutionDir)..\src\common;$(SolutionDir)..\src\consumer;$(SolutionDir)..\src\log;$(SolutionDir)..\src\message;$(SolutionDir)..\src\producer;$(SolutionDir)..\src\protocol;$(SolutionDir)..\src\thread;$(SolutionDir)..\src\transport;$(SolutionDir)..\thirdparty\jsoncpp-0.10.6\;$(SolutionDir)..\src;$(SolutionDir)..\libs\signature\include;$(VC_IncludePath)</IncludePath>
<LibraryPath>$(WindowsSdk_71A_LibraryPath_x86);$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(SolutionDir)..\thirdparty\boost_1_58_0\stage\lib</LibraryPath>
<IntDir>$(Configuration)\$(ProjectName)</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(WindowsSdk_71A_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)..\thirdparty\boost_1_58_0;$(SolutionDir)..\include;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\include;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\WIN32-Code\;$(SolutionDir)..\src\common;$(SolutionDir)..\src\consumer;$(SolutionDir)..\src\log;$(SolutionDir)..\src\message;$(SolutionDir)..\src\producer;$(SolutionDir)..\src\protocol;$(SolutionDir)..\src\thread;$(SolutionDir)..\src\transport;$(SolutionDir)..\thirdparty\jsoncpp-0.10.6\;$(SolutionDir)..\src;$(SolutionDir)..\libs\signature\include;$(VC_IncludePath)</IncludePath>
<LibraryPath>$(WindowsSdk_71A_LibraryPath_x64);$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;$(SolutionDir)..\thirdparty\boost_1_58_0\stage\lib</LibraryPath>
<IntDir>$(Configuration)\$(ProjectName)</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(WindowsSdk_71A_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)..\thirdparty\boost_1_58_0;$(SolutionDir)..\include;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\include;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\WIN32-Code\;$(SolutionDir)..\src\common;$(SolutionDir)..\src\consumer;$(SolutionDir)..\src\log;$(SolutionDir)..\src\message;$(SolutionDir)..\src\producer;$(SolutionDir)..\src\protocol;$(SolutionDir)..\src\thread;$(SolutionDir)..\src\transport;$(SolutionDir)..\thirdparty\jsoncpp-0.10.6\;$(SolutionDir)..\src;$(SolutionDir)..\libs\signature\include;$(VC_IncludePath)</IncludePath>
<LibraryPath>$(WindowsSdk_71A_LibraryPath_x64);$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;$(SolutionDir)..\thirdparty\boost_1_58_0\stage\lib</LibraryPath>
<IntDir>$(Configuration)\$(ProjectName)</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;ROCKETMQCLIENT_EXPORTS;_WIN32_WINNT=0x501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<AdditionalOptions>/MDd %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\$(Configuration)\libevent.lib;$(SolutionDir)..\thirdparty\jsoncpp-0.10.6\$(Configuration)\jsoncpp_lib_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions> /NODEFAULTLIB:library %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;ROCKETMQCLIENT_EXPORTS;_WIN32_WINNT=0x501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\$(Configuration)\libevent.lib;$(SolutionDir)..\thirdparty\jsoncpp-0.10.6\$(Configuration)\jsoncpp_lib_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;ROCKETMQCLIENT_EXPORTS;_WIN32_WINNT=0x501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<TargetMachine>MachineX64</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\$(Platform)\$(Configuration)\libevent.lib;$(SolutionDir)..\thirdparty\jsoncpp-0.10.6\$(Platform)\$(Configuration)\jsoncpp_lib_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;ROCKETMQCLIENT_EXPORTS;_WIN32_WINNT=0x501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<AdditionalOptions>/FS /MDd %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<TargetMachine>MachineX64</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;$(SolutionDir)..\thirdparty\libevent-release-2.0.22\$(Configuration)\libevent.lib;$(SolutionDir)..\thirdparty\jsoncpp-0.10.6\$(Configuration)\jsoncpp_lib_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions> /NODEFAULTLIB:library %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\libs\signature\src\base64.c" />
<ClCompile Include="..\libs\signature\src\hmac.c" />
<ClCompile Include="..\libs\signature\src\param_list.c" />
<ClCompile Include="..\libs\signature\src\sha1.c" />
<ClCompile Include="..\libs\signature\src\sha256.c" />
<ClCompile Include="..\libs\signature\src\sha512.c" />
<ClCompile Include="..\libs\signature\src\spas_client.c" />
<ClCompile Include="..\src\common\Arg_helper.cpp" />
<ClCompile Include="..\src\common\AsyncCallbackWrap.cpp" />
<ClCompile Include="..\src\common\big_endian.cpp" />
<ClCompile Include="..\src\common\ClientRPCHook.cpp" />
<ClCompile Include="..\src\common\dataBlock.cpp" />
<ClCompile Include="..\src\common\InputStream.cpp" />
<ClCompile Include="..\src\common\MemoryInputStream.cpp" />
<ClCompile Include="..\src\common\MemoryOutputStream.cpp" />
<ClCompile Include="..\src\common\MessageSysFlag.cpp" />
<ClCompile Include="..\src\common\MQClient.cpp" />
<ClCompile Include="..\src\common\MQVersion.cpp" />
<ClCompile Include="..\src\common\OutputStream.cpp" />
<ClCompile Include="..\src\common\PermName.cpp" />
<ClCompile Include="..\src\common\PullSysFlag.cpp" />
<ClCompile Include="..\src\common\sync_http_client.cpp" />
<ClCompile Include="..\src\common\TopAddressing.cpp" />
<ClCompile Include="..\src\common\TopicConfig.cpp" />
<ClCompile Include="..\src\common\url.cpp" />
<ClCompile Include="..\src\common\UtilAll.cpp" />
<ClCompile Include="..\src\common\Validators.cpp" />
<ClCompile Include="..\src\common\VirtualEnvUtil.cpp" />
<ClCompile Include="..\src\consumer\ConsumeMessageConcurrentlyService.cpp" />
<ClCompile Include="..\src\consumer\ConsumeMessageOrderlyService.cpp" />
<ClCompile Include="..\src\consumer\DefaultMQPullConsumer.cpp" />
<ClCompile Include="..\src\consumer\DefaultMQPushConsumer.cpp" />
<ClCompile Include="..\src\consumer\OffsetStore.cpp" />
<ClCompile Include="..\src\consumer\PullAPIWrapper.cpp" />
<ClCompile Include="..\src\consumer\PullRequest.cpp" />
<ClCompile Include="..\src\consumer\PullResult.cpp" />
<ClCompile Include="..\src\consumer\Rebalance.cpp" />
<ClCompile Include="..\src\consumer\SubscriptionData.cpp" />
<ClCompile Include="..\src\dllmain.cpp" />
<ClCompile Include="..\src\extern\CMessage.cpp" />
<ClCompile Include="..\src\extern\CMessageExt.cpp" />
<ClCompile Include="..\src\extern\CProducer.cpp" />
<ClCompile Include="..\src\extern\CPullConsumer.cpp" />
<ClCompile Include="..\src\extern\CPushConsumer.cpp" />
<ClCompile Include="..\src\extern\CSendResult.cpp" />
<ClCompile Include="..\src\log\Logging.cpp" />
<ClCompile Include="..\src\message\MQDecoder.cpp" />
<ClCompile Include="..\src\message\MQMessage.cpp" />
<ClCompile Include="..\src\message\MQMessageExt.cpp" />
<ClCompile Include="..\src\message\MQMessageQueue.cpp" />
<ClCompile Include="..\src\MQClientAPIImpl.cpp" />
<ClCompile Include="..\src\MQClientFactory.cpp" />
<ClCompile Include="..\src\MQClientManager.cpp" />
<ClCompile Include="..\src\producer\DefaultMQProducer.cpp" />
<ClCompile Include="..\src\producer\SendResult.cpp" />
<ClCompile Include="..\src\producer\StringIdMaker.cpp" />
<ClCompile Include="..\src\protocol\CommandHeader.cpp" />
<ClCompile Include="..\src\protocol\ConsumerRunningInfo.cpp" />
<ClCompile Include="..\src\protocol\LockBatchBody.cpp" />
<ClCompile Include="..\src\protocol\MessageQueue.cpp" />
<ClCompile Include="..\src\protocol\RemotingCommand.cpp" />
<ClCompile Include="..\src\thread\task_queue.cpp" />
<ClCompile Include="..\src\transport\ClientRemotingProcessor.cpp" />
<ClCompile Include="..\src\transport\ResponseFuture.cpp" />
<ClCompile Include="..\src\transport\SocketUtil.cpp" />
<ClCompile Include="..\src\transport\TcpRemotingClient.cpp" />
<ClCompile Include="..\src\transport\TcpTransport.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\common\AsyncArg.h" />
<ClInclude Include="..\src\common\AsyncCallbackWrap.h" />
<ClInclude Include="..\src\common\big_endian.h" />
<ClInclude Include="..\src\common\ByteOrder.h" />
<ClInclude Include="..\src\common\ClientRPCHook.h" />
<ClInclude Include="..\src\common\CommunicationMode.h" />
<ClInclude Include="..\src\common\dataBlock.h" />
<ClInclude Include="..\src\common\FilterAPI.h" />
<ClInclude Include="..\src\common\InputStream.h" />
<ClInclude Include="..\src\common\MemoryInputStream.h" />
<ClInclude Include="..\src\common\MemoryOutputStream.h" />
<ClInclude Include="..\src\common\MessageSysFlag.h" />
<ClInclude Include="..\src\common\MQVersion.h" />
<ClInclude Include="..\src\common\NamesrvConfig.h" />
<ClInclude Include="..\src\common\OutputStream.h" />
<ClInclude Include="..\src\common\PermName.h" />
<ClInclude Include="..\src\common\PullSysFlag.h" />
<ClInclude Include="..\src\common\ServiceState.h" />
<ClInclude Include="..\src\common\SubscriptionGroupConfig.h" />
<ClInclude Include="..\src\common\sync_http_client.h" />
<ClInclude Include="..\src\common\TopAddressing.h" />
<ClInclude Include="..\src\common\TopicConfig.h" />
<ClInclude Include="..\src\common\TopicFilterType.h" />
<ClInclude Include="..\src\common\url.h" />
<ClInclude Include="..\src\common\UtilAll.h" />
<ClInclude Include="..\src\common\Validators.h" />
<ClInclude Include="..\src\common\VirtualEnvUtil.h" />
<ClInclude Include="..\src\consumer\AllocateMQStrategy.h" />
<ClInclude Include="..\src\consumer\ConsumeMsgService.h" />
<ClInclude Include="..\src\consumer\FindBrokerResult.h" />
<ClInclude Include="..\src\consumer\OffsetStore.h" />
<ClInclude Include="..\src\consumer\PullAPIWrapper.h" />
<ClInclude Include="..\src\consumer\PullRequest.h" />
<ClInclude Include="..\src\consumer\PullResultExt.h" />
<ClInclude Include="..\src\consumer\Rebalance.h" />
<ClInclude Include="..\src\consumer\SubscriptionData.h" />
<ClInclude Include="..\src\log\Logging.h" />
<ClInclude Include="..\src\message\MQDecoder.h" />
<ClInclude Include="..\src\message\MQMessageId.h" />
<ClInclude Include="..\src\MQClientAPIImpl.h" />
<ClInclude Include="..\src\MQClientFactory.h" />
<ClInclude Include="..\src\MQClientManager.h" />
<ClInclude Include="..\src\producer\TopicPublishInfo.h" />
<ClInclude Include="..\src\protocol\CommandHeader.h" />
<ClInclude Include="..\src\protocol\ConsumerRunningInfo.h" />
<ClInclude Include="..\src\protocol\HeartbeatData.h" />
<ClInclude Include="..\src\protocol\KVTable.h" />
<ClInclude Include="..\src\protocol\LockBatchBody.h" />
<ClInclude Include="..\src\protocol\MessageQueue.h" />
<ClInclude Include="..\src\protocol\MQProtos.h" />
<ClInclude Include="..\src\protocol\ProcessQueueInfo.h" />
<ClInclude Include="..\src\protocol\RemotingCommand.h" />
<ClInclude Include="..\src\protocol\RemotingSerializable.h" />
<ClInclude Include="..\src\protocol\TopicList.h" />
<ClInclude Include="..\src\protocol\TopicRouteData.h" />
<ClInclude Include="..\src\thread\disruptorLFQ.h" />
<ClInclude Include="..\src\thread\disruptor\batch_descriptor.h" />
<ClInclude Include="..\src\thread\disruptor\claim_strategy.h" />
<ClInclude Include="..\src\thread\disruptor\event_processor.h" />
<ClInclude Include="..\src\thread\disruptor\event_publisher.h" />
<ClInclude Include="..\src\thread\disruptor\exceptions.h" />
<ClInclude Include="..\src\thread\disruptor\exception_handler.h" />
<ClInclude Include="..\src\thread\disruptor\interface.h" />
<ClInclude Include="..\src\thread\disruptor\ring_buffer.h" />
<ClInclude Include="..\src\thread\disruptor\sequence.h" />
<ClInclude Include="..\src\thread\disruptor\sequencer.h" />
<ClInclude Include="..\src\thread\disruptor\sequence_barrier.h" />
<ClInclude Include="..\src\thread\disruptor\utils.h" />
<ClInclude Include="..\src\thread\disruptor\wait_strategy.h" />
<ClInclude Include="..\src\thread\task_queue.h" />
<ClInclude Include="..\src\transport\ClientRemotingProcessor.h" />
<ClInclude Include="..\src\transport\ResponseFuture.h" />
<ClInclude Include="..\src\transport\SocketUtil.h" />
<ClInclude Include="..\src\transport\TcpRemotingClient.h" />
<ClInclude Include="..\src\transport\TcpTransport.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,450 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
<Filter Include="common">
<UniqueIdentifier>{41638677-648d-470b-a0dd-27ffbb643445}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\libs\signature\src\base64.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libs\signature\src\hmac.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libs\signature\src\param_list.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libs\signature\src\sha1.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libs\signature\src\sha256.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libs\signature\src\sha512.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libs\signature\src\spas_client.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\Arg_helper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\AsyncCallbackWrap.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\big_endian.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\ClientRPCHook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\dataBlock.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\InputStream.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\MemoryInputStream.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\MemoryOutputStream.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\MessageSysFlag.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\MQClient.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\MQVersion.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\OutputStream.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\PermName.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\PullSysFlag.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\sync_http_client.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\TopAddressing.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\TopicConfig.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\url.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\UtilAll.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\Validators.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\common\VirtualEnvUtil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\consumer\ConsumeMessageConcurrentlyService.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\consumer\ConsumeMessageOrderlyService.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\consumer\DefaultMQPullConsumer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\consumer\DefaultMQPushConsumer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\consumer\OffsetStore.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\consumer\PullAPIWrapper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\consumer\PullRequest.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\consumer\PullResult.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\consumer\Rebalance.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\consumer\SubscriptionData.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\extern\CMessage.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\extern\CMessageExt.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\extern\CProducer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\extern\CPullConsumer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\extern\CPushConsumer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\extern\CSendResult.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\log\Logging.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\message\MQDecoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\message\MQMessage.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\message\MQMessageExt.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\message\MQMessageQueue.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\MQClientAPIImpl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\MQClientFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\MQClientManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\producer\DefaultMQProducer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\producer\SendResult.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\protocol\CommandHeader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\protocol\ConsumerRunningInfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\protocol\LockBatchBody.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\protocol\MessageQueue.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\protocol\RemotingCommand.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thread\task_queue.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\transport\ClientRemotingProcessor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\transport\ResponseFuture.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\transport\SocketUtil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\transport\TcpRemotingClient.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\transport\TcpTransport.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\producer\StringIdMaker.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\common\AsyncArg.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\AsyncCallbackWrap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\big_endian.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\ByteOrder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\ClientRPCHook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\CommunicationMode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\dataBlock.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\FilterAPI.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\InputStream.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\MemoryInputStream.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\MemoryOutputStream.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\MessageSysFlag.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\MQVersion.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\NamesrvConfig.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\OutputStream.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\PermName.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\PullSysFlag.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\ServiceState.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\SubscriptionGroupConfig.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\sync_http_client.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\TopAddressing.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\TopicConfig.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\TopicFilterType.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\url.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\UtilAll.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\Validators.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\common\VirtualEnvUtil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\consumer\AllocateMQStrategy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\consumer\ConsumeMsgService.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\consumer\FindBrokerResult.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\consumer\OffsetStore.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\consumer\PullAPIWrapper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\consumer\PullRequest.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\consumer\PullResultExt.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\consumer\Rebalance.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\consumer\SubscriptionData.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\log\Logging.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\message\MQDecoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\message\MQMessageId.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\MQClientAPIImpl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\MQClientFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\MQClientManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\producer\TopicPublishInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\CommandHeader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\ConsumerRunningInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\HeartbeatData.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\KVTable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\LockBatchBody.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\MessageQueue.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\MQProtos.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\ProcessQueueInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\RemotingCommand.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\RemotingSerializable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\TopicList.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\protocol\TopicRouteData.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptorLFQ.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\batch_descriptor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\claim_strategy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\event_processor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\event_publisher.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\exceptions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\exception_handler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\interface.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\ring_buffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\sequence.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\sequencer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\sequence_barrier.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\utils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\disruptor\wait_strategy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\thread\task_queue.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\transport\ClientRemotingProcessor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\transport\ResponseFuture.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\transport\SocketUtil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\transport\TcpRemotingClient.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\transport\TcpTransport.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,532 @@
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
basepath=$(
cd $(dirname $0)
pwd
)
declare down_dir="${basepath}/tmp_down_dir"
declare build_dir="${basepath}/tmp_build_dir"
declare packet_dir="${basepath}/tmp_packet_dir"
declare install_lib_dir="${basepath}/bin"
declare static_package_dir="${basepath}/tmp_static_package_dir"
declare fname_openssl="openssl*.tar.gz"
declare fname_libevent="libevent*.zip"
declare fname_jsoncpp="jsoncpp*.zip"
declare fname_boost="boost*.tar.gz"
declare fname_openssl_down="openssl-1.1.1d.tar.gz"
declare fname_libevent_down="release-2.1.11-stable.zip"
declare fname_jsoncpp_down="0.10.7.zip"
declare fname_boost_down="1.58.0/boost_1_58_0.tar.gz"
PrintParams() {
echo "=========================================one key build help============================================"
echo "sh build.sh [no build libevent:noEvent] [no build json:noJson] [no build boost:noBoost] [ execution test:test]"
echo "usage: sh build.sh noJson noEvent noBoost test"
echo "=========================================one key build help============================================"
echo ""
}
if test "$(uname)" = "Linux"; then
declare cpu_num=$(cat /proc/cpuinfo | grep "processor" | wc -l)
elif test "$(uname)" = "Darwin" ; then
declare cpu_num=$(sysctl -n machdep.cpu.thread_count)
fi
declare need_build_openssl=1
declare need_build_libevent=1
declare need_build_jsoncpp=1
declare need_build_boost=1
declare enable_asan=0
declare enable_lsan=0
declare verbose=1
declare codecov=0
declare debug=0
declare test=0
pasres_arguments() {
for var in "$@"; do
case "$var" in
noOpenSSL)
need_build_openssl=0
;;
noEvent)
need_build_libevent=0
;;
noJson)
need_build_jsoncpp=0
;;
noBoost)
need_build_boost=0
;;
asan)
enable_asan=1
;;
lsan)
enable_lsan=1
;;
noVerbose)
verbose=0
;;
codecov)
codecov=1
;;
debug)
debug=1
;;
test)
test=1
;;
esac
done
}
pasres_arguments $@
PrintParams() {
echo "###########################################################################"
if [ $need_build_openssl -eq 0 ]; then
echo "no need build openssl lib"
else
echo "need build openssl lib"
fi
if [ $need_build_jsoncpp -eq 0 ]; then
echo "no need build jsoncpp lib"
else
echo "need build jsoncpp lib"
fi
if [ $need_build_libevent -eq 0 ]; then
echo "no need build libevent lib"
else
echo "need build libevent lib"
fi
if [ $need_build_boost -eq 0 ]; then
echo "no need build boost lib"
else
echo "need build boost lib"
fi
if [ $enable_asan -eq 1 ]; then
echo "enable asan reporting"
else
echo "disable asan reporting"
fi
if [ $enable_lsan -eq 1 ]; then
echo "enable lsan reporting"
else
echo "disable lsan reporting"
fi
if [ $verbose -eq 0 ]; then
echo "no need print detail logs"
else
echo "need print detail logs"
fi
if [ $codecov -eq 1 ]; then
echo "run unit tests with code coverage"
else
echo "run unit tests without code coverage"
fi
if [ $debug -eq 1 ]; then
echo "enable debug"
else
echo "disable debug"
fi
if [ $test -eq 1 ]; then
echo "build unit tests"
else
echo "without build unit tests"
fi
echo "###########################################################################"
echo ""
}
Prepare() {
if [ -e ${down_dir} ]; then
echo "${down_dir} is exist"
#cd ${down_dir}
#ls |grep -v ${fname_libevent} |grep -v ${fname_jsoncpp} | grep -v ${fname_boost} |xargs rm -rf
else
mkdir -p ${down_dir}
fi
cd ${basepath}
if [ -e ${fname_openssl} ]; then
mv -f ${basepath}/${fname_openssl} ${down_dir}
fi
if [ -e ${fname_libevent} ]; then
mv -f ${basepath}/${fname_libevent} ${down_dir}
fi
if [ -e ${fname_jsoncpp} ]; then
mv -f ${basepath}/${fname_jsoncpp} ${down_dir}
fi
if [ -e ${fname_boost} ]; then
mv -f ${basepath}/${fname_boost} ${down_dir}
fi
if [ -e ${build_dir} ]; then
echo "${build_dir} is exist"
#rm -rf ${build_dir}/*
else
mkdir -p ${build_dir}
fi
if [ -e ${packet_dir} ]; then
echo "${packet_dir} is exist"
#rm -rf ${packet_dir}/*
else
mkdir -p ${packet_dir}
fi
if [ -e ${install_lib_dir} ]; then
echo "${install_lib_dir} is exist"
else
mkdir -p ${install_lib_dir}
fi
}
BuildOpenSSL() {
if [ $need_build_openssl -eq 0 ]; then
echo "no need build openssl lib"
return 0
fi
cd ${down_dir}
if [ -e ${fname_openssl} ]; then
echo "${fname_openssl} is exist"
else
wget https://www.openssl.org/source/old/1.1.1/${fname_openssl_down} -O ${fname_openssl_down}
fi
tar -zxvf ${fname_openssl} &> unzipopenssl.txt
if [ $? -ne 0 ]; then
exit 1
fi
openssl_dir=$(ls | grep ^openssl | grep .*[^gz]$)
cd ${openssl_dir}
if [ $? -ne 0 ]; then
exit 1
fi
echo "build openssl static #####################"
if [ $verbose -eq 0 ]; then
./config shared CFLAGS=-fPIC CPPFLAGS=-fPIC --prefix=${install_lib_dir} --openssldir=${install_lib_dir} &> opensslconfig.txt
else
./config shared CFLAGS=-fPIC CPPFLAGS=-fPIC --prefix=${install_lib_dir} --openssldir=${install_lib_dir}
fi
if [ $? -ne 0 ]; then
exit 1
fi
if [ $verbose -eq 0 ]; then
echo "build openssl without detail log."
make depend &> opensslbuild.txt
make -j $cpu_num &> opensslbuild.txt
else
make depend
make -j $cpu_num
fi
if [ $? -ne 0 ]; then
exit 1
fi
make install
echo "build openssl success."
}
BuildLibevent() {
if [ $need_build_libevent -eq 0 ]; then
echo "no need build libevent lib"
return 0
fi
cd ${down_dir}
if [ -e ${fname_libevent} ]; then
echo "${fname_libevent} is exist"
else
wget https://github.com/libevent/libevent/archive/${fname_libevent_down} -O libevent-${fname_libevent_down}
fi
unzip -o ${fname_libevent} &> unziplibevent.txt
if [ $? -ne 0 ]; then
exit 1
fi
libevent_dir=$(ls | grep ^libevent | grep .*[^zip^txt]$)
cd ${libevent_dir}
if [ $? -ne 0 ]; then
exit 1
fi
./autogen.sh
if [ $? -ne 0 ]; then
exit 1
fi
echo "build libevent static #####################"
if [ $verbose -eq 0 ]; then
./configure --enable-static=yes --enable-shared=no CFLAGS="-fPIC -I${install_lib_dir}/include" CPPFLAGS="-fPIC -I${install_lib_dir}/include" LDFLAGS="-L${install_lib_dir}/lib" --prefix=${install_lib_dir} &> libeventconfig.txt
else
./configure --enable-static=yes --enable-shared=no CFLAGS="-fPIC -I${install_lib_dir}/include" CPPFLAGS="-fPIC -I${install_lib_dir}/include" LDFLAGS="-L${install_lib_dir}/lib" --prefix=${install_lib_dir}
fi
if [ $? -ne 0 ]; then
exit 1
fi
if [ $verbose -eq 0 ]; then
echo "build libevent without detail log."
make -j $cpu_num &> libeventbuild.txt
else
make -j $cpu_num
fi
if [ $? -ne 0 ]; then
exit 1
fi
make install
echo "build linevent success."
}
BuildJsonCPP() {
if [ $need_build_jsoncpp -eq 0 ]; then
echo "no need build jsoncpp lib"
return 0
fi
cd ${down_dir}
if [ -e ${fname_jsoncpp} ]; then
echo "${fname_jsoncpp} is exist"
else
wget https://github.com/open-source-parsers/jsoncpp/archive/${fname_jsoncpp_down} -O jsoncpp-${fname_jsoncpp_down}
fi
unzip -o ${fname_jsoncpp} &> unzipjsoncpp.txt
if [ $? -ne 0 ]; then
exit 1
fi
jsoncpp_dir=$(ls | grep ^jsoncpp | grep .*[^zip]$)
cd ${jsoncpp_dir}
if [ $? -ne 0 ]; then
exit 1
fi
mkdir build
cd build
echo "build jsoncpp static ######################"
if [ $verbose -eq 0 ]; then
echo "build jsoncpp without detail log."
cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir} &> jsoncppbuild.txt
else
cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir}
fi
if [ $? -ne 0 ]; then
exit 1
fi
if [ $verbose -eq 0 ]; then
make -j $cpu_num &> jsoncppbuild.txt
else
make -j $cpu_num
fi
if [ $? -ne 0 ]; then
exit 1
fi
make install
echo "build jsoncpp success."
if [ ! -f ${install_lib_dir}/lib/libjsoncpp.a ]; then
echo " ./bin/lib directory is not libjsoncpp.a"
cp ${install_lib_dir}/lib/x86_64-linux-gnu/libjsoncpp.a ${install_lib_dir}/lib/
fi
}
BuildBoost() {
if [ $need_build_boost -eq 0 ]; then
echo "no need build boost lib"
return 0
fi
cd ${down_dir}
if [ -e ${fname_boost} ]; then
echo "${fname_boost} is exist"
else
wget http://sourceforge.net/projects/boost/files/boost/${fname_boost_down}
fi
tar -zxvf ${fname_boost} &> unzipboost.txt
boost_dir=$(ls | grep ^boost | grep .*[^gz]$)
cd ${boost_dir}
if [ $? -ne 0 ]; then
exit 1
fi
./bootstrap.sh
if [ $? -ne 0 ]; then
exit 1
fi
echo "build boost static #####################"
pwd
if [ $verbose -eq 0 ]; then
echo "build boost without detail log."
./b2 -j$cpu_num cflags=-fPIC cxxflags=-fPIC --with-atomic --with-thread --with-system --with-chrono --with-date_time --with-log --with-regex --with-serialization --with-filesystem --with-locale --with-iostreams threading=multi link=static release install --prefix=${install_lib_dir} &> boostbuild.txt
else
./b2 -j$cpu_num cflags=-fPIC cxxflags=-fPIC --with-atomic --with-thread --with-system --with-chrono --with-date_time --with-log --with-regex --with-serialization --with-filesystem --with-locale --with-iostreams threading=multi link=static release install --prefix=${install_lib_dir}
fi
if [ $? -ne 0 ]; then
exit 1
fi
}
BuildRocketMQClient() {
cd ${build_dir}
echo "============start to build rocketmq client cpp.========="
local ROCKETMQ_CMAKE_FLAG=""
if [ $test -eq 1 ]; then
if [ $codecov -eq 1 ]; then
ROCKETMQ_CMAKE_FLAG=$ROCKETMQ_CMAKE_FLAG" -DRUN_UNIT_TEST=ON -DCODE_COVERAGE=ON"
else
ROCKETMQ_CMAKE_FLAG=$ROCKETMQ_CMAKE_FLAG" -DRUN_UNIT_TEST=ON -DCODE_COVERAGE=OFF"
fi
else
ROCKETMQ_CMAKE_FLAG=$ROCKETMQ_CMAKE_FLAG" -DRUN_UNIT_TEST=OFF -DCODE_COVERAGE=OFF"
fi
if [ $enable_asan -eq 1 ]; then
ROCKETMQ_CMAKE_FLAG=$ROCKETMQ_CMAKE_FLAG" -DENABLE_ASAN=ON"
else
ROCKETMQ_CMAKE_FLAG=$ROCKETMQ_CMAKE_FLAG" -DENABLE_ASAN=OFF"
fi
if [ $enable_lsan -eq 1 ]; then
ROCKETMQ_CMAKE_FLAG=$ROCKETMQ_CMAKE_FLAG" -DENABLE_LSAN=ON"
else
ROCKETMQ_CMAKE_FLAG=$ROCKETMQ_CMAKE_FLAG" -DENABLE_LSAN=OFF"
fi
if [ $debug -eq 1 ]; then
ROCKETMQ_CMAKE_FLAG=$ROCKETMQ_CMAKE_FLAG" -DCMAKE_BUILD_TYPE=Debug"
else
ROCKETMQ_CMAKE_FLAG=$ROCKETMQ_CMAKE_FLAG" -DCMAKE_BUILD_TYPE=Release"
fi
cmake .. $ROCKETMQ_CMAKE_FLAG
if [ $verbose -eq 0 ]; then
echo "build rocketmq without detail log."
make -j $cpu_num &> buildclient.txt
else
make -j $cpu_num
fi
if [ $? -ne 0 ]; then
echo "build error....."
exit 1
fi
#sudo make install
PackageRocketMQStatic
}
BuildGoogleTest() {
if [ $test -eq 0 ]; then
echo "no need build google test lib"
return 0
fi
if [ -f ./bin/lib/libgtest.a ]; then
echo "libgteest already exist no need build test"
return 0
fi
cd ${down_dir}
if [ -e release-1.8.1.tar.gz ]; then
echo "${fname_boost} is exist"
else
wget https://github.com/abseil/googletest/archive/release-1.8.1.tar.gz
fi
if [ ! -d "googletest-release-1.8.1" ]; then
tar -zxvf release-1.8.1.tar.gz &> googletest.txt
fi
cd googletest-release-1.8.1
mkdir -p build
cd build
echo "build googletest static #####################"
if [ $verbose -eq 0 ]; then
echo "build googletest without detail log."
cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir} &> googletestbuild.txt
else
cmake .. -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${install_lib_dir}
fi
if [ $? -ne 0 ]; then
exit 1
fi
if [ $verbose -eq 0 ]; then
make -j $cpu_num &> gtestbuild.txt
else
make -j $cpu_num
fi
if [ $? -ne 0 ]; then
exit 1
fi
make install
if [ ! -f ${install_lib_dir}/lib/libgtest.a ]; then
echo " ./bin/lib directory is not libgtest.a"
cp ${install_lib_dir}/lib64/lib* ${install_lib_dir}/lib
fi
}
ExecutionTesting() {
if [ $test -eq 0 ]; then
echo "Build success without executing unit tests."
return 0
fi
echo "############# unit test start ###########"
cd ${build_dir}
if [ $verbose -eq 0 ]; then
ctest
else
ctest -V
fi
if [ $? -ne 0 ]; then
echo "############# unit test failed ###########"
exit 1
fi
echo "############# unit test finish ###########"
}
PackageRocketMQStatic() {
echo "############# Start package static rocketmq library. #############"
if test "$(uname)" = "Linux"; then
#packet libevent,jsoncpp,boost,rocketmq,Signature to one librocketmq.a
cp -f ${basepath}/libs/signature/lib/libSignature.a ${install_lib_dir}/lib
ar -M <${basepath}/package_rocketmq.mri
cp -f librocketmq.a ${install_lib_dir}
elif test "$(uname)" = "Darwin" ; then
mkdir -p ${static_package_dir}
cd ${static_package_dir}
cp -f ${basepath}/libs/signature/lib/libSignature.a .
cp -f ${install_lib_dir}/lib/lib*.a .
cp -f ${install_lib_dir}/librocketmq.a .
echo "Md5 Hash RocketMQ Before:"
md5sum librocketmq.a
local dir=`ls *.a | grep -E 'gtest|gmock'`
for i in $dir
do
rm -rf $i
done
libtool -no_warning_for_no_symbols -static -o librocketmq.a *.a
echo "Md5 Hash RocketMQ After:"
md5sum librocketmq.a
echo "Try to copy $(pwd)/librocketmq.a to ${install_lib_dir}/"
cp -f librocketmq.a ${install_lib_dir}/
cd ${basepath}
rm -rf ${static_package_dir}
fi
echo "############# Package static rocketmq library success.#############"
}
PrintParams
Prepare
BuildOpenSSL
BuildLibevent
BuildJsonCPP
BuildBoost
BuildGoogleTest
BuildRocketMQClient
ExecutionTesting

View File

@@ -0,0 +1,95 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Find jsoncpp
#
# Find the jsoncpp includes and library
#
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH
#
# -*- cmake -*-
# - Find JSONCpp
# Find the JSONCpp includes and library
# This module defines
# JSONCPP_INCLUDE_DIRS, where to find json.h, etc.
# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp.
# JSONCPP_FOUND, If false, do not try to use jsoncpp.
# also defined, but not for general use are
# JSONCPP_LIBRARIES, where to find the jsoncpp library.
# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
if( JSONCPP_USE_STATIC_LIBS )
set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES})
if(WIN32)
list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a)
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
endif()
else()
set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES})
if(WIN32)
list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .dll .so)
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .so)
endif()
endif()
FIND_PATH(JSONCPP_INCLUDE_DIRS
NAMES
json.h
json/json.h
PATHS
${CMAKE_SOURCE_DIR}/bin/include
C:/jsoncpp/include
${CMAKE_SOURCE_DIR}/win32-deps/include
C:/jsoncpp-0.10.6/include
PATH_SUFFIXES jsoncpp
)
find_library(JSONCPP_LIBRARIES
NAMES jsoncpp
PATHS ${CMAKE_SOURCE_DIR}/bin/lib C:/jsoncpp/lib ${CMAKE_SOURCE_DIR}/win32-deps/lib C:/jsoncpp-0.10.6/
)
IF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS)
SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARIES})
SET(JSONCPP_FOUND "YES")
ELSE (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS)
SET(JSONCPP_FOUND "NO")
ENDIF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS)
IF (JSONCPP_FOUND)
IF (NOT JSONCPP_FIND_QUIETLY)
MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}")
ENDIF (NOT JSONCPP_FIND_QUIETLY)
ELSE (JSONCPP_FOUND)
IF (JSONCPP_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find JSONCPP library include: ${JSONCPP_INCLUDE_DIRS}, lib: ${JSONCPP_LIBRARIES}")
ENDIF (JSONCPP_FIND_REQUIRED)
ENDIF (JSONCPP_FOUND)
# Deprecated declarations.
SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIRS} )
GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARIES} PATH)
MARK_AS_ADVANCED(
JSONCPP_LIBRARIES
JSONCPP_INCLUDE_DIRS
)
# Restore the original find library ordering
if( JSONCPP_USE_STATIC_LIBS )
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
endif()

View File

@@ -0,0 +1,152 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# - Try to find libevent
#.rst
# FindLibevent
# ------------
#
# Find Libevent include directories and libraries. Invoke as::
#
# find_package(Libevent
# [version] [EXACT] # Minimum or exact version
# [REQUIRED] # Fail if Libevent is not found
# [COMPONENT <C>...]) # Libraries to look for
#
# Valid components are one or more of:: libevent core extra pthreads openssl.
# Note that 'libevent' contains both core and extra. You must specify one of
# them for the other components.
#
# This module will define the following variables::
#
# LIBEVENT_FOUND - True if headers and requested libraries were found
# LIBEVENT_INCLUDE_DIRS - Libevent include directories
# LIBEVENT_LIBRARIES - Libevent libraries to be linked
# LIBEVENT_<C>_FOUND - Component <C> was found (<C> is uppercase)
# LIBEVENT_<C>_LIBRARY - Library to be linked for Libevent component <C>.
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBEVENT QUIET libevent)
# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
if( Libevent_USE_STATIC_LIBS )
set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES})
if(WIN32)
list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a)
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
endif()
else()
set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES})
if(WIN32)
list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .dll .so)
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .so)
endif()
endif()
# Look for the Libevent 2.0 or 1.4 headers
find_path(LIBEVENT_INCLUDE_DIR
NAMES
WIN32-Code/event2/event-config.h
event2/event-config.h
event-config.h
PATHS ${CMAKE_SOURCE_DIR}/bin/include C:/libevent/include ${CMAKE_SOURCE_DIR}/win32-deps/include
HINTS
${PC_LIBEVENT_INCLUDE_DIRS}
)
# ------------------------------------------------------------------------
# Prefix initialization
# ------------------------------------------------------------------------
set(Libevent_LIB_PREFIX "")
set(LIBEVENT_EVENT_CONFIG_DIR ${LIBEVENT_INCLUDE_DIR})
if(WIN32)
set(Libevent_LIB_PREFIX "lib")
set(LIBEVENT_EVENT_CONFIG_DIR "${LIBEVENT_INCLUDE_DIR}/../WIN32-Code/")
endif()
if(LIBEVENT_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*")
if(EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h")
# Libevent 2.0
file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h"
LIBEVENT_VERSION REGEX "${_version_regex}")
else()
# Libevent 1.4
if(EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h")
file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h"
LIBEVENT_VERSION REGEX "${_version_regex}")
endif()
endif()
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBEVENT_VERSION "${LIBEVENT_VERSION}")
unset(_version_regex)
endif()
set(_LIBEVENT_REQUIRED_VARS)
if(WIN32)
set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extras)
else()
set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extra pthreads)
endif()
message(status "** libevent components: ${Libevent_FIND_COMPONENTS}")
foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event")
# Note: compare two variables to avoid a CMP0054 policy warning
if(COMPONENT STREQUAL _LIBEVENT_LIBNAME)
set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event")
else()
set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event_${COMPONENT}")
endif()
string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
message(status "** ${_LIBEVENT_LIBNAME}")
find_library(LIBEVENT_${COMPONENT_UPPER}_LIBRARY
NAMES ${_LIBEVENT_LIBNAME}
PATHS ${CMAKE_SOURCE_DIR}/bin/lib C:/libevent-2.0.22-stable C:/libevent-2.0.22-stable/lib C:/libevent/lib ${CMAKE_SOURCE_DIR}/win32-deps/lib
HINTS ${PC_LIBEVENT_LIBRARY_DIRS}
)
if(LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
set(Libevent_${COMPONENT}_FOUND 1)
endif()
list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
endforeach()
unset(_LIBEVENT_LIBNAME)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBEVENT_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Libevent REQUIRED_VARS
${_LIBEVENT_REQUIRED_VARS}
LIBEVENT_INCLUDE_DIR
VERSION_VAR LIBEVENT_VERSION
HANDLE_COMPONENTS)
if(LIBEVENT_FOUND)
set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_INCLUDE_DIR})
set(LIBEVENT_LIBRARIES)
foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT_UPPER}_LIBRARY})
set(LIBEVENT_${COMPONENT_UPPER}_FOUND ${Libevent_${COMPONENT}_FOUND})
endforeach()
endif()
mark_as_advanced(LIBEVENT_INCLUDE_DIR ${_LIBEVENT_REQUIRED_VARS})
# Restore the original find library ordering
if( Libevent_USE_STATIC_LIBS )
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
endif()
unset(_LIBEVENT_REQUIRED_VARS)

View File

@@ -0,0 +1,29 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
BASEDIR=$(dirname "$0")
if [[ ! -d ${BASEDIR}/rocketmq_amd64/usr/local/include/rocketmq ]]; then
mkdir -p ${BASEDIR}/rocketmq_amd64/usr/local/include/rocketmq
fi
if [[ ! -d ${BASEDIR}/rocketmq_amd64/usr/local/lib ]]; then
mkdir -p ${BASEDIR}/rocketmq_amd64/usr/local/lib
fi
cp -R ${BASEDIR}/../include/* ${BASEDIR}/rocketmq_amd64/usr/local/include/rocketmq
cp ${BASEDIR}/../bin/librocketmq.so ${BASEDIR}/rocketmq_amd64/usr/local/lib/
cp ${BASEDIR}/../bin/librocketmq.a ${BASEDIR}/rocketmq_amd64/usr/local/lib/
VERSION=`cat ${BASEDIR}/rocketmq_amd64/DEBIAN/control | grep Version | awk -F ':' '{print $2}'| sed 's/^ *//'`
dpkg-deb --build ${BASEDIR}/rocketmq_amd64 rocketmq-client-cpp-${VERSION}.amd64.deb

View File

@@ -0,0 +1,8 @@
Package: RocketMQ
Version: 2.2.0
Architecture: amd64
Essential: no
Priority: optional
Depends:
Maintainer: "Apache RocketMQ" <dev@rocketmq.apache.org>
Description: This package is C++ client of Apache RocketMQ for debian and its derivertives like Ubuntu.

View File

@@ -0,0 +1,17 @@
#!/bin/sh
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
ldconfig

View File

@@ -0,0 +1,46 @@
#!/bin/sh
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
VERSION="2.2.0"
PKG_NAME="rocketmq-client-cpp"
CWD_DIR=$(cd "$(dirname "$0")"; pwd)
DEPLOY_BUILD_HOME=${CWD_DIR}/${PKG_NAME}
# ##====================================================================
#make
# ##====================================================================
# # deploy
rm -rf ${DEPLOY_BUILD_HOME}
mkdir -p ${DEPLOY_BUILD_HOME}/lib
cp -rf ${CWD_DIR}/../bin/*.a ${DEPLOY_BUILD_HOME}/lib/
if test "$(uname)" = "Linux"; then
cp -rf ${CWD_DIR}/../bin/*.so ${DEPLOY_BUILD_HOME}/lib/
fi
if test "$(uname)" = "Darwin"; then
cp -rf ${CWD_DIR}/../bin/*.dylib ${DEPLOY_BUILD_HOME}/lib/
fi
cp -rf ${CWD_DIR}/../include ${DEPLOY_BUILD_HOME}/
cp -rf ${CWD_DIR}/../example ${DEPLOY_BUILD_HOME}/
cp -rf ${CWD_DIR}/../README.md ${DEPLOY_BUILD_HOME}/
cp -rf ${CWD_DIR}/../LICENSE ${DEPLOY_BUILD_HOME}/LICENSE
cp -rf ${CWD_DIR}/../NOTICE ${DEPLOY_BUILD_HOME}/NOTICE
cd ${CWD_DIR} && tar -cvzf ./${PKG_NAME}-${VERSION}-bin-release.tar.gz ./${PKG_NAME} &> /dev/null
rm -rf ${DEPLOY_BUILD_HOME}
# # ##====================================================================
#make clean

View File

@@ -0,0 +1,135 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <chrono>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <thread>
#include "common.h"
using namespace rocketmq;
std::atomic<bool> g_quit;
std::mutex g_mtx;
std::condition_variable g_finished;
SendCallback* g_callback = NULL;
TpsReportService g_tps;
class MySendCallback : public SendCallback {
virtual void onSuccess(SendResult& sendResult) {
g_msgCount--;
g_tps.Increment();
if (g_msgCount.load() <= 0) {
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.notify_one();
}
}
virtual void onException(MQException& e) { cout << "send Exception\n"; }
};
class MyAutoDeleteSendCallback : public AutoDeleteSendCallBack {
public:
virtual ~MyAutoDeleteSendCallback() {}
virtual void onSuccess(SendResult& sendResult) {
g_msgCount--;
if (g_msgCount.load() <= 0) {
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.notify_one();
}
}
virtual void onException(MQException& e) { std::cout << "send Exception" << e << "\n"; }
};
void AsyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) {
while (!g_quit.load()) {
if (g_msgCount.load() <= 0) {
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.notify_one();
}
MQMessage msg(info->topic, // topic
"*", // tag
info->body); // body
if (info->IsAutoDeleteSendCallback) {
g_callback = new MyAutoDeleteSendCallback(); // auto delete
}
try {
producer->send(msg, g_callback);
} catch (MQException& e) {
std::cout << e << endl; // if catch excepiton , need re-send this msg by
// service
}
}
}
int main(int argc, char* argv[]) {
RocketmqSendAndConsumerArgs info;
if (!ParseArgs(argc, argv, &info)) {
exit(-1);
}
DefaultMQProducer producer("please_rename_unique_group_name");
if (!info.IsAutoDeleteSendCallback) {
g_callback = new MySendCallback();
}
PrintRocketmqSendAndConsumerArgs(info);
if (!info.namesrv.empty())
producer.setNamesrvAddr(info.namesrv);
producer.setGroupName(info.groupname);
producer.setInstanceName(info.groupname);
producer.setNamesrvDomain(info.namesrv_domain);
producer.start();
g_tps.start();
std::vector<std::shared_ptr<std::thread>> work_pool;
auto start = std::chrono::system_clock::now();
int msgcount = g_msgCount.load();
for (int j = 0; j < info.thread_count; j++) {
std::shared_ptr<std::thread> th = std::make_shared<std::thread>(AsyncProducerWorker, &info, &producer);
work_pool.push_back(th);
}
{
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.wait(lck);
g_quit.store(true);
}
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n"
<< "========================finished==============================\n";
producer.shutdown();
for (size_t th = 0; th != work_pool.size(); ++th) {
work_pool[th]->join();
}
if (!info.IsAutoDeleteSendCallback) {
delete g_callback;
}
return 0;
}

View File

@@ -0,0 +1,108 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <vector>
#include "common.h"
std::mutex g_mtx;
std::condition_variable g_finished;
TpsReportService g_tps;
using namespace rocketmq;
class MyMsgListener : public MessageListenerConcurrently {
public:
MyMsgListener() {}
virtual ~MyMsgListener() {}
virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) {
g_msgCount.store(g_msgCount.load() - msgs.size());
for (size_t i = 0; i < msgs.size(); ++i) {
g_tps.Increment();
}
if (g_msgCount.load() <= 0) {
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.notify_one();
}
return CONSUME_SUCCESS;
}
};
int main(int argc, char* argv[]) {
RocketmqSendAndConsumerArgs info;
if (!ParseArgs(argc, argv, &info)) {
exit(-1);
}
PrintRocketmqSendAndConsumerArgs(info);
DefaultMQPushConsumer consumer("please_rename_unique_group_name");
DefaultMQProducer producer("please_rename_unique_group_name");
producer.setNamesrvAddr(info.namesrv);
producer.setGroupName("msg-persist-group_producer_sandbox");
producer.setNamesrvDomain(info.namesrv_domain);
producer.start();
consumer.setNamesrvAddr(info.namesrv);
consumer.setGroupName(info.groupname);
consumer.setNamesrvDomain(info.namesrv_domain);
consumer.setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET);
consumer.setInstanceName(info.groupname);
consumer.subscribe(info.topic, "*");
consumer.setConsumeThreadCount(15);
consumer.setTcpTransportTryLockTimeout(1000);
consumer.setTcpTransportConnectTimeout(400);
MyMsgListener msglistener;
consumer.registerMessageListener(&msglistener);
try {
consumer.start();
} catch (MQClientException& e) {
cout << e << endl;
}
g_tps.start();
int msgcount = g_msgCount.load();
for (int i = 0; i < msgcount; ++i) {
MQMessage msg(info.topic, // topic
"*", // tag
info.body); // body
try {
producer.send(msg);
} catch (MQException& e) {
std::cout << e << endl; // if catch excepiton , need re-send this msg by
// service
}
}
{
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.wait(lck);
}
producer.shutdown();
consumer.shutdown();
return 0;
}

View File

@@ -0,0 +1,122 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
#include "common.h"
using namespace rocketmq;
using namespace std;
std::atomic<bool> g_quit;
std::mutex g_mtx;
std::condition_variable g_finished;
TpsReportService g_tps;
void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) {
while (!g_quit.load()) {
if (g_msgCount.load() <= 0) {
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.notify_one();
break;
}
vector<MQMessage> msgs;
MQMessage msg1(info->topic, "*", info->body);
msg1.setProperty("property1", "value1");
MQMessage msg2(info->topic, "*", info->body);
msg2.setProperty("property1", "value1");
msg2.setProperty("property2", "value2");
MQMessage msg3(info->topic, "*", info->body);
msg3.setProperty("property1", "value1");
msg3.setProperty("property2", "value2");
msg3.setProperty("property3", "value3");
msgs.push_back(msg1);
msgs.push_back(msg2);
msgs.push_back(msg3);
try {
auto start = std::chrono::system_clock::now();
SendResult sendResult = producer->send(msgs);
g_tps.Increment();
--g_msgCount;
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
if (duration.count() >= 500) {
std::cout << "send RT more than: " << duration.count() << " ms with msgid: " << sendResult.getMsgId() << endl;
}
} catch (const MQException& e) {
std::cout << "send failed: " << e.what() << std::endl;
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.notify_one();
return;
}
}
}
int main(int argc, char* argv[]) {
RocketmqSendAndConsumerArgs info;
if (!ParseArgs(argc, argv, &info)) {
exit(-1);
}
PrintRocketmqSendAndConsumerArgs(info);
DefaultMQProducer producer("please_rename_unique_group_name");
producer.setNamesrvAddr(info.namesrv);
producer.setNamesrvDomain(info.namesrv_domain);
producer.setGroupName(info.groupname);
producer.setInstanceName(info.groupname);
producer.setSessionCredentials("mq acesskey", "mq secretkey", "ALIYUN");
producer.setSendMsgTimeout(500);
producer.setTcpTransportTryLockTimeout(1000);
producer.setTcpTransportConnectTimeout(400);
producer.start();
std::vector<std::shared_ptr<std::thread>> work_pool;
auto start = std::chrono::system_clock::now();
int msgcount = g_msgCount.load();
g_tps.start();
int threadCount = info.thread_count;
for (int j = 0; j < threadCount; j++) {
std::shared_ptr<std::thread> th = std::make_shared<std::thread>(SyncProducerWorker, &info, &producer);
work_pool.push_back(th);
}
{
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.wait(lck);
g_quit.store(true);
}
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n"
<< "========================finished==============================\n";
for (size_t th = 0; th != work_pool.size(); ++th) {
work_pool[th]->join();
}
producer.shutdown();
return 0;
}

View File

@@ -0,0 +1,88 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "CCommon.h"
#include "CMessage.h"
#include "CProducer.h"
#include "CSendResult.h"
#ifdef _WIN32
#include <windows.h>
#else
#include <memory.h>
#include <unistd.h>
#endif
void thread_sleep(unsigned milliseconds) {
#ifdef _WIN32
Sleep(milliseconds);
#else
usleep(milliseconds * 1000); // takes microseconds
#endif
}
void SendSuccessCallback(CSendResult result) {
printf("async send success, msgid:%s\n", result.msgId);
}
void SendExceptionCallback(CMQException e) {
char msg[1024];
snprintf(msg, sizeof(msg), "error:%d, msg:%s, file:%s:%d", e.error, e.msg, e.file, e.line);
printf("async send exception %s\n", msg);
}
void StartSendMessage(CProducer* producer) {
int i = 0;
int ret_code = 0;
char body[128];
CMessage* msg = CreateMessage("T_TestTopic");
SetMessageTags(msg, "Test_Tag");
SetMessageKeys(msg, "Test_Keys");
for (i = 0; i < 10; i++) {
memset(body, 0, sizeof(body));
snprintf(body, sizeof(body), "new message body, index %d", i);
SetMessageBody(msg, body);
ret_code = SendMessageAsync(producer, msg, SendSuccessCallback, SendExceptionCallback);
printf("async send message[%d] return code: %d\n", i, ret_code);
thread_sleep(1000);
}
DestroyMessage(msg);
}
void CreateProducerAndStartSendMessage(int i) {
printf("Producer Initializing.....\n");
CProducer* producer = CreateProducer("Group_producer");
SetProducerNameServerAddress(producer, "127.0.0.1:9876");
if (i == 1) {
SetProducerSendMsgTimeout(producer, 3);
}
StartProducer(producer);
printf("Producer start.....\n");
StartSendMessage(producer);
ShutdownProducer(producer);
DestroyProducer(producer);
printf("Producer Shutdown!\n");
}
int main(int argc, char* argv[]) {
printf("Send Async successCallback.....\n");
CreateProducerAndStartSendMessage(0);
printf("Send Async exceptionCallback.....\n");
CreateProducerAndStartSendMessage(1);
return 0;
}

View File

@@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include "CBatchMessage.h"
#include "CCommon.h"
#include "CMessage.h"
#include "CProducer.h"
#include "CSendResult.h"
void StartSendMessage(CProducer* producer) {
int i = 0;
int ret_code = 0;
char body[128];
CBatchMessage* batchMessage = CreateBatchMessage("T_TestTopic");
for (i = 0; i < 10; i++) {
CMessage* msg = CreateMessage("T_TestTopic");
SetMessageTags(msg, "Test_Tag");
SetMessageKeys(msg, "Test_Keys");
memset(body, 0, sizeof(body));
snprintf(body, sizeof(body), "new message body, index %d", i);
SetMessageBody(msg, body);
AddMessage(batchMessage, msg);
}
CSendResult result;
ret_code = SendBatchMessage(producer, batchMessage, &result);
printf("SendBatchMessage %s .....\n", ret_code == 0 ? "Success" : ret_code == 11 ? "FAILED" : " It is null value");
DestroyBatchMessage(batchMessage);
}
void CreateProducerAndStartSendMessage() {
printf("Producer Initializing.....\n");
CProducer* producer = CreateProducer("Group_producer");
SetProducerNameServerAddress(producer, "127.0.0.1:9876");
StartProducer(producer);
printf("Producer start.....\n");
StartSendMessage(producer);
ShutdownProducer(producer);
DestroyProducer(producer);
printf("Producer Shutdown!\n");
}
int main(int argc, char* argv[]) {
printf("Send Batch.....\n");
CreateProducerAndStartSendMessage();
return 0;
}

View File

@@ -0,0 +1,60 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
project(example)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
link_directories(${LIBEVENT_LIBRARY})
link_directories(${JSONCPP_LIBRARY})
link_directories(${OPENSSL_LIBRARIES_DIR})
#if (BUILD_ROCKETMQ_SHARED)
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_ALL_DYN_LINK -shared ")
#endif()
file(GLOB files "*.c*")
foreach(file ${files})
get_filename_component(basename ${file} NAME_WE)
add_executable(${basename} ${file})
if(MSVC)
if(CMAKE_CONFIGURATION_TYPES STREQUAL "Release")
set_target_properties( ${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT" )
else()
set_target_properties( ${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMTD" )
endif()
endif()
if (MSVC)
if (BUILD_ROCKETMQ_SHARED)
target_link_libraries (${basename} rocketmq_shared ${deplibs}
${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES})
else()
target_link_libraries (${basename} rocketmq_static ${deplibs}
${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES})
endif()
else()
if (BUILD_ROCKETMQ_SHARED)
target_link_libraries (${basename} rocketmq_shared)
else()
target_link_libraries (${basename} rocketmq_static)
endif()
endif()
endforeach()

View File

@@ -0,0 +1,93 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "CCommon.h"
#include "CMessage.h"
#include "CProducer.h"
#include "CSendResult.h"
#ifdef _WIN32
#include <windows.h>
#else
#include <memory.h>
#include <unistd.h>
#endif
void thread_sleep(unsigned milliseconds) {
#ifdef _WIN32
Sleep(milliseconds);
#else
usleep(milliseconds * 1000); // takes microseconds
#endif
}
void SendSuccessCallback(CSendResult result) {
printf("async send success, msgid:%s\n", result.msgId);
}
void SendExceptionCallback(CMQException e) {
char msg[1024];
snprintf(msg, sizeof(msg), "error:%d, msg:%s, file:%s:%d", e.error, e.msg, e.file, e.line);
printf("async send exception %s\n", msg);
}
int aQueueSelectorCallback(int size, CMessage* msg, void* arg) {
return 0;
};
void StartSendMessage(CProducer* producer) {
int i = 0;
int ret_code = 0;
char body[128];
CMessage* msg = CreateMessage("topic_COrderlyAsyncProducer");
SetMessageTags(msg, "Test_Tag");
SetMessageKeys(msg, "Test_Keys");
for (i = 0; i < 10; i++) {
memset(body, 0, sizeof(body));
snprintf(body, sizeof(body), "new message body, index %d", i);
SetMessageBody(msg, body);
ret_code = SendMessageOrderlyAsync(producer, msg, aQueueSelectorCallback, (void*)&i, SendSuccessCallback,
SendExceptionCallback);
printf("async send message[%d] return code: %d\n", i, ret_code);
thread_sleep(1000);
}
DestroyMessage(msg);
}
void CreateProducerAndStartSendMessage(int i) {
printf("Producer Initializing.....\n");
CProducer* producer = CreateProducer("FooBarGroup1");
SetProducerNameServerAddress(producer, "192.168.0.149:9876");
if (i == 1) {
SetProducerSendMsgTimeout(producer, 3);
}
StartProducer(producer);
printf("Producer start.....\n");
StartSendMessage(producer);
ShutdownProducer(producer);
DestroyProducer(producer);
printf("Producer Shutdown!\n");
}
int main(int argc, char* argv[]) {
printf("COrderlyAsyncProducer successCallback.....\n");
CreateProducerAndStartSendMessage(0);
printf("COrderlyAsyncProducer exceptionCallback.....\n");
CreateProducerAndStartSendMessage(1);
return 0;
}

View File

@@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <thread>
#include "common.h"
using namespace rocketmq;
std::condition_variable g_finished;
std::mutex g_mtx;
std::atomic<bool> g_quit(false);
class SelectMessageQueueByHash : public MessageQueueSelector {
public:
MQMessageQueue select(const std::vector<MQMessageQueue>& mqs, const MQMessage& msg, void* arg) {
int orderId = *static_cast<int*>(arg);
int index = orderId % mqs.size();
return mqs[index];
}
};
SelectMessageQueueByHash g_mySelector;
void ProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) {
while (!g_quit.load()) {
if (g_msgCount.load() <= 0) {
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.notify_one();
}
MQMessage msg(info->topic, // topic
"*", // tag
info->body); // body
int orderId = 1;
SendResult sendResult =
producer->send(msg, &g_mySelector, static_cast<void*>(&orderId), info->retrytimes, info->SelectUnactiveBroker);
--g_msgCount;
}
}
int main(int argc, char* argv[]) {
RocketmqSendAndConsumerArgs info;
if (!ParseArgs(argc, argv, &info)) {
exit(-1);
}
DefaultMQProducer producer("please_rename_unique_group_name");
PrintRocketmqSendAndConsumerArgs(info);
producer.setNamesrvAddr(info.namesrv);
producer.setNamesrvDomain(info.namesrv_domain);
producer.setGroupName(info.groupname);
producer.setInstanceName(info.groupname);
producer.start();
int msgcount = g_msgCount.load();
std::vector<std::shared_ptr<std::thread>> work_pool;
int threadCount = info.thread_count;
for (int j = 0; j < threadCount; j++) {
std::shared_ptr<std::thread> th = std::make_shared<std::thread>(ProducerWorker, &info, &producer);
work_pool.push_back(th);
}
auto start = std::chrono::system_clock::now();
{
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.wait(lck);
g_quit.store(true);
}
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n"
<< "========================finished==============================\n";
for (size_t th = 0; th != work_pool.size(); ++th) {
work_pool[th]->join();
}
producer.shutdown();
return 0;
}

View File

@@ -0,0 +1,112 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <map>
#include <mutex>
#include <thread>
#include <vector>
#include "common.h"
using namespace rocketmq;
std::condition_variable g_finished;
std::mutex g_mtx;
std::atomic<int> g_consumedCount(0);
std::atomic<bool> g_quit(false);
TpsReportService g_tps;
class MyMsgListener : public MessageListenerOrderly {
public:
MyMsgListener() {}
virtual ~MyMsgListener() {}
virtual ConsumeStatus consumeMessage(const vector<MQMessageExt>& msgs) {
if (g_consumedCount.load() >= g_msgCount) {
std::unique_lock<std::mutex> lK(g_mtx);
g_quit.store(true);
g_finished.notify_one();
}
for (size_t i = 0; i < msgs.size(); i++) {
++g_consumedCount;
g_tps.Increment();
}
return CONSUME_SUCCESS;
}
};
int main(int argc, char* argv[]) {
RocketmqSendAndConsumerArgs info;
if (!ParseArgs(argc, argv, &info)) {
exit(-1);
}
PrintRocketmqSendAndConsumerArgs(info);
DefaultMQPushConsumer consumer("please_rename_unique_group_name");
DefaultMQProducer producer("please_rename_unique_group_name");
producer.setNamesrvAddr(info.namesrv);
producer.setGroupName("msg-persist-group_producer_sandbox");
producer.start();
consumer.setNamesrvAddr(info.namesrv);
consumer.setNamesrvDomain(info.namesrv_domain);
consumer.setGroupName(info.groupname);
consumer.setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET);
consumer.subscribe(info.topic, "*");
consumer.setConsumeThreadCount(info.thread_count);
consumer.setConsumeMessageBatchMaxSize(31);
if (info.syncpush)
consumer.setAsyncPull(false);
MyMsgListener msglistener;
consumer.registerMessageListener(&msglistener);
g_tps.start();
try {
consumer.start();
} catch (MQClientException& e) {
std::cout << e << std::endl;
}
int msgcount = g_msgCount.load();
for (int i = 0; i < msgcount; ++i) {
MQMessage msg(info.topic, // topic
"*", // tag
info.body); // body
try {
producer.send(msg);
} catch (MQException& e) {
std::cout << e << endl; // if catch excepiton , need re-send this msg by
// service
}
}
while (!g_quit.load()) {
std::unique_lock<std::mutex> lk(g_mtx);
g_finished.wait(lk);
}
producer.shutdown();
consumer.shutdown();
return 0;
}

View File

@@ -0,0 +1,73 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "CCommon.h"
#include "CMessage.h"
#include "CProducer.h"
#include "CSendResult.h"
#ifdef _WIN32
#include <windows.h>
#else
#include <memory.h>
#include <unistd.h>
#endif
void thread_sleep(unsigned int milliseconds) {
#ifdef _WIN32
Sleep(milliseconds);
#else
usleep(milliseconds * 1000); // suspend execution for microsecond intervals
#endif
}
void StartSendMessage(CProducer* producer) {
int i = 0;
char body[256];
CMessage* msg = CreateMessage("T_TestTopic");
SetMessageTags(msg, "Test_Tag");
SetMessageKeys(msg, "Test_Keys");
CSendResult result;
for (i = 0; i < 3; i++) {
memset(body, 0, sizeof(body));
snprintf(body, sizeof(body), "new message body, index %d", i);
SetMessageBody(msg, body);
int status = SendMessageSync(producer, msg, &result);
if (status == OK) {
printf("send message[%d] result status:%d, msgId:%s\n", i, (int)result.sendStatus, result.msgId);
} else {
printf("send message[%d] failed !\n", i);
}
thread_sleep(1000);
}
DestroyMessage(msg);
}
int main(int argc, char* argv[]) {
CProducer* producer = CreateProducer("Group_producer");
SetProducerNameServerAddress(producer, "127.0.0.1:9876");
StartProducer(producer);
printf("Producer initialized. \n");
StartSendMessage(producer);
ShutdownProducer(producer);
DestroyProducer(producer);
printf("Producer stopped !\n");
return 0;
}

View File

@@ -0,0 +1,95 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "CCommon.h"
#include "CMessageExt.h"
#include "CMessageQueue.h"
#include "CPullConsumer.h"
#include "CPullResult.h"
#ifdef _WIN32
#include <windows.h>
#else
#include <memory.h>
#include <unistd.h>
#endif
void thread_sleep(unsigned milliseconds) {
#ifdef _WIN32
Sleep(milliseconds);
#else
usleep(milliseconds * 1000); // takes microseconds
#endif
}
int main(int argc, char* argv[]) {
int i = 0, j = 0;
int ret = 0;
int size = 0;
CMessageQueue* mqs = NULL;
printf("PullConsumer Initializing....\n");
CPullConsumer* consumer = CreatePullConsumer("Group_Consumer_Test");
SetPullConsumerNameServerAddress(consumer, "172.17.0.2:9876");
StartPullConsumer(consumer);
printf("Pull Consumer Start...\n");
for (i = 1; i <= 5; i++) {
printf("FetchSubscriptionMessageQueues : %d times\n", i);
ret = FetchSubscriptionMessageQueues(consumer, "T_TestTopic", &mqs, &size);
if (ret != OK) {
printf("Get MQ Queue Failed,ErrorCode:%d\n", ret);
}
printf("Get MQ Size:%d\n", size);
for (j = 0; j < size; j++) {
int noNewMsg = 0;
long long tmpoffset = 0;
printf("Pull Message For Topic:%s,Queue:%s,QueueId:%d\n", mqs[j].topic, mqs[j].brokerName, mqs[j].queueId);
do {
int k = 0;
CPullResult pullResult = Pull(consumer, &mqs[j], "*", tmpoffset, 32);
if (pullResult.pullStatus != E_BROKER_TIMEOUT) {
tmpoffset = pullResult.nextBeginOffset;
}
printf("PullStatus:%d,MaxOffset:%lld,MinOffset:%lld,NextBegainOffset:%lld", pullResult.pullStatus,
pullResult.maxOffset, pullResult.minOffset, pullResult.nextBeginOffset);
switch (pullResult.pullStatus) {
case E_FOUND:
printf("Get Message Size:%d\n", pullResult.size);
for (k = 0; k < pullResult.size; ++k) {
printf("Got Message ID:%s,Body:%s\n", GetMessageId(pullResult.msgFoundList[k]),
GetMessageBody(pullResult.msgFoundList[k]));
}
break;
case E_NO_MATCHED_MSG:
noNewMsg = 1;
break;
default:
noNewMsg = 0;
}
ReleasePullResult(pullResult);
thread_sleep(100);
} while (noNewMsg == 0);
thread_sleep(1000);
}
thread_sleep(2000);
ReleaseSubscriptionMessageQueue(mqs);
}
thread_sleep(5000);
ShutdownPullConsumer(consumer);
DestroyPullConsumer(consumer);
printf("PullConsumer Shutdown!\n");
return 0;
}

View File

@@ -0,0 +1,120 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <map>
#include <vector>
#include "common.h"
using namespace rocketmq;
std::map<MQMessageQueue, uint64_t> g_offseTable;
void putMessageQueueOffset(MQMessageQueue mq, uint64_t offset) {
g_offseTable[mq] = offset;
}
uint64_t getMessageQueueOffset(MQMessageQueue mq) {
map<MQMessageQueue, uint64_t>::iterator it = g_offseTable.find(mq);
if (it != g_offseTable.end()) {
return it->second;
}
return 0;
}
int main(int argc, char* argv[]) {
RocketmqSendAndConsumerArgs info;
if (!ParseArgs(argc, argv, &info)) {
exit(-1);
}
PrintRocketmqSendAndConsumerArgs(info);
DefaultMQPullConsumer consumer("please_rename_unique_group_name");
consumer.setNamesrvAddr(info.namesrv);
consumer.setNamesrvDomain(info.namesrv_domain);
consumer.setGroupName(info.groupname);
consumer.setInstanceName(info.groupname);
consumer.registerMessageQueueListener(info.topic, NULL);
consumer.start();
std::vector<MQMessageQueue> mqs;
try {
consumer.fetchSubscribeMessageQueues(info.topic, mqs);
auto iter = mqs.begin();
for (; iter != mqs.end(); ++iter) {
std::cout << "mq:" << (*iter).toString() << endl;
}
} catch (MQException& e) {
std::cout << e << endl;
}
auto start = std::chrono::system_clock::now();
auto iter = mqs.begin();
for (; iter != mqs.end(); ++iter) {
MQMessageQueue mq = (*iter);
// if cluster model
// putMessageQueueOffset(mq, g_consumer.fetchConsumeOffset(mq,true));
// if broadcast model
// putMessageQueueOffset(mq, your last consume offset);
bool noNewMsg = false;
do {
try {
PullResult result = consumer.pull(mq, "*", getMessageQueueOffset(mq), 32);
g_msgCount += result.msgFoundList.size();
std::cout << result.msgFoundList.size() << std::endl;
// if pull request timeout or received NULL response, pullStatus will be
// setted to BROKER_TIMEOUT,
// And nextBeginOffset/minOffset/MaxOffset will be setted to 0
if (result.pullStatus != BROKER_TIMEOUT) {
putMessageQueueOffset(mq, result.nextBeginOffset);
PrintPullResult(&result);
} else {
cout << "broker timeout occur" << endl;
}
switch (result.pullStatus) {
case FOUND:
case NO_MATCHED_MSG:
case OFFSET_ILLEGAL:
case BROKER_TIMEOUT:
break;
case NO_NEW_MSG:
noNewMsg = true;
break;
default:
break;
}
} catch (MQClientException& e) {
std::cout << e << std::endl;
}
} while (!noNewMsg);
}
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "msg count: " << g_msgCount.load() << "\n";
std::cout << "per msg time: " << duration.count() / (double)g_msgCount.load() << "ms \n"
<< "========================finished==============================\n";
consumer.shutdown();
return 0;
}

View File

@@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "CCommon.h"
#include "CMessageExt.h"
#include "CPushConsumer.h"
#ifdef _WIN32
#include <windows.h>
#else
#include <memory.h>
#include <unistd.h>
#endif
void thread_sleep(unsigned milliseconds) {
#ifdef _WIN32
Sleep(milliseconds);
#else
usleep(milliseconds * 1000); // takes microseconds
#endif
}
int doConsumeMessage(struct CPushConsumer* consumer, CMessageExt* msgExt) {
printf("Hello,doConsumeMessage by Application!\n");
printf("Msg Topic:%s\n", GetMessageTopic(msgExt));
printf("Msg Tags:%s\n", GetMessageTags(msgExt));
printf("Msg Keys:%s\n", GetMessageKeys(msgExt));
printf("Msg Body:%s\n", GetMessageBody(msgExt));
return E_CONSUME_SUCCESS;
}
int main(int argc, char* argv[]) {
int i = 0;
printf("PushConsumer Initializing....\n");
CPushConsumer* consumer = CreatePushConsumer("Group_Consumer_Test");
SetPushConsumerNameServerAddress(consumer, "172.17.0.2:9876");
Subscribe(consumer, "T_TestTopic", "*");
RegisterMessageCallback(consumer, doConsumeMessage);
StartPushConsumer(consumer);
printf("Push Consumer Start...\n");
for (i = 0; i < 10; i++) {
printf("Now Running : %d S\n", i * 10);
thread_sleep(10000);
}
ShutdownPushConsumer(consumer);
DestroyPushConsumer(consumer);
printf("PushConsumer Shutdown!\n");
return 0;
}

View File

@@ -0,0 +1,125 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include <chrono>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <map>
#include <mutex>
#include <string>
#include <vector>
#include "common.h"
std::mutex g_mtx;
std::condition_variable g_finished;
TpsReportService g_tps;
using namespace rocketmq;
class MyMsgListener : public MessageListenerConcurrently {
public:
MyMsgListener() {}
virtual ~MyMsgListener() {}
virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) {
g_msgCount.store(g_msgCount.load() - msgs.size());
for (size_t i = 0; i < msgs.size(); ++i) {
g_tps.Increment();
// cout << "msg body: "<< msgs[i].getBody() << endl;
}
if (g_msgCount.load() <= 0) {
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.notify_one();
}
return CONSUME_SUCCESS;
}
};
int main(int argc, char* argv[]) {
RocketmqSendAndConsumerArgs info;
if (!ParseArgs(argc, argv, &info)) {
exit(-1);
}
PrintRocketmqSendAndConsumerArgs(info);
DefaultMQPushConsumer consumer("please_rename_unique_group_name");
DefaultMQProducer producer("please_rename_unique_group_name");
producer.setSessionCredentials("AccessKey", "SecretKey", "ALIYUN");
producer.setTcpTransportTryLockTimeout(1000);
producer.setTcpTransportConnectTimeout(400);
producer.setNamesrvDomain(info.namesrv_domain);
producer.setNamesrvAddr(info.namesrv);
producer.setGroupName("msg-persist-group_producer_sandbox");
producer.start();
consumer.setNamesrvAddr(info.namesrv);
consumer.setGroupName(info.groupname);
consumer.setSessionCredentials("AccessKey", "SecretKey", "ALIYUN");
consumer.setConsumeThreadCount(info.thread_count);
consumer.setNamesrvDomain(info.namesrv_domain);
consumer.setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET);
if (info.syncpush)
consumer.setAsyncPull(false); // set sync pull
if (info.broadcasting) {
consumer.setMessageModel(rocketmq::BROADCASTING);
}
consumer.setInstanceName(info.groupname);
consumer.subscribe(info.topic, "*");
consumer.setConsumeThreadCount(15);
consumer.setTcpTransportTryLockTimeout(1000);
consumer.setTcpTransportConnectTimeout(400);
MyMsgListener msglistener;
consumer.registerMessageListener(&msglistener);
try {
consumer.start();
} catch (MQClientException& e) {
cout << e << endl;
}
g_tps.start();
int msgcount = g_msgCount.load();
for (int i = 0; i < msgcount; ++i) {
MQMessage msg(info.topic, // topic
"*", // tag
info.body); // body
// std::this_thread::sleep_for(std::chrono::seconds(100000));
try {
producer.send(msg);
} catch (MQException& e) {
std::cout << e << endl; // if catch excepiton , need re-send this msg by
// service
}
}
{
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.wait(lck);
}
producer.shutdown();
consumer.shutdown();
return 0;
}

View File

@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WIN32
#include <unistd.h>
#endif
#include <stdio.h>
#include "CCommon.h"
#include "CMessageExt.h"
#include "CPushConsumer.h"
int doConsumeMessage(struct CPushConsumer* consumer, CMessageExt* msgExt) {
printf("Hello,doConsumeMessage by Application!\n");
printf("Msg Topic:%s\n", GetMessageTopic(msgExt));
printf("Msg Tags:%s\n", GetMessageTags(msgExt));
printf("Msg Keys:%s\n", GetMessageKeys(msgExt));
printf("Msg Body:%s\n", GetMessageBody(msgExt));
return E_CONSUME_SUCCESS;
}
int main(int argc, char* argv[]) {
int i = 0;
printf("PushConsumer Initializing....\n");
CPushConsumer* consumer = CreatePushConsumer("Group_Consumer_Test");
SetPushConsumerNameServerAddress(consumer, "127.0.0.1:9876");
Subscribe(consumer, "test", "*");
RegisterMessageCallbackOrderly(consumer, doConsumeMessage);
StartPushConsumer(consumer);
printf("Push Consumer Start...\n");
for (i = 0; i < 10; i++) {
printf("Now Running : %d S\n", i * 10);
sleep(10);
}
ShutdownPushConsumer(consumer);
DestroyPushConsumer(consumer);
printf("PushConsumer Shutdown!\n");
return 0;
}

View File

@@ -0,0 +1 @@
1. AsyncProducer 2. OrderlyProducer 3. SyncProducer

View File

@@ -0,0 +1,64 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <thread>
#include "common.h"
using namespace rocketmq;
int main(int argc, char* argv[]) {
RocketmqSendAndConsumerArgs info;
if (!ParseArgs(argc, argv, &info)) {
exit(-1);
}
PrintRocketmqSendAndConsumerArgs(info);
DefaultMQProducer producer("please_rename_unique_group_name");
producer.setNamesrvAddr(info.namesrv);
producer.setNamesrvDomain(info.namesrv_domain);
producer.setGroupName(info.groupname);
producer.setInstanceName(info.groupname);
producer.setSendMsgTimeout(500);
producer.setTcpTransportTryLockTimeout(1000);
producer.setTcpTransportConnectTimeout(400);
producer.start();
MQMessage msg(info.topic, // topic
"*", // tag
info.body); // body
// messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h
// 2h
msg.setDelayTimeLevel(5); // 1m
try {
SendResult sendResult = producer.send(msg, info.SelectUnactiveBroker);
} catch (const MQException& e) {
std::cout << "send failed: " << std::endl;
}
producer.shutdown();
return 0;
}

View File

@@ -0,0 +1,108 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <thread>
#include "common.h"
using namespace rocketmq;
std::atomic<bool> g_quit;
std::mutex g_mtx;
std::condition_variable g_finished;
TpsReportService g_tps;
void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) {
while (!g_quit.load()) {
if (g_msgCount.load() <= 0) {
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.notify_one();
}
MQMessage msg(info->topic, // topic
"*", // tag
info->body); // body
try {
auto start = std::chrono::system_clock::now();
SendResult sendResult = producer->send(msg, info->SelectUnactiveBroker);
g_tps.Increment();
--g_msgCount;
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
if (duration.count() >= 500) {
std::cout << "send RT more than: " << duration.count() << " ms with msgid: " << sendResult.getMsgId() << endl;
}
} catch (const MQException& e) {
std::cout << "send failed: " << std::endl;
}
}
}
int main(int argc, char* argv[]) {
RocketmqSendAndConsumerArgs info;
if (!ParseArgs(argc, argv, &info)) {
exit(-1);
}
PrintRocketmqSendAndConsumerArgs(info);
DefaultMQProducer producer("please_rename_unique_group_name");
producer.setNamesrvAddr(info.namesrv);
producer.setNamesrvDomain(info.namesrv_domain);
producer.setGroupName(info.groupname);
producer.setInstanceName(info.groupname);
producer.setSessionCredentials("mq acesskey", "mq secretkey", "ALIYUN");
producer.setSendMsgTimeout(500);
producer.setTcpTransportTryLockTimeout(1000);
producer.setTcpTransportConnectTimeout(400);
producer.start();
std::vector<std::shared_ptr<std::thread>> work_pool;
auto start = std::chrono::system_clock::now();
int msgcount = g_msgCount.load();
g_tps.start();
int threadCount = info.thread_count;
for (int j = 0; j < threadCount; j++) {
std::shared_ptr<std::thread> th = std::make_shared<std::thread>(SyncProducerWorker, &info, &producer);
work_pool.push_back(th);
}
{
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.wait(lck);
g_quit.store(true);
}
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n"
<< "========================finished==============================\n";
for (size_t th = 0; th != work_pool.size(); ++th) {
work_pool[th]->join();
}
producer.shutdown();
return 0;
}

View File

@@ -0,0 +1,135 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <atomic>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <thread>
#include "TransactionListener.h"
#include "TransactionMQProducer.h"
#include "TransactionSendResult.h"
#include "common.h"
using namespace rocketmq;
std::atomic<bool> g_quit;
std::mutex g_mtx;
std::condition_variable g_finished;
TpsReportService g_tps;
class MyTransactionListener : public TransactionListener {
virtual LocalTransactionState executeLocalTransaction(const MQMessage& msg, void* arg) {
if (!arg) {
std::cout << "executeLocalTransaction transactionId:" << msg.getTransactionId()
<< ", return state: COMMIT_MESAGE " << endl;
return LocalTransactionState::COMMIT_MESSAGE;
}
LocalTransactionState state = (LocalTransactionState)(*(int*)arg % 3);
std::cout << "executeLocalTransaction transactionId:" << msg.getTransactionId() << ", return state: " << state
<< endl;
return state;
}
virtual LocalTransactionState checkLocalTransaction(const MQMessageExt& msg) {
std::cout << "checkLocalTransaction enter msg:" << msg.toString() << endl;
return LocalTransactionState::COMMIT_MESSAGE;
}
};
void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, TransactionMQProducer* producer) {
while (!g_quit.load()) {
if (g_msgCount.load() <= 0) {
std::this_thread::sleep_for(std::chrono::seconds(60));
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.notify_one();
break;
}
MQMessage msg(info->topic, // topic
"*", // tag
info->body); // body
try {
auto start = std::chrono::system_clock::now();
std::cout << "before sendMessageInTransaction" << endl;
LocalTransactionState state = LocalTransactionState::UNKNOWN;
TransactionSendResult sendResult = producer->sendMessageInTransaction(msg, &state);
std::cout << "after sendMessageInTransaction msgId: " << sendResult.getMsgId() << endl;
g_tps.Increment();
--g_msgCount;
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
if (duration.count() >= 500) {
std::cout << "send RT more than: " << duration.count() << " ms with msgid: " << sendResult.getMsgId() << endl;
}
} catch (const MQException& e) {
std::cout << "send failed: " << e.what() << std::endl;
}
}
}
int main(int argc, char* argv[]) {
RocketmqSendAndConsumerArgs info;
if (!ParseArgs(argc, argv, &info)) {
exit(-1);
}
PrintRocketmqSendAndConsumerArgs(info);
TransactionMQProducer producer("please_rename_unique_group_name");
producer.setNamesrvAddr(info.namesrv);
producer.setNamesrvDomain(info.namesrv_domain);
producer.setGroupName(info.groupname);
producer.setInstanceName(info.groupname);
producer.setSessionCredentials("mq acesskey", "mq secretkey", "ALIYUN");
producer.setSendMsgTimeout(500);
producer.setTcpTransportTryLockTimeout(1000);
producer.setTcpTransportConnectTimeout(400);
producer.setLogLevel(eLOG_LEVEL_DEBUG);
producer.setTransactionListener(new MyTransactionListener());
producer.start();
std::vector<std::shared_ptr<std::thread>> work_pool;
auto start = std::chrono::system_clock::now();
int msgcount = g_msgCount.load();
g_tps.start();
int threadCount = info.thread_count;
for (int j = 0; j < threadCount; j++) {
std::shared_ptr<std::thread> th = std::make_shared<std::thread>(SyncProducerWorker, &info, &producer);
work_pool.push_back(th);
}
{
std::unique_lock<std::mutex> lck(g_mtx);
g_finished.wait(lck);
g_quit.store(true);
}
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n"
<< "========================finished==============================\n";
for (size_t th = 0; th != work_pool.size(); ++th) {
work_pool[th]->join();
}
producer.shutdown();
return 0;
}

View File

@@ -0,0 +1,220 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ROCKETMQ_CLIENT4CPP_EXAMPLE_COMMON_H_
#define ROCKETMQ_CLIENT4CPP_EXAMPLE_COMMON_H_
#include <atomic>
#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <vector>
#ifndef WIN32
#include "unistd.h"
#endif
#include "Arg_helper.h"
#include "DefaultMQProducer.h"
#include "DefaultMQPullConsumer.h"
#include "DefaultMQPushConsumer.h"
using namespace std;
std::atomic<int> g_msgCount(1);
class RocketmqSendAndConsumerArgs {
public:
RocketmqSendAndConsumerArgs()
: body("msgbody for test"),
thread_count(std::thread::hardware_concurrency()),
broadcasting(false),
syncpush(false),
SelectUnactiveBroker(false),
IsAutoDeleteSendCallback(false),
retrytimes(5),
PrintMoreInfo(false) {}
public:
std::string namesrv;
std::string namesrv_domain;
std::string groupname;
std::string topic;
std::string body;
int thread_count;
bool broadcasting;
bool syncpush;
bool SelectUnactiveBroker; // default select active broker
bool IsAutoDeleteSendCallback;
int retrytimes; // default retry 5 times;
bool PrintMoreInfo;
};
class TpsReportService {
public:
TpsReportService() : tps_interval_(1), quit_flag_(false), tps_count_(0) {}
void start() {
if (tps_thread_ == NULL) {
std::cout << "tps_thread_ is null" << std::endl;
return;
}
tps_thread_.reset(new std::thread(std::bind(&TpsReportService::TpsReport, this)));
}
~TpsReportService() {
quit_flag_.store(true);
if (tps_thread_ == NULL) {
std::cout << "tps_thread_ is null" << std::endl;
return;
}
if (tps_thread_->joinable())
tps_thread_->join();
}
void Increment() { ++tps_count_; }
void TpsReport() {
while (!quit_flag_.load()) {
std::this_thread::sleep_for(tps_interval_);
std::cout << "tps: " << tps_count_.load() << std::endl;
tps_count_.store(0);
}
}
private:
std::chrono::seconds tps_interval_;
std::shared_ptr<std::thread> tps_thread_;
std::atomic<bool> quit_flag_;
std::atomic<long> tps_count_;
};
void PrintPullResult(rocketmq::PullResult* result) {
std::cout << result->toString() << std::endl;
if (result->pullStatus == rocketmq::FOUND) {
std::cout << result->toString() << endl;
std::vector<rocketmq::MQMessageExt>::iterator it = result->msgFoundList.begin();
for (; it != result->msgFoundList.end(); ++it) {
cout << "=======================================================" << endl << (*it).toString() << endl;
}
}
}
static void PrintRocketmqSendAndConsumerArgs(const RocketmqSendAndConsumerArgs& info) {
std::cout << "nameserver: " << info.namesrv << endl
<< "topic: " << info.topic << endl
<< "groupname: " << info.groupname << endl
<< "produce content: " << info.body << endl
<< "msg count: " << g_msgCount.load() << endl
<< "thread count: " << info.thread_count << endl;
}
static void help() {
std::cout << "need option,like follow: \n"
<< "-n nameserver addr, if not set -n and -i ,no nameSrv will be got \n"
"-i nameserver domain name, if not set -n and -i ,no nameSrv will be "
"got \n"
"-g groupname \n"
"-t msg topic \n"
"-m messagecout(default value: 1) \n"
"-c content(default value: only test ) \n"
"-b (BROADCASTING model, default value: CLUSTER) \n"
"-s sync push(default is async push)\n"
"-r setup retry times(default value: 5 times)\n"
"-u select active broker to send msg(default value: false)\n"
"-d use AutoDeleteSendcallback by cpp client(defalut value: false) \n"
"-T thread count of send msg or consume msg(defalut value: system cpu "
"core number) \n"
"-v print more details information \n";
}
static bool ParseArgs(int argc, char* argv[], RocketmqSendAndConsumerArgs* info) {
#ifndef WIN32
int ch;
while ((ch = getopt(argc, argv, "n:i:g:t:m:c:b:s:h:r:T:bu")) != -1) {
switch (ch) {
case 'n':
info->namesrv.insert(0, optarg);
break;
case 'i':
info->namesrv_domain.insert(0, optarg);
break;
case 'g':
info->groupname.insert(0, optarg);
break;
case 't':
info->topic.insert(0, optarg);
break;
case 'm':
g_msgCount.store(atoi(optarg));
break;
case 'c':
info->body.insert(0, optarg);
break;
case 'b':
info->broadcasting = true;
break;
case 's':
info->syncpush = true;
break;
case 'r':
info->retrytimes = atoi(optarg);
break;
case 'u':
info->SelectUnactiveBroker = true;
break;
case 'T':
info->thread_count = atoi(optarg);
break;
case 'v':
info->PrintMoreInfo = true;
break;
case 'h':
help();
return false;
default:
help();
return false;
}
}
#else
rocketmq::Arg_helper arg_help(argc, argv);
info->namesrv = arg_help.get_option_value("-n");
info->namesrv_domain = arg_help.get_option_value("-i");
info->groupname = arg_help.get_option_value("-g");
info->topic = arg_help.get_option_value("-t");
info->broadcasting = atoi(arg_help.get_option_value("-b").c_str());
string msgContent(arg_help.get_option_value("-c"));
if (!msgContent.empty())
info->body = msgContent;
info->syncpush = atoi(arg_help.get_option_value("-s").c_str());
int retrytimes = atoi(arg_help.get_option_value("-r").c_str());
if (retrytimes > 0)
info->retrytimes = retrytimes;
info->SelectUnactiveBroker = atoi(arg_help.get_option_value("-u").c_str());
int thread_count = atoi(arg_help.get_option_value("-T").c_str());
if (thread_count > 0)
info->thread_count = thread_count;
info->PrintMoreInfo = atoi(arg_help.get_option_value("-v").c_str());
g_msgCount = atoi(arg_help.get_option_value("-m").c_str());
#endif
if (info->groupname.empty() || info->topic.empty() || (info->namesrv_domain.empty() && info->namesrv.empty())) {
std::cout << "please use -g to setup groupname and -t setup topic \n";
help();
return false;
}
return true;
}
#endif // ROCKETMQ_CLIENT4CPP_EXAMPLE_COMMON_H_

View File

@@ -0,0 +1,77 @@
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
TMPFILE=".clang_format_file.tmp"
FORMAT="{BasedOnStyle: Chromium, ColumnLimit: 120, TabWidth: 2}"
function Usage
{
echo "Usage: $0 want-format-file|want-format-dir ..."
#echo "Currently only format a file or dir at a time"
}
#Setp1 check clang-format support
if ! which clang-format &> /dev/null; then
echo -e "\033[32m !!!!!!please install clang-format \033[0m"
exit 1
fi
#Setp2 check weather incoming format file
if [ ! $# -ge 1 ];then
Usage
exit 1
fi
for dest in "$@"
do
if [ ! -e $dest ]; then
echo -e "\033[32m $dest not exists,please check this file weather exists \033[0m"
fi
done
#Setp3 get filelist
for dest in $*
do
if [ -f $dest ];then
files="$files $dest"
elif [ -d $dest ];then
files="$files `ls $dest/*.cpp $dest/*.h $dest/*.cc 2>/dev/null`"
else
echo -e "\033[32m $dest sorry current $0 only support regular file or dir \033[0m"
fi
done
#Setp4 use clang-format format dest file
for file in $files
do
echo $file
clang-format $file > $TMPFILE
if [ -e $TMPFILE ];then
filesize=`wc -c $TMPFILE |cut -d " " -f1`
if [ $filesize -eq 0 ];then
echo -e "\033[32m formt file error,May be because of the size of the source file is 0, or format program error \033[0m"
exit 1
fi
fi
#Setp4 replace source file
mv -f $TMPFILE $file
done

View File

@@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARG_HELPER_H_
#define _ARG_HELPER_H_
#include <string>
#include <vector>
#include "RocketMQClient.h"
namespace rocketmq {
class ROCKETMQCLIENT_API Arg_helper {
public:
Arg_helper(int argc, char* argv[]);
Arg_helper(std::string arg_str_);
std::string get_option(int idx_) const;
bool is_enable_option(std::string opt_) const;
std::string get_option_value(std::string opt_) const;
private:
std::vector<std::string> m_args;
};
} // namespace rocketmq
#endif //<!_ARG_HELPER_H_;

View File

@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __SENDCALLBACK_H__
#define __SENDCALLBACK_H__
#include "MQClientException.h"
#include "PullResult.h"
#include "RocketMQClient.h"
#include "SendResult.h"
namespace rocketmq {
struct AsyncCallback {};
typedef enum sendCallbackType { noAutoDeleteSendCallback = 0, autoDeleteSendCallback = 1 } sendCallbackType;
class ROCKETMQCLIENT_API SendCallback : public AsyncCallback {
public:
virtual ~SendCallback() {}
virtual void onSuccess(SendResult& sendResult) = 0;
virtual void onException(MQException& e) = 0;
virtual sendCallbackType getSendCallbackType() { return noAutoDeleteSendCallback; }
};
// async SendCallback will be deleted automatically by rocketmq cpp after invoke callback interface
class ROCKETMQCLIENT_API AutoDeleteSendCallBack : public SendCallback {
public:
virtual ~AutoDeleteSendCallBack() {}
virtual void onSuccess(SendResult& sendResult) = 0;
virtual void onException(MQException& e) = 0;
virtual sendCallbackType getSendCallbackType() { return autoDeleteSendCallback; }
};
class ROCKETMQCLIENT_API PullCallback : public AsyncCallback {
public:
virtual ~PullCallback() {}
virtual void onSuccess(MQMessageQueue& mq, PullResult& result, bool bProducePullRequest) = 0;
virtual void onException(MQException& e) = 0;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_BATCHMESSAGE_H__
#define __C_BATCHMESSAGE_H__
#include "CCommon.h"
#include "CMessage.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct CBatchMessage CBatchMessage;
ROCKETMQCLIENT_API CBatchMessage* CreateBatchMessage();
ROCKETMQCLIENT_API int AddMessage(CBatchMessage* batchMsg, CMessage* msg);
ROCKETMQCLIENT_API int DestroyBatchMessage(CBatchMessage* batchMsg);
#ifdef __cplusplus
}
#endif
#endif //__C_BATCHMESSAGE_H__

View File

@@ -0,0 +1,91 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_COMMON_H__
#define __C_COMMON_H__
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_MESSAGE_ID_LENGTH 256
#define MAX_TOPIC_LENGTH 512
#define MAX_BROKER_NAME_ID_LENGTH 256
#define MAX_SDK_VERSION_LENGTH 256
#define DEFAULT_SDK_VERSION "DefaultVersion"
typedef enum _CStatus_ {
// Success
OK = 0,
// Failed, null pointer value
NULL_POINTER = 1,
MALLOC_FAILED = 2,
PRODUCER_ERROR_CODE_START = 10,
PRODUCER_START_FAILED = 10,
PRODUCER_SEND_SYNC_FAILED = 11,
PRODUCER_SEND_ONEWAY_FAILED = 12,
PRODUCER_SEND_ORDERLY_FAILED = 13,
PRODUCER_SEND_ASYNC_FAILED = 14,
PRODUCER_SEND_ORDERLYASYNC_FAILED = 15,
PRODUCER_SEND_TRANSACTION_FAILED = 16,
PUSHCONSUMER_ERROR_CODE_START = 20,
PUSHCONSUMER_START_FAILED = 20,
PULLCONSUMER_ERROR_CODE_START = 30,
PULLCONSUMER_START_FAILED = 30,
PULLCONSUMER_FETCH_MQ_FAILED = 31,
PULLCONSUMER_FETCH_MESSAGE_FAILED = 32,
Not_Support = 500,
NOT_SUPPORT_NOW = -1
} CStatus;
typedef enum _CLogLevel_ {
E_LOG_LEVEL_FATAL = 1,
E_LOG_LEVEL_ERROR = 2,
E_LOG_LEVEL_WARN = 3,
E_LOG_LEVEL_INFO = 4,
E_LOG_LEVEL_DEBUG = 5,
E_LOG_LEVEL_TRACE = 6,
E_LOG_LEVEL_LEVEL_NUM = 7
} CLogLevel;
#ifdef WIN32
#ifdef ROCKETMQCLIENT_EXPORTS
#ifdef _WINDLL
#define ROCKETMQCLIENT_API __declspec(dllexport)
#else
#define ROCKETMQCLIENT_API
#endif
#else
#ifdef ROCKETMQCLIENT_IMPORT
#define ROCKETMQCLIENT_API __declspec(dllimport)
#else
#define ROCKETMQCLIENT_API
#endif
#endif
#else
#define ROCKETMQCLIENT_API
#endif
typedef enum _CMessageModel_ { BROADCASTING, CLUSTERING } CMessageModel;
typedef enum _CTraceModel_ { OPEN, CLOSE } CTraceModel;
#ifdef __cplusplus
}
#endif
#endif //__C_COMMON_H__

View File

@@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CERROR_MESSAGE_H__
#define __CERROR_MESSAGE_H__
#include "CCommon.h"
#ifdef __cplusplus
extern "C" {
#endif
ROCKETMQCLIENT_API const char* GetLatestErrorMessage(); // Return the last error message
#ifdef __cplusplus
}
#endif
#endif //__CERROR_MESSAGE_H__

View File

@@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_MQEXCPTION_H__
#define __C_MQEXCPTION_H__
#include "CCommon.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_EXEPTION_MSG_LENGTH 512
#define MAX_EXEPTION_FILE_LENGTH 256
#define MAX_EXEPTION_TYPE_LENGTH 128
typedef struct _CMQException_ {
int error;
int line;
char file[MAX_EXEPTION_FILE_LENGTH];
char msg[MAX_EXEPTION_MSG_LENGTH];
char type[MAX_EXEPTION_TYPE_LENGTH];
} CMQException;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_MESSAGE_H__
#define __C_MESSAGE_H__
#include "CCommon.h"
#ifdef __cplusplus
extern "C" {
#endif
// typedef struct _CMessage_ CMessage;
typedef struct CMessage CMessage;
ROCKETMQCLIENT_API CMessage* CreateMessage(const char* topic);
ROCKETMQCLIENT_API int DestroyMessage(CMessage* msg);
ROCKETMQCLIENT_API int SetMessageTopic(CMessage* msg, const char* topic);
ROCKETMQCLIENT_API int SetMessageTags(CMessage* msg, const char* tags);
ROCKETMQCLIENT_API int SetMessageKeys(CMessage* msg, const char* keys);
ROCKETMQCLIENT_API int SetMessageBody(CMessage* msg, const char* body);
ROCKETMQCLIENT_API int SetByteMessageBody(CMessage* msg, const char* body, int len);
ROCKETMQCLIENT_API int SetMessageProperty(CMessage* msg, const char* key, const char* value);
ROCKETMQCLIENT_API int SetDelayTimeLevel(CMessage* msg, int level);
ROCKETMQCLIENT_API const char* GetOriginMessageTopic(CMessage* msg);
ROCKETMQCLIENT_API const char* GetOriginMessageTags(CMessage* msg);
ROCKETMQCLIENT_API const char* GetOriginMessageKeys(CMessage* msg);
ROCKETMQCLIENT_API const char* GetOriginMessageBody(CMessage* msg);
ROCKETMQCLIENT_API const char* GetOriginMessageProperty(CMessage* msg, const char* key);
ROCKETMQCLIENT_API int GetOriginDelayTimeLevel(CMessage* msg);
#ifdef __cplusplus
}
#endif
#endif //__C_MESSAGE_H__

View File

@@ -0,0 +1,49 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_MESSAGE_EXT_H__
#define __C_MESSAGE_EXT_H__
#include "CCommon.h"
#ifdef __cplusplus
extern "C" {
#endif
// typedef struct _CMessageExt_ _CMessageExt;
typedef struct CMessageExt CMessageExt;
ROCKETMQCLIENT_API const char* GetMessageTopic(CMessageExt* msgExt);
ROCKETMQCLIENT_API const char* GetMessageTags(CMessageExt* msgExt);
ROCKETMQCLIENT_API const char* GetMessageKeys(CMessageExt* msgExt);
ROCKETMQCLIENT_API const char* GetMessageBody(CMessageExt* msgExt);
ROCKETMQCLIENT_API const char* GetMessageProperty(CMessageExt* msgExt, const char* key);
ROCKETMQCLIENT_API const char* GetMessageId(CMessageExt* msgExt);
ROCKETMQCLIENT_API int GetMessageDelayTimeLevel(CMessageExt* msgExt);
ROCKETMQCLIENT_API int GetMessageQueueId(CMessageExt* msgExt);
ROCKETMQCLIENT_API int GetMessageReconsumeTimes(CMessageExt* msgExt);
ROCKETMQCLIENT_API int GetMessageStoreSize(CMessageExt* msgExt);
ROCKETMQCLIENT_API long long GetMessageBornTimestamp(CMessageExt* msgExt);
ROCKETMQCLIENT_API long long GetMessageStoreTimestamp(CMessageExt* msgExt);
ROCKETMQCLIENT_API long long GetMessageQueueOffset(CMessageExt* msgExt);
ROCKETMQCLIENT_API long long GetMessageCommitLogOffset(CMessageExt* msgExt);
ROCKETMQCLIENT_API long long GetMessagePreparedTransactionOffset(CMessageExt* msgExt);
#ifdef __cplusplus
}
#endif
#endif //__C_MESSAGE_EXT_H__

View File

@@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_MESSAGE_QUEUE_H__
#define __C_MESSAGE_QUEUE_H__
#include "CCommon.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _CMessageQueue_ {
char topic[MAX_TOPIC_LENGTH];
char brokerName[MAX_BROKER_NAME_ID_LENGTH];
int queueId;
} CMessageQueue;
#ifdef __cplusplus
}
#endif
#endif //__C_MESSAGE_H__

View File

@@ -0,0 +1,109 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_PRODUCER_H__
#define __C_PRODUCER_H__
#include "CBatchMessage.h"
#include "CMQException.h"
#include "CMessage.h"
#include "CMessageExt.h"
#include "CSendResult.h"
#include "CTransactionStatus.h"
#ifdef __cplusplus
extern "C" {
#endif
// typedef struct _CProducer_ _CProducer;
typedef struct CProducer CProducer;
typedef int (*QueueSelectorCallback)(int size, CMessage* msg, void* arg);
typedef void (*CSendSuccessCallback)(CSendResult result);
typedef void (*CSendExceptionCallback)(CMQException e);
typedef void (*COnSendSuccessCallback)(CSendResult result, CMessage* msg, void* userData);
typedef void (*COnSendExceptionCallback)(CMQException e, CMessage* msg, void* userData);
typedef CTransactionStatus (*CLocalTransactionCheckerCallback)(CProducer* producer, CMessageExt* msg, void* data);
typedef CTransactionStatus (*CLocalTransactionExecutorCallback)(CProducer* producer, CMessage* msg, void* data);
ROCKETMQCLIENT_API CProducer* CreateProducer(const char* groupId);
ROCKETMQCLIENT_API CProducer* CreateOrderlyProducer(const char* groupId);
ROCKETMQCLIENT_API CProducer* CreateTransactionProducer(const char* groupId,
CLocalTransactionCheckerCallback callback,
void* userData);
ROCKETMQCLIENT_API int DestroyProducer(CProducer* producer);
ROCKETMQCLIENT_API int StartProducer(CProducer* producer);
ROCKETMQCLIENT_API int ShutdownProducer(CProducer* producer);
ROCKETMQCLIENT_API const char* ShowProducerVersion(CProducer* producer);
ROCKETMQCLIENT_API int SetProducerNameServerAddress(CProducer* producer, const char* namesrv);
ROCKETMQCLIENT_API int SetProducerNameServerDomain(CProducer* producer, const char* domain);
ROCKETMQCLIENT_API int SetProducerGroupName(CProducer* producer, const char* groupName);
ROCKETMQCLIENT_API int SetProducerInstanceName(CProducer* producer, const char* instanceName);
ROCKETMQCLIENT_API int SetProducerSessionCredentials(CProducer* producer,
const char* accessKey,
const char* secretKey,
const char* onsChannel);
ROCKETMQCLIENT_API int SetProducerLogPath(CProducer* producer, const char* logPath);
ROCKETMQCLIENT_API int SetProducerLogFileNumAndSize(CProducer* producer, int fileNum, long fileSize);
ROCKETMQCLIENT_API int SetProducerLogLevel(CProducer* producer, CLogLevel level);
ROCKETMQCLIENT_API int SetProducerSendMsgTimeout(CProducer* producer, int timeout);
ROCKETMQCLIENT_API int SetProducerCompressLevel(CProducer* producer, int level);
ROCKETMQCLIENT_API int SetProducerMaxMessageSize(CProducer* producer, int size);
ROCKETMQCLIENT_API int SetProducerMessageTrace(CProducer* consumer, CTraceModel openTrace);
ROCKETMQCLIENT_API int SendMessageSync(CProducer* producer, CMessage* msg, CSendResult* result);
ROCKETMQCLIENT_API int SendBatchMessage(CProducer* producer, CBatchMessage* msg, CSendResult* result);
ROCKETMQCLIENT_API int SendMessageAsync(CProducer* producer,
CMessage* msg,
CSendSuccessCallback cSendSuccessCallback,
CSendExceptionCallback cSendExceptionCallback);
ROCKETMQCLIENT_API int SendAsync(CProducer* producer,
CMessage* msg,
COnSendSuccessCallback cSendSuccessCallback,
COnSendExceptionCallback cSendExceptionCallback,
void* userData);
ROCKETMQCLIENT_API int SendMessageOneway(CProducer* producer, CMessage* msg);
ROCKETMQCLIENT_API int SendMessageOnewayOrderly(CProducer* producer,
CMessage* msg,
QueueSelectorCallback selector,
void* arg);
ROCKETMQCLIENT_API int SendMessageOrderly(CProducer* producer,
CMessage* msg,
QueueSelectorCallback callback,
void* arg,
int autoRetryTimes,
CSendResult* result);
ROCKETMQCLIENT_API int SendMessageOrderlyAsync(CProducer* producer,
CMessage* msg,
QueueSelectorCallback callback,
void* arg,
CSendSuccessCallback cSendSuccessCallback,
CSendExceptionCallback cSendExceptionCallback);
ROCKETMQCLIENT_API int SendMessageOrderlyByShardingKey(CProducer* producer,
CMessage* msg,
const char* shardingKey,
CSendResult* result);
ROCKETMQCLIENT_API int SendMessageTransaction(CProducer* producer,
CMessage* msg,
CLocalTransactionExecutorCallback callback,
void* userData,
CSendResult* result);
#ifdef __cplusplus
}
#endif
#endif //__C_PRODUCER_H__

View File

@@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_PULL_CONSUMER_H__
#define __C_PULL_CONSUMER_H__
#include "CCommon.h"
#include "CMessageExt.h"
#include "CMessageQueue.h"
#include "CPullResult.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct CPullConsumer CPullConsumer;
ROCKETMQCLIENT_API CPullConsumer* CreatePullConsumer(const char* groupId);
ROCKETMQCLIENT_API int DestroyPullConsumer(CPullConsumer* consumer);
ROCKETMQCLIENT_API int StartPullConsumer(CPullConsumer* consumer);
ROCKETMQCLIENT_API int ShutdownPullConsumer(CPullConsumer* consumer);
ROCKETMQCLIENT_API const char* ShowPullConsumerVersion(CPullConsumer* consumer);
ROCKETMQCLIENT_API int SetPullConsumerGroupID(CPullConsumer* consumer, const char* groupId);
ROCKETMQCLIENT_API const char* GetPullConsumerGroupID(CPullConsumer* consumer);
ROCKETMQCLIENT_API int SetPullConsumerNameServerAddress(CPullConsumer* consumer, const char* namesrv);
ROCKETMQCLIENT_API int SetPullConsumerNameServerDomain(CPullConsumer* consumer, const char* domain);
ROCKETMQCLIENT_API int SetPullConsumerSessionCredentials(CPullConsumer* consumer,
const char* accessKey,
const char* secretKey,
const char* channel);
ROCKETMQCLIENT_API int SetPullConsumerLogPath(CPullConsumer* consumer, const char* logPath);
ROCKETMQCLIENT_API int SetPullConsumerLogFileNumAndSize(CPullConsumer* consumer, int fileNum, long fileSize);
ROCKETMQCLIENT_API int SetPullConsumerLogLevel(CPullConsumer* consumer, CLogLevel level);
ROCKETMQCLIENT_API int FetchSubscriptionMessageQueues(CPullConsumer* consumer,
const char* topic,
CMessageQueue** mqs,
int* size);
ROCKETMQCLIENT_API int ReleaseSubscriptionMessageQueue(CMessageQueue* mqs);
ROCKETMQCLIENT_API CPullResult
Pull(CPullConsumer* consumer, const CMessageQueue* mq, const char* subExpression, long long offset, int maxNums);
ROCKETMQCLIENT_API int ReleasePullResult(CPullResult pullResult);
#ifdef __cplusplus
}
#endif
#endif //__C_PUSH_CONSUMER_H__

View File

@@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_PULL_RESULT_H__
#define __C_PULL_RESULT_H__
#include "CCommon.h"
#include "CMessageExt.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum E_CPullStatus {
E_FOUND,
E_NO_NEW_MSG,
E_NO_MATCHED_MSG,
E_OFFSET_ILLEGAL,
E_BROKER_TIMEOUT // indicate pull request timeout or received NULL response
} CPullStatus;
typedef struct _CPullResult_ {
CPullStatus pullStatus;
long long nextBeginOffset;
long long minOffset;
long long maxOffset;
CMessageExt** msgFoundList;
int size;
void* pData;
} CPullResult;
#ifdef __cplusplus
}
#endif
#endif //__C_PULL_RESULT_H__

View File

@@ -0,0 +1,67 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_PUSH_CONSUMER_H__
#define __C_PUSH_CONSUMER_H__
#include "CCommon.h"
#include "CMessageExt.h"
#ifdef __cplusplus
extern "C" {
#endif
// typedef struct _CConsumer_ _CConsumer;
typedef struct CPushConsumer CPushConsumer;
typedef enum E_CConsumeStatus { E_CONSUME_SUCCESS = 0, E_RECONSUME_LATER = 1 } CConsumeStatus;
typedef int (*MessageCallBack)(CPushConsumer*, CMessageExt*);
ROCKETMQCLIENT_API CPushConsumer* CreatePushConsumer(const char* groupId);
ROCKETMQCLIENT_API int DestroyPushConsumer(CPushConsumer* consumer);
ROCKETMQCLIENT_API int StartPushConsumer(CPushConsumer* consumer);
ROCKETMQCLIENT_API int ShutdownPushConsumer(CPushConsumer* consumer);
ROCKETMQCLIENT_API const char* ShowPushConsumerVersion(CPushConsumer* consumer);
ROCKETMQCLIENT_API int SetPushConsumerGroupID(CPushConsumer* consumer, const char* groupId);
ROCKETMQCLIENT_API const char* GetPushConsumerGroupID(CPushConsumer* consumer);
ROCKETMQCLIENT_API int SetPushConsumerNameServerAddress(CPushConsumer* consumer, const char* namesrv);
ROCKETMQCLIENT_API int SetPushConsumerNameServerDomain(CPushConsumer* consumer, const char* domain);
ROCKETMQCLIENT_API int Subscribe(CPushConsumer* consumer, const char* topic, const char* expression);
ROCKETMQCLIENT_API int RegisterMessageCallbackOrderly(CPushConsumer* consumer, MessageCallBack pCallback);
ROCKETMQCLIENT_API int RegisterMessageCallback(CPushConsumer* consumer, MessageCallBack pCallback);
ROCKETMQCLIENT_API int UnregisterMessageCallbackOrderly(CPushConsumer* consumer);
ROCKETMQCLIENT_API int UnregisterMessageCallback(CPushConsumer* consumer);
ROCKETMQCLIENT_API int SetPushConsumerThreadCount(CPushConsumer* consumer, int threadCount);
ROCKETMQCLIENT_API int SetPushConsumerMessageBatchMaxSize(CPushConsumer* consumer, int batchSize);
ROCKETMQCLIENT_API int SetPushConsumerInstanceName(CPushConsumer* consumer, const char* instanceName);
ROCKETMQCLIENT_API int SetPushConsumerSessionCredentials(CPushConsumer* consumer,
const char* accessKey,
const char* secretKey,
const char* channel);
ROCKETMQCLIENT_API int SetPushConsumerLogPath(CPushConsumer* consumer, const char* logPath);
ROCKETMQCLIENT_API int SetPushConsumerLogFileNumAndSize(CPushConsumer* consumer, int fileNum, long fileSize);
ROCKETMQCLIENT_API int SetPushConsumerLogLevel(CPushConsumer* consumer, CLogLevel level);
ROCKETMQCLIENT_API int SetPushConsumerMessageModel(CPushConsumer* consumer, CMessageModel messageModel);
ROCKETMQCLIENT_API int SetPushConsumerMaxCacheMessageSize(CPushConsumer* consumer, int maxCacheSize);
ROCKETMQCLIENT_API int SetPushConsumerMaxCacheMessageSizeInMb(CPushConsumer* consumer, int maxCacheSizeInMb);
ROCKETMQCLIENT_API int SetPushConsumerMessageTrace(CPushConsumer* consumer, CTraceModel openTrace);
#ifdef __cplusplus
}
#endif
#endif //__C_PUSH_CONSUMER_H__

View File

@@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_SEND_RESULT_H__
#define __C_SEND_RESULT_H__
#include "CCommon.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum E_CSendStatus_ {
E_SEND_OK = 0,
E_SEND_FLUSH_DISK_TIMEOUT = 1,
E_SEND_FLUSH_SLAVE_TIMEOUT = 2,
E_SEND_SLAVE_NOT_AVAILABLE = 3
} CSendStatus;
typedef struct _SendResult_ {
CSendStatus sendStatus;
char msgId[MAX_MESSAGE_ID_LENGTH];
long long offset;
} CSendResult;
#ifdef __cplusplus
}
#endif
#endif //__C_PRODUCER_H__

View File

@@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __C_TRANSACTION_STATUS_H__
#define __C_TRANSACTION_STATUS_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef enum E_CTransactionStatus {
E_COMMIT_TRANSACTION = 0,
E_ROLLBACK_TRANSACTION = 1,
E_UNKNOWN_TRANSACTION = 2,
} CTransactionStatus;
#ifdef __cplusplus
}
#endif
#endif //__C_TRANSACTION_STATUS_H__

View File

@@ -0,0 +1,61 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CONSUMETYPE_H__
#define __CONSUMETYPE_H__
namespace rocketmq {
//<!***************************************************************************
enum ConsumeType {
CONSUME_ACTIVELY,
CONSUME_PASSIVELY,
};
//<!***************************************************************************
enum ConsumeFromWhere {
/**
*new consumer will consume from end offset of queue,
* and then consume from last consumed offset of queue follow-up
*/
CONSUME_FROM_LAST_OFFSET,
// @Deprecated
CONSUME_FROM_LAST_OFFSET_AND_FROM_MIN_WHEN_BOOT_FIRST,
// @Deprecated
CONSUME_FROM_MIN_OFFSET,
// @Deprecated
CONSUME_FROM_MAX_OFFSET,
/**
*new consumer will consume from first offset of queue,
* and then consume from last consumed offset of queue follow-up
*/
CONSUME_FROM_FIRST_OFFSET,
/**
*new consumer will consume from the queue offset specified by timestamp,
* and then consume from last consumed offset of queue follow-up
*/
CONSUME_FROM_TIMESTAMP,
};
//<!***************************************************************************
enum MessageModel {
BROADCASTING,
CLUSTERING,
};
//<!***************************************************************************
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,152 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __DEFAULTMQPRODUCER_H__
#define __DEFAULTMQPRODUCER_H__
#include "AsyncCallback.h"
#include "MQClient.h"
#include "MQMessageQueue.h"
#include "MQSelector.h"
#include "RocketMQClient.h"
#include "SendResult.h"
#include "SessionCredentials.h"
namespace rocketmq {
class DefaultMQProducerImpl;
class ROCKETMQCLIENT_API DefaultMQProducer {
public:
DefaultMQProducer(const std::string& groupname);
virtual ~DefaultMQProducer();
virtual void start();
virtual void shutdown();
virtual std::string version();
virtual SendResult send(MQMessage& msg, bool bSelectActiveBroker = false);
virtual SendResult send(MQMessage& msg, const MQMessageQueue& mq);
virtual SendResult send(MQMessage& msg, MessageQueueSelector* selector, void* arg);
virtual SendResult send(MQMessage& msg,
MessageQueueSelector* selector,
void* arg,
int autoRetryTimes,
bool bActiveBroker = false);
virtual SendResult send(std::vector<MQMessage>& msgs);
virtual SendResult send(std::vector<MQMessage>& msgs, const MQMessageQueue& mq);
virtual void send(MQMessage& msg, SendCallback* pSendCallback, bool bSelectActiveBroker = false);
virtual void send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* pSendCallback);
virtual void send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* pSendCallback);
virtual void sendOneway(MQMessage& msg, bool bSelectActiveBroker = false);
virtual void sendOneway(MQMessage& msg, const MQMessageQueue& mq);
virtual void sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg);
const std::string& getNamesrvAddr() const;
void setNamesrvAddr(const std::string& namesrvAddr);
void setSessionCredentials(const std::string& accessKey,
const std::string& secretKey,
const std::string& accessChannel);
const SessionCredentials& getSessionCredentials() const;
const std::string& getNamesrvDomain() const;
void setNamesrvDomain(const std::string& namesrvDomain);
const std::string& getNameSpace() const;
void setNameSpace(const std::string& nameSpace);
const std::string& getGroupName() const;
void setGroupName(const std::string& groupname);
const std::string& getInstanceName() const;
void setInstanceName(const std::string& instanceName);
/**
* Log configuration interface, default LOG_LEVEL is LOG_LEVEL_INFO, default
* log file num is 3, each log size is 100M
**/
void setLogLevel(elogLevel inputLevel);
elogLevel getLogLevel();
void setLogPath(const std::string& logPath);
void setLogFileSizeAndNum(int fileNum, long perFileSize); // perFileSize is MB unit
int getSendMsgTimeout() const;
void setSendMsgTimeout(int sendMsgTimeout);
/*
* If msgBody size is large than compressMsgBodyOverHowmuch
* rocketmq cpp will compress msgBody according to compressLevel
*/
int getCompressMsgBodyOverHowmuch() const;
void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch);
int getCompressLevel() const;
void setCompressLevel(int compressLevel);
int getMaxMessageSize() const;
void setMaxMessageSize(int maxMessageSize);
int getRetryTimes() const;
void setRetryTimes(int times);
int getRetryTimes4Async() const;
void setRetryTimes4Async(int times);
/** Set TcpTransport pull thread num, which dermine the num of threads to
* distribute network data,
* 1. its default value is CPU num, it must be setted before producer/consumer
* start, minimum value is CPU num;
* 2. this pullThread num must be tested on your environment to find the best
* value for RT of sendMsg or delay time of consume msg before you change it;
* 3. producer and consumer need different pullThread num, if set this num,
* producer and consumer must set different instanceName.
**/
void setTcpTransportPullThreadNum(int num);
int getTcpTransportPullThreadNum() const;
/** Timeout of tcp connect, it is same meaning for both producer and consumer;
* 1. default value is 3000ms
* 2. input parameter could only be milliSecond, suggestion value is
* 1000-3000ms;
**/
void setTcpTransportConnectTimeout(uint64_t timeout); // ms
uint64_t getTcpTransportConnectTimeout() const;
/** Timeout of tryLock tcpTransport before sendMsg/pullMsg, if timeout,
* returns NULL
* 1. paremeter unit is ms, default value is 3000ms, the minimun value is 1000ms
* suggestion value is 3000ms;
* 2. if configured with value smaller than 1000ms, the tryLockTimeout value
* will be setted to 1000ms
**/
void setTcpTransportTryLockTimeout(uint64_t timeout); // ms
uint64_t getTcpTransportTryLockTimeout() const;
void setUnitName(std::string unitName);
const std::string& getUnitName() const;
void setMessageTrace(bool messageTrace);
bool getMessageTrace() const;
void setEnableSsl(bool enableSsl);
bool getEnableSsl() const;
void setSslPropertyFile(const std::string& sslPropertyFile);
const std::string& getSslPropertyFile() const;
private:
DefaultMQProducerImpl* impl;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,152 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __DEFAULTMQPULLCONSUMER_H__
#define __DEFAULTMQPULLCONSUMER_H__
#include <set>
#include <string>
#include "AsyncCallback.h"
#include "ConsumeType.h"
#include "MQClient.h"
#include "MQMessage.h"
#include "MQMessageExt.h"
#include "MQMessageQueue.h"
#include "MQueueListener.h"
#include "PullResult.h"
#include "RocketMQClient.h"
#include "SessionCredentials.h"
namespace rocketmq {
class SubscriptionData;
class DefaultMQPullConsumerImpl;
class ROCKETMQCLIENT_API DefaultMQPullConsumer {
public:
DefaultMQPullConsumer(const std::string& groupname);
virtual ~DefaultMQPullConsumer();
virtual void start();
virtual void shutdown();
virtual std::string version();
const std::string& getNamesrvAddr() const;
void setNamesrvAddr(const std::string& namesrvAddr);
void setSessionCredentials(const std::string& accessKey,
const std::string& secretKey,
const std::string& accessChannel);
const SessionCredentials& getSessionCredentials() const;
const std::string& getNamesrvDomain() const;
void setNamesrvDomain(const std::string& namesrvDomain);
const std::string& getInstanceName() const;
void setInstanceName(const std::string& instanceName);
const std::string& getNameSpace() const;
void setNameSpace(const std::string& nameSpace);
const std::string& getGroupName() const;
void setGroupName(const std::string& groupname);
void setEnableSsl(bool enableSsl);
bool getEnableSsl() const;
void setSslPropertyFile(const std::string& sslPropertyFile);
const std::string& getSslPropertyFile() const;
/**
* Log configuration interface, default LOG_LEVEL is LOG_LEVEL_INFO, default
* log file num is 3, each log size is 100M
**/
void setLogLevel(elogLevel inputLevel);
elogLevel getLogLevel();
void setLogPath(const std::string& logPath);
void setLogFileSizeAndNum(int fileNum, long perFileSize); // perFileSize is MB unit
virtual void fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs);
/**
* Pull message from specified queue, if no msg in queue, return directly
*
* @param mq
* specify the pulled queue
* @param subExpression
* set filter expression for pulled msg, broker will filter msg actively
* Now only OR operation is supported, eg: "tag1 || tag2 || tag3"
* if subExpression is setted to "null" or "*", all msg will be subscribed
* @param offset
* specify the started pull offset
* @param maxNums
* specify max msg num by per pull
* @return
* PullResult
*/
virtual PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64 offset, int maxNums);
virtual void pull(const MQMessageQueue& mq,
const std::string& subExpression,
int64 offset,
int maxNums,
PullCallback* pPullCallback);
/**
* Pull msg from specified queue, if no msg, broker will suspend the pull request 20s
*
* @param mq
* specify the pulled queue
* @param subExpression
* set filter expression for pulled msg, broker will filter msg actively
* Now only OR operation is supported, eg: "tag1 || tag2 || tag3"
* if subExpression is setted to "null" or "*", all msg will be subscribed
* @param offset
* specify the started pull offset
* @param maxNums
* specify max msg num by per pull
* @return
* accroding to PullResult
*/
virtual PullResult pullBlockIfNotFound(const MQMessageQueue& mq,
const std::string& subExpression,
int64 offset,
int maxNums);
virtual void pullBlockIfNotFound(const MQMessageQueue& mq,
const std::string& subExpression,
int64 offset,
int maxNums,
PullCallback* pPullCallback);
void persistConsumerOffset();
void persistConsumerOffsetByResetOffset();
void updateTopicSubscribeInfo(const std::string& topic, std::vector<MQMessageQueue>& info);
ConsumeFromWhere getConsumeFromWhere();
void getSubscriptions(std::vector<SubscriptionData>&);
void updateConsumeOffset(const MQMessageQueue& mq, int64 offset);
void removeConsumeOffset(const MQMessageQueue& mq);
void registerMessageQueueListener(const std::string& topic, MQueueListener* pListener);
int64 fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore);
void fetchMessageQueuesInBalance(const std::string& topic, std::vector<MQMessageQueue> mqs);
void persistConsumerOffset4PullConsumer(const MQMessageQueue& mq);
private:
DefaultMQPullConsumerImpl* impl;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,148 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __DEFAULTMQPUSHCONSUMER_H__
#define __DEFAULTMQPUSHCONSUMER_H__
#include <string>
#include "AsyncCallback.h"
#include "ConsumeType.h"
#include "MQClient.h"
#include "MQMessageListener.h"
#include "MQMessageQueue.h"
#include "SessionCredentials.h"
namespace rocketmq {
class DefaultMQPushConsumerImpl;
class ROCKETMQCLIENT_API DefaultMQPushConsumer {
public:
DefaultMQPushConsumer(const std::string& groupname);
virtual ~DefaultMQPushConsumer();
virtual void start();
virtual void shutdown();
virtual std::string version();
const std::string& getNamesrvAddr() const;
void setNamesrvAddr(const std::string& namesrvAddr);
void setSessionCredentials(const std::string& accessKey,
const std::string& secretKey,
const std::string& accessChannel);
const SessionCredentials& getSessionCredentials() const;
void subscribe(const std::string& topic, const std::string& subExpression);
void registerMessageListener(MQMessageListener* pMessageListener);
MessageListenerType getMessageListenerType();
MessageModel getMessageModel() const;
void setMessageModel(MessageModel messageModel);
void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere);
ConsumeFromWhere getConsumeFromWhere();
const std::string& getNamesrvDomain() const;
void setNamesrvDomain(const std::string& namesrvDomain);
const std::string& getInstanceName() const;
void setInstanceName(const std::string& instanceName);
const std::string& getNameSpace() const;
void setNameSpace(const std::string& nameSpace);
const std::string& getGroupName() const;
void setGroupName(const std::string& groupname);
void setEnableSsl(bool enableSsl);
bool getEnableSsl() const;
void setSslPropertyFile(const std::string& sslPropertyFile);
const std::string& getSslPropertyFile() const;
/**
* Log configuration interface, default LOG_LEVEL is LOG_LEVEL_INFO, default
* log file num is 3, each log size is 100M
**/
void setLogLevel(elogLevel inputLevel);
elogLevel getLogLevel();
void setLogPath(const std::string& logPath);
void setLogFileSizeAndNum(int fileNum, long perFileSize); // perFileSize is MB unit
void setConsumeThreadCount(int threadCount);
int getConsumeThreadCount() const;
void setMaxReconsumeTimes(int maxReconsumeTimes);
int getMaxReconsumeTimes() const;
void setPullMsgThreadPoolCount(int threadCount);
int getPullMsgThreadPoolCount() const;
void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize);
int getConsumeMessageBatchMaxSize() const;
/**
* Set max cache msg size perQueue in memory if consumer could not consume msgs
* immediately
* default maxCacheMsgSize perQueue is 1000, set range is:1~65535
**/
void setMaxCacheMsgSizePerQueue(int maxCacheSize);
int getMaxCacheMsgSizePerQueue() const;
/** Set TcpTransport pull thread num, which dermine the num of threads to
* distribute network data,
* 1. its default value is CPU num, it must be setted before producer/consumer
* start, minimum value is CPU num;
* 2. this pullThread num must be tested on your environment to find the best
* value for RT of sendMsg or delay time of consume msg before you change it;
* 3. producer and consumer need different pullThread num, if set this num,
* producer and consumer must set different instanceName.
**/
void setTcpTransportPullThreadNum(int num);
int getTcpTransportPullThreadNum() const;
/** Timeout of tcp connect, it is same meaning for both producer and consumer;
* 1. default value is 3000ms
* 2. input parameter could only be milliSecond, suggestion value is
* 1000-3000ms;
**/
void setTcpTransportConnectTimeout(uint64_t timeout); // ms
uint64_t getTcpTransportConnectTimeout() const;
/** Timeout of tryLock tcpTransport before sendMsg/pullMsg, if timeout,
* returns NULL
* 1. paremeter unit is ms, default value is 3000ms, the minimun value is 1000ms
* suggestion value is 3000ms;
* 2. if configured with value smaller than 1000ms, the tryLockTimeout value
* will be setted to 1000ms
**/
void setTcpTransportTryLockTimeout(uint64_t timeout); // ms
uint64_t getTcpTransportTryLockTimeout() const;
void setUnitName(std::string unitName);
const std::string& getUnitName() const;
void setAsyncPull(bool asyncFlag);
void setMessageTrace(bool messageTrace);
bool getMessageTrace() const;
private:
DefaultMQPushConsumerImpl* impl;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MQADMIN_H__
#define __MQADMIN_H__
namespace rocketmq {
enum elogLevel {
eLOG_LEVEL_FATAL = 1,
eLOG_LEVEL_ERROR = 2,
eLOG_LEVEL_WARN = 3,
eLOG_LEVEL_INFO = 4,
eLOG_LEVEL_DEBUG = 5,
eLOG_LEVEL_TRACE = 6,
eLOG_LEVEL_LEVEL_NUM = 7
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,88 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MQCLIENTEXCEPTION_H__
#define __MQCLIENTEXCEPTION_H__
#include <string.h>
#include <exception>
#include <ostream>
#include <sstream>
#include <string>
#include "RocketMQClient.h"
namespace rocketmq {
class ROCKETMQCLIENT_API MQException : public std::exception {
public:
MQException(const std::string& msg, int error, const char* file, int line) throw()
: m_error(error), m_line(line), m_file(file) {
try {
std::stringstream ss;
ss << "msg: " << msg << ",error:" << error << ",in file <" << file << "> line:" << line;
m_msg = ss.str();
} catch (...) {
}
}
MQException(const std::string& msg, int error, const char* file, const char* type, int line) throw()
: m_error(error), m_line(line), m_file(file), m_type(type) {
try {
std::stringstream ss;
ss << "msg: " << msg << ",error:" << error << ",in file <" << file << "> line:" << line;
m_msg = ss.str();
} catch (...) {
}
}
virtual ~MQException() throw() {}
const char* what() const throw() { return m_msg.c_str(); }
int GetError() const throw() { return m_error; }
virtual const char* GetType() const throw() { return m_type.c_str(); }
int GetLine() { return m_line; }
const char* GetFile() { return m_file.c_str(); }
protected:
int m_error;
int m_line;
std::string m_msg;
std::string m_file;
std::string m_type;
};
inline std::ostream& operator<<(std::ostream& os, const MQException& e) {
os << "Type: " << e.GetType() << " , " << e.what();
return os;
}
#define DEFINE_MQCLIENTEXCEPTION(name) \
class ROCKETMQCLIENT_API name : public MQException { \
public: \
name(const std::string& msg, int error, const char* file, int line) throw() \
: MQException(msg, error, file, #name, line) {} \
virtual const char* GetType() const throw() { return m_type.c_str(); } \
};
DEFINE_MQCLIENTEXCEPTION(MQClientException)
DEFINE_MQCLIENTEXCEPTION(MQBrokerException)
DEFINE_MQCLIENTEXCEPTION(InterruptedException)
DEFINE_MQCLIENTEXCEPTION(RemotingException)
DEFINE_MQCLIENTEXCEPTION(UnknownHostException)
#define THROW_MQEXCEPTION(e, msg, err) throw e(msg, err, __FILE__, __LINE__)
#define NEW_MQEXCEPTION(e, msg, err) e(msg, err, __FILE__, __LINE__)
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,141 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MESSAGE_H__
#define __MESSAGE_H__
#include <map>
#include <sstream>
#include <string>
#include <vector>
#include "RocketMQClient.h"
namespace rocketmq {
class ROCKETMQCLIENT_API MQMessage {
public:
MQMessage();
MQMessage(const std::string& topic, const std::string& body);
MQMessage(const std::string& topic, const std::string& tags, const std::string& body);
MQMessage(const std::string& topic, const std::string& tags, const std::string& keys, const std::string& body);
MQMessage(const std::string& topic,
const std::string& tags,
const std::string& keys,
const int flag,
const std::string& body,
bool waitStoreMsgOK);
virtual ~MQMessage();
MQMessage(const MQMessage& other);
MQMessage& operator=(const MQMessage& other);
void setProperty(const std::string& name, const std::string& value);
const std::string& getProperty(const std::string& name) const;
const std::string& getTopic() const;
void setTopic(const std::string& topic);
void setTopic(const char* body, int len);
const std::string& getTags() const;
void setTags(const std::string& tags);
const std::string& getKeys() const;
void setKeys(const std::string& keys);
void setKeys(const std::vector<std::string>& keys);
int getDelayTimeLevel() const;
void setDelayTimeLevel(int level);
bool isWaitStoreMsgOK() const;
void setWaitStoreMsgOK(bool waitStoreMsgOK);
int getFlag() const;
void setFlag(int flag);
int getSysFlag() const;
void setSysFlag(int sysFlag);
const std::string& getBody() const;
void setBody(const char* body, int len);
void setBody(const std::string& body);
void setTransactionId(const std::string& id) { m_transactionId = id; }
std::string getTransactionId() const { return m_transactionId; }
std::map<std::string, std::string> getProperties() const;
void setProperties(std::map<std::string, std::string>& properties);
const std::string toString() const {
std::stringstream ss;
std::string tags = getTags();
ss << "Message [topic=" << m_topic << ", flag=" << m_flag << ", tag=" << tags << "]";
return ss.str();
}
protected:
friend class MQDecoder;
void setPropertyInternal(const std::string& name, const std::string& value);
void setPropertiesInternal(std::map<std::string, std::string>& properties);
void Init(const std::string& topic,
const std::string& tags,
const std::string& keys,
const int flag,
const std::string& body,
bool waitStoreMsgOK);
public:
static const std::string PROPERTY_KEYS;
static const std::string PROPERTY_TAGS;
static const std::string PROPERTY_WAIT_STORE_MSG_OK;
static const std::string PROPERTY_DELAY_TIME_LEVEL;
static const std::string PROPERTY_RETRY_TOPIC;
static const std::string PROPERTY_REAL_TOPIC;
static const std::string PROPERTY_REAL_QUEUE_ID;
static const std::string PROPERTY_TRANSACTION_PREPARED;
static const std::string PROPERTY_PRODUCER_GROUP;
static const std::string PROPERTY_MIN_OFFSET;
static const std::string PROPERTY_MAX_OFFSET;
static const std::string PROPERTY_BUYER_ID;
static const std::string PROPERTY_ORIGIN_MESSAGE_ID;
static const std::string PROPERTY_TRANSFER_FLAG;
static const std::string PROPERTY_CORRECTION_FLAG;
static const std::string PROPERTY_MQ2_FLAG;
static const std::string PROPERTY_RECONSUME_TIME;
static const std::string PROPERTY_MSG_REGION;
static const std::string PROPERTY_TRACE_SWITCH;
static const std::string PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX;
static const std::string PROPERTY_MAX_RECONSUME_TIMES;
static const std::string PROPERTY_CONSUME_START_TIMESTAMP;
static const std::string PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET;
static const std::string PROPERTY_TRANSACTION_CHECK_TIMES;
static const std::string PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS;
static const std::string KEY_SEPARATOR;
protected:
int m_sysFlag;
private:
std::string m_topic;
int m_flag;
std::string m_body;
std::string m_transactionId;
std::map<std::string, std::string> m_properties;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,115 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MESSAGEEXT_H__
#define __MESSAGEEXT_H__
#ifdef WIN32
#include <Windows.h>
#include <Winsock2.h>
#else
#include <sys/socket.h>
#endif
#include "MQMessage.h"
#include "RocketMQClient.h"
namespace rocketmq {
//<!message extend class, which was generated on broker;
class ROCKETMQCLIENT_API MQMessageExt : public MQMessage {
public:
MQMessageExt();
MQMessageExt(int queueId,
int64 bornTimestamp,
sockaddr bornHost,
int64 storeTimestamp,
sockaddr storeHost,
std::string msgId);
virtual ~MQMessageExt();
static int parseTopicFilterType(int sysFlag);
int getQueueId() const;
void setQueueId(int queueId);
int64 getBornTimestamp() const;
void setBornTimestamp(int64 bornTimestamp);
sockaddr getBornHost() const;
std::string getBornHostString() const;
std::string getBornHostNameString() const;
void setBornHost(const sockaddr& bornHost);
int64 getStoreTimestamp() const;
void setStoreTimestamp(int64 storeTimestamp);
sockaddr getStoreHost() const;
std::string getStoreHostString() const;
void setStoreHost(const sockaddr& storeHost);
const std::string& getMsgId() const;
void setMsgId(const std::string& msgId);
const std::string& getOffsetMsgId() const;
void setOffsetMsgId(const std::string& offsetMsgId);
int getBodyCRC() const;
void setBodyCRC(int bodyCRC);
int64 getQueueOffset() const;
void setQueueOffset(int64 queueOffset);
int64 getCommitLogOffset() const;
void setCommitLogOffset(int64 physicOffset);
int getStoreSize() const;
void setStoreSize(int storeSize);
int getReconsumeTimes() const;
void setReconsumeTimes(int reconsumeTimes);
int64 getPreparedTransactionOffset() const;
void setPreparedTransactionOffset(int64 preparedTransactionOffset);
std::string toString() const {
std::stringstream ss;
ss << "MessageExt [queueId=" << m_queueId << ", storeSize=" << m_storeSize << ", queueOffset=" << m_queueOffset
<< ", sysFlag=" << m_sysFlag << ", bornTimestamp=" << m_bornTimestamp << ", bornHost=" << getBornHostString()
<< ", storeTimestamp=" << m_storeTimestamp << ", storeHost=" << getStoreHostString() << ", msgId=" << m_msgId
<< ", commitLogOffset=" << m_commitLogOffset << ", bodyCRC=" << m_bodyCRC
<< ", reconsumeTimes=" << m_reconsumeTimes << ", preparedTransactionOffset=" << m_preparedTransactionOffset
<< ", " << MQMessage::toString() << "]";
return ss.str();
}
private:
int64 m_queueOffset;
int64 m_commitLogOffset;
int64 m_bornTimestamp;
int64 m_storeTimestamp;
int64 m_preparedTransactionOffset;
int m_queueId;
int m_storeSize;
int m_bodyCRC;
int m_reconsumeTimes;
sockaddr m_bornHost;
sockaddr m_storeHost;
std::string m_msgId;
std::string m_offsetMsgId;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MESSAGELISTENER_H__
#define __MESSAGELISTENER_H__
#include <limits.h>
#include "MQMessageExt.h"
#include "MQMessageQueue.h"
namespace rocketmq {
//<!***************************************************************************
enum ConsumeStatus {
// consume success, msg will be cleard from memory
CONSUME_SUCCESS,
// consume fail, but will be re-consume by call messageLisenter again
RECONSUME_LATER
};
enum MessageListenerType { messageListenerDefaultly = 0, messageListenerOrderly = 1, messageListenerConcurrently = 2 };
class ROCKETMQCLIENT_API MQMessageListener {
public:
virtual ~MQMessageListener() {}
virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) = 0;
virtual MessageListenerType getMessageListenerType() { return messageListenerDefaultly; }
};
class ROCKETMQCLIENT_API MessageListenerOrderly : public MQMessageListener {
public:
virtual ~MessageListenerOrderly() {}
virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) = 0;
virtual MessageListenerType getMessageListenerType() { return messageListenerOrderly; }
};
class ROCKETMQCLIENT_API MessageListenerConcurrently : public MQMessageListener {
public:
virtual ~MessageListenerConcurrently() {}
virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) = 0;
virtual MessageListenerType getMessageListenerType() { return messageListenerConcurrently; }
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MQMESSAGEQUEUE_H__
#define __MQMESSAGEQUEUE_H__
#include <iomanip>
#include <sstream>
#include <string>
#include "RocketMQClient.h"
namespace rocketmq {
class ROCKETMQCLIENT_API MQMessageQueue {
public:
MQMessageQueue();
MQMessageQueue(const std::string& topic, const std::string& brokerName, int queueId);
MQMessageQueue(const MQMessageQueue& other);
MQMessageQueue& operator=(const MQMessageQueue& other);
std::string getTopic() const;
void setTopic(const std::string& topic);
std::string getBrokerName() const;
void setBrokerName(const std::string& brokerName);
int getQueueId() const;
void setQueueId(int queueId);
bool operator==(const MQMessageQueue& mq) const;
bool operator<(const MQMessageQueue& mq) const;
int compareTo(const MQMessageQueue& mq) const;
const std::string toString() const {
std::stringstream ss;
ss << "MessageQueue [topic=" << m_topic << ", brokerName=" << m_brokerName << ", queueId=" << m_queueId << "]";
return ss.str();
}
private:
std::string m_topic;
std::string m_brokerName;
int m_queueId;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,30 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _MQSELECTOR_H_
#define _MQSELECTOR_H_
#include "MQMessage.h"
#include "MQMessageQueue.h"
#include "RocketMQClient.h"
namespace rocketmq {
class ROCKETMQCLIENT_API MessageQueueSelector {
public:
virtual ~MessageQueueSelector() {}
virtual MQMessageQueue select(const std::vector<MQMessageQueue>& mqs, const MQMessage& msg, void* arg) = 0;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MESSAGEQUEUELISTENER_H__
#define __MESSAGEQUEUELISTENER_H__
#include <vector>
#include "RocketMQClient.h"
namespace rocketmq {
class ROCKETMQCLIENT_API MQueueListener {
public:
virtual ~MQueueListener() {}
virtual void messageQueueChanged(const std::string& topic,
std::vector<MQMessageQueue>& mqAll,
std::vector<MQMessageQueue>& mqDivided) = 0;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __PULLRESULT_H__
#define __PULLRESULT_H__
#include <sstream>
#include "MQMessageExt.h"
#include "RocketMQClient.h"
namespace rocketmq {
enum PullStatus {
FOUND,
NO_NEW_MSG,
NO_MATCHED_MSG,
OFFSET_ILLEGAL,
BROKER_TIMEOUT // indicate pull request timeout or received NULL response
};
static const char* EnumStrings[] = {"FOUND", "NO_NEW_MSG", "NO_MATCHED_MSG", "OFFSET_ILLEGAL", "BROKER_TIMEOUT"};
class ROCKETMQCLIENT_API PullResult {
public:
PullResult();
PullResult(PullStatus status);
PullResult(PullStatus pullStatus, int64 nextBeginOffset, int64 minOffset, int64 maxOffset);
PullResult(PullStatus pullStatus,
int64 nextBeginOffset,
int64 minOffset,
int64 maxOffset,
const std::vector<MQMessageExt>& src);
virtual ~PullResult();
std::string toString() {
std::stringstream ss;
ss << "PullResult [ pullStatus=" << EnumStrings[pullStatus] << ", nextBeginOffset=" << nextBeginOffset
<< ", minOffset=" << minOffset << ", maxOffset=" << maxOffset << ", msgFoundList=" << msgFoundList.size()
<< " ]";
return ss.str();
}
public:
PullStatus pullStatus;
int64 nextBeginOffset;
int64 minOffset;
int64 maxOffset;
std::vector<MQMessageExt> msgFoundList;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __ROCKETMQCLIENT_H__
#define __ROCKETMQCLIENT_H__
#ifdef WIN32
#ifdef ROCKETMQCLIENT_EXPORTS
#ifdef _WINDLL
#define ROCKETMQCLIENT_API __declspec(dllexport)
#else
#define ROCKETMQCLIENT_API
#endif
#else
#ifdef ROCKETMQCLIENT_IMPORT
#define ROCKETMQCLIENT_API __declspec(dllimport)
#else
#define ROCKETMQCLIENT_API
#endif
#endif
#else
#define ROCKETMQCLIENT_API
#endif
/** A platform-independent 8-bit signed integer type. */
typedef signed char int8;
/** A platform-independent 8-bit unsigned integer type. */
typedef unsigned char uint8;
/** A platform-independent 16-bit signed integer type. */
typedef signed short int16;
/** A platform-independent 16-bit unsigned integer type. */
typedef unsigned short uint16;
/** A platform-independent 32-bit signed integer type. */
typedef signed int int32;
/** A platform-independent 32-bit unsigned integer type. */
typedef unsigned int uint32;
/** A platform-independent 64-bit integer type. */
typedef long long int64;
/** A platform-independent 64-bit unsigned integer type. */
typedef unsigned long long uint64;
#endif

View File

@@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __SENDRESULT_H__
#define __SENDRESULT_H__
#include "MQMessageQueue.h"
#include "RocketMQClient.h"
namespace rocketmq {
enum SendStatus { SEND_OK, SEND_FLUSH_DISK_TIMEOUT, SEND_FLUSH_SLAVE_TIMEOUT, SEND_SLAVE_NOT_AVAILABLE };
class ROCKETMQCLIENT_API SendResult {
public:
SendResult();
SendResult(const SendStatus& sendStatus,
const std::string& msgId,
const std::string& offsetMsgId,
const MQMessageQueue& messageQueue,
int64 queueOffset);
SendResult(const SendStatus& sendStatus,
const std::string& msgId,
const std::string& offsetMsgId,
const MQMessageQueue& messageQueue,
int64 queueOffset,
const std::string& regionId);
virtual ~SendResult();
SendResult(const SendResult& other);
SendResult& operator=(const SendResult& other);
void setTransactionId(const std::string& id) { m_transactionId = id; }
std::string getTransactionId() { return m_transactionId; }
const std::string& getMsgId() const;
const std::string& getOffsetMsgId() const;
const std::string& getRegionId() const;
void setRegionId(const std::string& regionId);
SendStatus getSendStatus() const;
MQMessageQueue getMessageQueue() const;
int64 getQueueOffset() const;
std::string toString() const;
private:
SendStatus m_sendStatus;
std::string m_msgId;
std::string m_offsetMsgId;
MQMessageQueue m_messageQueue;
int64 m_queueOffset;
std::string m_transactionId;
std::string m_regionId;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,73 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __SESSIONCREDENTIALS_H__
#define __SESSIONCREDENTIALS_H__
#include "RocketMQClient.h"
namespace rocketmq {
class SessionCredentials {
public:
static const std::string AccessKey;
static const std::string SecretKey;
static const std::string Signature;
static const std::string SignatureMethod;
static const std::string ONSChannelKey;
SessionCredentials(std::string input_accessKey, std::string input_secretKey, const std::string& input_authChannel)
: accessKey(input_accessKey), secretKey(input_secretKey), authChannel(input_authChannel) {}
SessionCredentials() : authChannel("ALIYUN") {}
~SessionCredentials() {}
std::string getAccessKey() const { return accessKey; }
void setAccessKey(std::string input_accessKey) { accessKey = input_accessKey; }
std::string getSecretKey() const { return secretKey; }
void setSecretKey(std::string input_secretKey) { secretKey = input_secretKey; }
std::string getSignature() const { return signature; }
void setSignature(std::string input_signature) { signature = input_signature; }
std::string getSignatureMethod() const { return signatureMethod; }
void setSignatureMethod(std::string input_signatureMethod) { signatureMethod = input_signatureMethod; }
std::string getAuthChannel() const { return authChannel; }
void setAuthChannel(std::string input_channel) { authChannel = input_channel; }
bool isValid() const {
if (accessKey.empty() || secretKey.empty() || authChannel.empty())
return false;
return true;
}
private:
std::string accessKey;
std::string secretKey;
std::string signature;
std::string signatureMethod;
std::string authChannel;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __TRANSACTIONLISTENER_H__
#define __TRANSACTIONLISTENER_H__
#include "MQMessage.h"
#include "MQMessageExt.h"
#include "TransactionSendResult.h"
namespace rocketmq {
class ROCKETMQCLIENT_API TransactionListener {
public:
virtual ~TransactionListener() {}
/**
* When send transactional prepare(half) message succeed, this method will be invoked to execute local transaction.
*
* @param msg Half(prepare) message
* @param arg Custom business parameter
* @return Transaction state
*/
virtual LocalTransactionState executeLocalTransaction(const MQMessage& msg, void* arg) = 0;
/**
* When no response to prepare(half) message. broker will send check message to check the transaction status, and this
* method will be invoked to get local transaction status.
*
* @param msg Check message
* @return Transaction state
*/
virtual LocalTransactionState checkLocalTransaction(const MQMessageExt& msg) = 0;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,100 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __TRANSACTIONMQPRODUCER_H__
#define __TRANSACTIONMQPRODUCER_H__
#include <memory>
#include <string>
#include "MQClient.h"
#include "MQMessage.h"
#include "MQMessageExt.h"
#include "SessionCredentials.h"
#include "TransactionListener.h"
#include "TransactionSendResult.h"
namespace rocketmq {
class TransactionMQProducerImpl;
class ROCKETMQCLIENT_API TransactionMQProducer {
public:
TransactionMQProducer(const std::string& producerGroup);
virtual ~TransactionMQProducer();
void start();
void shutdown();
std::string version();
const std::string& getNamesrvAddr() const;
void setNamesrvAddr(const std::string& namesrvAddr);
const std::string& getNamesrvDomain() const;
void setNamesrvDomain(const std::string& namesrvDomain);
const std::string& getInstanceName() const;
void setInstanceName(const std::string& instanceName);
const std::string& getNameSpace() const;
void setNameSpace(const std::string& nameSpace);
const std::string& getGroupName() const;
void setGroupName(const std::string& groupname);
void setSessionCredentials(const std::string& accessKey,
const std::string& secretKey,
const std::string& accessChannel);
const SessionCredentials& getSessionCredentials() const;
void setUnitName(std::string unitName);
const std::string& getUnitName() const;
int getSendMsgTimeout() const;
void setSendMsgTimeout(int sendMsgTimeout);
void setTcpTransportPullThreadNum(int num);
int getTcpTransportPullThreadNum() const;
void setTcpTransportConnectTimeout(uint64_t timeout); // ms
uint64_t getTcpTransportConnectTimeout() const;
void setTcpTransportTryLockTimeout(uint64_t timeout); // ms
uint64_t getTcpTransportTryLockTimeout() const;
int getCompressMsgBodyOverHowmuch() const;
void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch);
int getCompressLevel() const;
void setCompressLevel(int compressLevel);
int getMaxMessageSize() const;
void setMaxMessageSize(int maxMessageSize);
void setLogLevel(elogLevel inputLevel);
elogLevel getLogLevel();
void setLogFileSizeAndNum(int fileNum, long perFileSize); // perFileSize is MB unit
void setMessageTrace(bool messageTrace);
bool getMessageTrace() const;
std::shared_ptr<TransactionListener> getTransactionListener();
void setTransactionListener(TransactionListener* listener);
TransactionSendResult sendMessageInTransaction(MQMessage& msg, void* arg);
void checkTransactionState(const std::string& addr,
const MQMessageExt& message,
long tranStateTableOffset,
long commitLogOffset,
const std::string& msgId,
const std::string& transactionId,
const std::string& offsetMsgId);
private:
TransactionMQProducerImpl* impl;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __TRANSACTIONSENDRESULT_H__
#define __TRANSACTIONSENDRESULT_H__
#include "SendResult.h"
namespace rocketmq {
enum LocalTransactionState { COMMIT_MESSAGE, ROLLBACK_MESSAGE, UNKNOWN };
class ROCKETMQCLIENT_API TransactionSendResult : public SendResult {
public:
TransactionSendResult() {}
TransactionSendResult(const SendStatus& sendStatus,
const std::string& msgId,
const std::string& offsetMsgId,
const MQMessageQueue& messageQueue,
int64 queueOffset)
: SendResult(sendStatus, msgId, offsetMsgId, messageQueue, queueOffset) {}
LocalTransactionState getLocalTransactionState() { return m_localTransactionState; }
void setLocalTransactionState(LocalTransactionState localTransactionState) {
m_localTransactionState = localTransactionState;
}
private:
LocalTransactionState m_localTransactionState;
};
} // namespace rocketmq
#endif

View File

@@ -0,0 +1,16 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
add_subdirectory(signature)

View File

@@ -0,0 +1,29 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
project(signature)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
aux_source_directory(src/ DIR_LIB_SRCS)
add_library(Signature STATIC ${DIR_LIB_SRCS})
target_link_libraries(Signature ${deplibs})
set_target_properties(Signature PROPERTIES OUTPUT_NAME "Signature")
# install
install(TARGETS Signature DESTINATION lib)
#install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include/rocketmq)

View File

@@ -0,0 +1,49 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BASE64_H
#define BASE64_H
/* Get size_t. */
#include <stddef.h>
/* Get bool. */
#include <stdbool.h>
#ifdef __cplusplus
namespace rocketmqSignature {
#endif
/* This uses that the expression (n+(k-1))/k means the smallest
integer >= n/k, i.e., the ceiling of n/k. */
#define BASE64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4)
extern bool isbase64(char ch);
extern void base64_encode(const char* in, size_t inlen, char* out, size_t outlen);
extern size_t base64_encode_alloc(const char* in, size_t inlen, char** out);
extern bool base64_decode(const char* in, size_t inlen, char* out, size_t* outlen);
extern bool base64_decode_alloc(const char* in, size_t inlen, char** out, size_t* outlen);
#ifdef __cplusplus
}
#endif
#endif /* BASE64_H */

View File

@@ -0,0 +1,70 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _HMAC_HMAC_H
#define _HMAC_HMAC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#ifndef SHA1_DIGEST_LEN
#define SHA1_DIGEST_LEN 20
#endif
#ifndef SHA256_DIGEST_LEN
#define SHA256_DIGEST_LEN 32
#endif
#ifndef SHA512_DIGEST_LEN
#define SHA512_DIGEST_LEN 64
#endif
/*
* hmac_sha1:
* hmac_sha256:
* hmac_sha512:
* Calculate Hashed Message Authentication Code with sha1/256/512 algorithm
* Caution: ret_buf should provide enough space for HMAC result.
*
* @key [in]: the secure-key string
* @key_len [in]: the length of secure-key
* @data [in]: data string could be calculated.
* @data_len [in]: the length of data. length is needed because strlen could not take effect.
* @ret_buf [out]: HMAC result stored in ret_buf.
*/
#ifdef __cplusplus
namespace rocketmqSignature {
#endif
extern int hmac_sha1(const void* key, size_t key_len, const void* data, size_t data_len, void* ret_buf);
extern int hmac_sha256(const void* key, size_t key_len, const void* data, size_t data_len, void* ret_buf);
extern int hmac_sha512(const void* key, size_t key_len, const void* data, size_t data_len, void* ret_buf);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PARAM_LIST_H
#define PARAM_LIST_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
namespace rocketmqSignature {
#endif
typedef struct _spas_param_node {
char* name;
char* value;
struct _spas_param_node* pnext;
} SPAS_PARAM_NODE;
typedef struct _spas_param_list {
SPAS_PARAM_NODE* phead;
unsigned int length; /* count of nodes */
unsigned int size; /* total size of string presentation */
} SPAS_PARAM_LIST;
extern SPAS_PARAM_LIST* create_param_list(void);
extern int add_param_to_list(SPAS_PARAM_LIST* list, const char* name, const char* value);
extern void free_param_list(SPAS_PARAM_LIST* list);
extern char* param_list_to_str(const SPAS_PARAM_LIST* list);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,84 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SHA1_H
#define SHA1_H 1
#include <stdio.h>
#include <stdint.h>
#ifdef __cplusplus
namespace rocketmqSignature {
#endif
#define SHA1_DIGEST_SIZE 20
/* Structure to save state of computation between the single steps. */
struct sha1_ctx {
uint32_t A;
uint32_t B;
uint32_t C;
uint32_t D;
uint32_t E;
uint32_t total[2];
uint32_t buflen;
uint32_t buffer[32];
};
/* Initialize structure containing state of computation. */
extern void sha1_init_ctx(struct sha1_ctx* ctx);
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is necessary that LEN is a multiple of 64!!! */
extern void sha1_process_block(const void* buffer, size_t len, struct sha1_ctx* ctx);
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is NOT required that LEN is a multiple of 64. */
extern void sha1_process_bytes(const void* buffer, size_t len, struct sha1_ctx* ctx);
/* Process the remaining bytes in the buffer and put result from CTX
in first 20 bytes following RESBUF. The result is always in little
endian byte order, so that a byte-wise output yields to the wanted
ASCII representation of the message digest. */
extern void* sha1_finish_ctx(struct sha1_ctx* ctx, void* resbuf);
/* Put result from CTX in first 20 bytes following RESBUF. The result is
always in little endian byte order, so that a byte-wise output yields
to the wanted ASCII representation of the message digest. */
extern void* sha1_read_ctx(const struct sha1_ctx* ctx, void* resbuf);
/* Compute SHA1 message digest for bytes read from STREAM. The
resulting message digest number will be written into the 20 bytes
beginning at RESBLOCK. */
extern int sha1_stream(FILE* stream, void* resblock);
/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
digest. */
extern void* sha1_buffer(const char* buffer, size_t len, void* resblock);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SHA256_H
#define SHA256_H 1
#include <stdio.h>
#include <stdint.h>
#ifdef __cplusplus
namespace rocketmqSignature {
#endif
/* Structure to save state of computation between the single steps. */
struct sha256_ctx {
uint32_t state[8];
uint32_t total[2];
size_t buflen;
uint32_t buffer[32];
};
enum { SHA224_DIGEST_SIZE = 28 };
enum { SHA256_DIGEST_SIZE = 32 };
/* Initialize structure containing state of computation. */
extern void sha256_init_ctx(struct sha256_ctx* ctx);
extern void sha224_init_ctx(struct sha256_ctx* ctx);
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is necessary that LEN is a multiple of 64!!! */
extern void sha256_process_block(const void* buffer, size_t len, struct sha256_ctx* ctx);
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is NOT required that LEN is a multiple of 64. */
extern void sha256_process_bytes(const void* buffer, size_t len, struct sha256_ctx* ctx);
/* Process the remaining bytes in the buffer and put result from CTX
in first 32 (28) bytes following RESBUF. The result is always in little
endian byte order, so that a byte-wise output yields to the wanted
ASCII representation of the message digest. */
extern void* sha256_finish_ctx(struct sha256_ctx* ctx, void* resbuf);
extern void* sha224_finish_ctx(struct sha256_ctx* ctx, void* resbuf);
/* Put result from CTX in first 32 (28) bytes following RESBUF. The result is
always in little endian byte order, so that a byte-wise output yields
to the wanted ASCII representation of the message digest. */
extern void* sha256_read_ctx(const struct sha256_ctx* ctx, void* resbuf);
extern void* sha224_read_ctx(const struct sha256_ctx* ctx, void* resbuf);
/* Compute SHA256 (SHA224) message digest for bytes read from STREAM. The
resulting message digest number will be written into the 32 (28) bytes
beginning at RESBLOCK. */
extern int sha256_stream(FILE* stream, void* resblock);
extern int sha224_stream(FILE* stream, void* resblock);
/* Compute SHA256 (SHA224) message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
digest. */
extern void* sha256_buffer(const char* buffer, size_t len, void* resblock);
extern void* sha224_buffer(const char* buffer, size_t len, void* resblock);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,90 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SHA512_H
#define SHA512_H 1
#include <stdio.h>
#include "u64.h"
#ifdef __cplusplus
namespace rocketmqSignature {
#endif
/* Structure to save state of computation between the single steps. */
struct sha512_ctx {
u64 state[8];
u64 total[2];
size_t buflen;
u64 buffer[32];
};
enum { SHA384_DIGEST_SIZE = 48 };
enum { SHA512_DIGEST_SIZE = 64 };
/* Initialize structure containing state of computation. */
extern void sha512_init_ctx(struct sha512_ctx* ctx);
extern void sha384_init_ctx(struct sha512_ctx* ctx);
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is necessary that LEN is a multiple of 128!!! */
extern void sha512_process_block(const void* buffer, size_t len, struct sha512_ctx* ctx);
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is NOT required that LEN is a multiple of 128. */
extern void sha512_process_bytes(const void* buffer, size_t len, struct sha512_ctx* ctx);
/* Process the remaining bytes in the buffer and put result from CTX
in first 64 (48) bytes following RESBUF. The result is always in little
endian byte order, so that a byte-wise output yields to the wanted
ASCII representation of the message digest. */
extern void* sha512_finish_ctx(struct sha512_ctx* ctx, void* resbuf);
extern void* sha384_finish_ctx(struct sha512_ctx* ctx, void* resbuf);
/* Put result from CTX in first 64 (48) bytes following RESBUF. The result is
always in little endian byte order, so that a byte-wise output yields
to the wanted ASCII representation of the message digest.
IMPORTANT: On some systems it is required that RESBUF is correctly
aligned for a 32 bits value. */
extern void* sha512_read_ctx(const struct sha512_ctx* ctx, void* resbuf);
extern void* sha384_read_ctx(const struct sha512_ctx* ctx, void* resbuf);
/* Compute SHA512 (SHA384) message digest for bytes read from STREAM. The
resulting message digest number will be written into the 64 (48) bytes
beginning at RESBLOCK. */
extern int sha512_stream(FILE* stream, void* resblock);
extern int sha384_stream(FILE* stream, void* resblock);
/* Compute SHA512 (SHA384) message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
digest. */
extern void* sha512_buffer(const char* buffer, size_t len, void* resblock);
extern void* sha384_buffer(const char* buffer, size_t len, void* resblock);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,103 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SPAS_CLIENT_H
#define SPAS_CLIENT_H
#include "param_list.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
namespace rocketmqSignature {
#endif
#define SPAS_MAX_KEY_LEN 128 /* max access_key/secret_key length */
#define SPAS_MAX_PATH 256 /* max credential file path length */
#define SPAS_ACCESS_KEY_TAG \
"accessKey" /* access_key tag in credential file \
*/
#define SPAS_SECRET_KEY_TAG \
"secretKey" /* secret_key tag in credential file \
*/
#define SPAS_CREDENTIAL_ENV "SPAS_CREDENTIAL" /* credential file environment variable */
typedef enum {
SIGN_HMACSHA1 = 0, /* HmacSHA1 */
SIGN_HMACSHA256 = 1, /* HmacSHA256 */
} SPAS_SIGN_ALGORITHM;
typedef enum {
NO_UPDATE = 0, /* do not update credential */
UPDATE_BY_ALARM = 1, /* update credential by SIGALRM */
#ifdef SPAS_MT
UPDATE_BY_THREAD = 2, /* update credential by standalone thread */
#endif
} CREDENTIAL_UPDATE_MODE;
typedef enum {
SPAS_NO_ERROR = 0, /* success */
ERROR_INVALID_PARAM = -1, /* invalid parameter */
ERROR_NO_CREDENTIAL = -2, /* credential file not specified */
ERROR_FILE_OPEN = -3, /* file open failed */
ERROR_MEM_ALLOC = -4, /* memory allocation failed */
ERROR_MISSING_KEY = -5, /* missing access_key/secret_key */
ERROR_KEY_LENGTH = -6, /* key length exceed limit */
ERROR_UPDATE_CREDENTIAL = -7 /* update credential file failed */
} SPAS_ERROR_CODE;
typedef struct _spas_credential {
char access_key[SPAS_MAX_KEY_LEN];
char secret_key[SPAS_MAX_KEY_LEN];
} SPAS_CREDENTIAL;
extern int spas_load_credential(char* path, CREDENTIAL_UPDATE_MODE mode);
extern int spas_set_access_key(char* key);
extern int spas_set_secret_key(char* key);
extern char* spas_get_access_key(void);
extern char* spas_get_secret_key(void);
extern SPAS_CREDENTIAL* spas_get_credential(void);
#ifdef SPAS_MT
extern int spas_load_thread_credential(char* path);
extern int spas_set_thread_access_key(char* key);
extern int spas_set_thread_secret_key(char* key);
extern char* spas_get_thread_access_key(void);
extern char* spas_get_thread_secret_key(void);
#endif
extern char* spas_get_signature(const SPAS_PARAM_LIST* list, const char* key);
extern char* spas_get_signature2(const SPAS_PARAM_LIST* list, const char* key, SPAS_SIGN_ALGORITHM algorithm);
extern char* spas_sign(const char* data, size_t size, const char* key);
extern char* spas_sign2(const char* data, size_t size, const char* key, SPAS_SIGN_ALGORITHM algorithm);
extern void spas_mem_free(char* pSignature);
extern char* spas_get_version(void);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,135 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stddef.h>
#include <stdint.h>
/* Return X rotated left by N bits, where 0 < N < 64. */
#define u64rol(x, n) u64or(u64shl(x, n), u64shr(x, 64 - n))
#ifdef UINT64_MAX
/* Native implementations are trivial. See below for comments on what
these operations do. */
typedef uint64_t u64;
#define u64hilo(hi, lo) ((u64)(((u64)(hi) << 32) + (lo)))
#define u64init(hi, lo) u64hilo(hi, lo)
#define u64lo(x) ((u64)(x))
#define u64lt(x, y) ((x) < (y))
#define u64and(x, y) ((x) & (y))
#define u64or(x, y) ((x) | (y))
#define u64xor(x, y) ((x) ^ (y))
#define u64plus(x, y) ((x) + (y))
#define u64shl(x, n) ((x) << (n))
#define u64shr(x, n) ((x) >> (n))
#else
/* u64 is a 64-bit unsigned integer value.
u64init (HI, LO), is like u64hilo (HI, LO), but for use in
initializer contexts. */
#ifdef WORDS_BIGENDIAN
typedef struct { uint32_t hi, lo; } u64;
#define u64init(hi, lo) \
{ hi, lo }
#else
typedef struct { uint32_t lo, hi; } u64;
#define u64init(hi, lo) \
{ lo, hi }
#endif
/* Given the high and low-order 32-bit quantities HI and LO, return a u64
value representing (HI << 32) + LO. */
static inline u64 u64hilo(uint32_t hi, uint32_t lo) {
u64 r;
r.hi = hi;
r.lo = lo;
return r;
}
/* Return a u64 value representing LO. */
static inline u64 u64lo(uint32_t lo) {
u64 r;
r.hi = 0;
r.lo = lo;
return r;
}
/* Return X < Y. */
static inline int u64lt(u64 x, u64 y) {
return x.hi < y.hi || (x.hi == y.hi && x.lo < y.lo);
}
/* Return X & Y. */
static inline u64 u64and(u64 x, u64 y) {
u64 r;
r.hi = x.hi & y.hi;
r.lo = x.lo & y.lo;
return r;
}
/* Return X | Y. */
static inline u64 u64or(u64 x, u64 y) {
u64 r;
r.hi = x.hi | y.hi;
r.lo = x.lo | y.lo;
return r;
}
/* Return X ^ Y. */
static inline u64 u64xor(u64 x, u64 y) {
u64 r;
r.hi = x.hi ^ y.hi;
r.lo = x.lo ^ y.lo;
return r;
}
/* Return X + Y. */
static inline u64 u64plus(u64 x, u64 y) {
u64 r;
r.lo = x.lo + y.lo;
r.hi = x.hi + y.hi + (r.lo < x.lo);
return r;
}
/* Return X << N. */
static inline u64 u64shl(u64 x, int n) {
u64 r;
if (n < 32) {
r.hi = (x.hi << n) | (x.lo >> (32 - n));
r.lo = x.lo << n;
} else {
r.hi = x.lo << (n - 32);
r.lo = 0;
}
return r;
}
/* Return X >> N. */
static inline u64 u64shr(u64 x, int n) {
u64 r;
if (n < 32) {
r.hi = x.hi >> n;
r.lo = (x.hi << (32 - n)) | (x.lo >> n);
} else {
r.hi = 0;
r.lo = x.hi >> (n - 32);
}
return r;
}
#endif

View File

@@ -0,0 +1,409 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Get prototype. */
#include "base64.h"
/* Get malloc. */
#include <stdlib.h>
/* Get UCHAR_MAX. */
#include <limits.h>
#ifdef __cplusplus
namespace rocketmqSignature{
#endif
/* C89 compliant way to cast 'char' to 'unsigned char'. */
#ifdef WIN32
static _inline unsigned char
#else
static inline unsigned char
#endif
to_uchar (char ch)
{
return ch;
}
/* Base64 encode IN array of size INLEN into OUT array of size OUTLEN.
If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as
possible. If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero
terminate the output buffer. */
void
base64_encode (const char *in, size_t inlen,
char *out, size_t outlen)
{
static const char b64str[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
while (inlen && outlen)
{
*out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f];
if (!--outlen)
break;
*out++ = b64str[((to_uchar (in[0]) << 4)
+ (--inlen ? to_uchar (in[1]) >> 4 : 0))
& 0x3f];
if (!--outlen)
break;
*out++ =
(inlen
? b64str[((to_uchar (in[1]) << 2)
+ (--inlen ? to_uchar (in[2]) >> 6 : 0))
& 0x3f]
: '=');
if (!--outlen)
break;
*out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '=';
if (!--outlen)
break;
if (inlen)
inlen--;
if (inlen)
in += 3;
}
if (outlen)
*out = '\0';
}
/* Allocate a buffer and store zero terminated base64 encoded data
from array IN of size INLEN, returning BASE64_LENGTH(INLEN), i.e.,
the length of the encoded data, excluding the terminating zero. On
return, the OUT variable will hold a pointer to newly allocated
memory that must be deallocated by the caller. If output string
length would overflow, 0 is returned and OUT is set to NULL. If
memory allocation failed, OUT is set to NULL, and the return value
indicates length of the requested memory block, i.e.,
BASE64_LENGTH(inlen) + 1. */
size_t
base64_encode_alloc (const char *in, size_t inlen, char **out)
{
size_t outlen = 1 + BASE64_LENGTH (inlen);
/* Check for overflow in outlen computation.
*
* If there is no overflow, outlen >= inlen.
*
* If the operation (inlen + 2) overflows then it yields at most +1, so
* outlen is 0.
*
* If the multiplication overflows, we lose at least half of the
* correct value, so the result is < ((inlen + 2) / 3) * 2, which is
* less than (inlen + 2) * 0.66667, which is less than inlen as soon as
* (inlen > 4).
*/
if (inlen > outlen)
{
*out = NULL;
return 0;
}
*out = (char *)malloc (outlen);
if (!*out)
return outlen;
base64_encode (in, inlen, *out, outlen);
return outlen - 1;
}
/* With this approach this file works independent of the charset used
(think EBCDIC). However, it does assume that the characters in the
Base64 alphabet (A-Za-z0-9+/) are encoded in 0..255. POSIX
1003.1-2001 require that char and unsigned char are 8-bit
quantities, though, taking care of that problem. But this may be a
potential problem on non-POSIX C99 platforms.
IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_"
as the formal parameter rather than "x". */
#define B64(_) \
((_) == 'A' ? 0 \
: (_) == 'B' ? 1 \
: (_) == 'C' ? 2 \
: (_) == 'D' ? 3 \
: (_) == 'E' ? 4 \
: (_) == 'F' ? 5 \
: (_) == 'G' ? 6 \
: (_) == 'H' ? 7 \
: (_) == 'I' ? 8 \
: (_) == 'J' ? 9 \
: (_) == 'K' ? 10 \
: (_) == 'L' ? 11 \
: (_) == 'M' ? 12 \
: (_) == 'N' ? 13 \
: (_) == 'O' ? 14 \
: (_) == 'P' ? 15 \
: (_) == 'Q' ? 16 \
: (_) == 'R' ? 17 \
: (_) == 'S' ? 18 \
: (_) == 'T' ? 19 \
: (_) == 'U' ? 20 \
: (_) == 'V' ? 21 \
: (_) == 'W' ? 22 \
: (_) == 'X' ? 23 \
: (_) == 'Y' ? 24 \
: (_) == 'Z' ? 25 \
: (_) == 'a' ? 26 \
: (_) == 'b' ? 27 \
: (_) == 'c' ? 28 \
: (_) == 'd' ? 29 \
: (_) == 'e' ? 30 \
: (_) == 'f' ? 31 \
: (_) == 'g' ? 32 \
: (_) == 'h' ? 33 \
: (_) == 'i' ? 34 \
: (_) == 'j' ? 35 \
: (_) == 'k' ? 36 \
: (_) == 'l' ? 37 \
: (_) == 'm' ? 38 \
: (_) == 'n' ? 39 \
: (_) == 'o' ? 40 \
: (_) == 'p' ? 41 \
: (_) == 'q' ? 42 \
: (_) == 'r' ? 43 \
: (_) == 's' ? 44 \
: (_) == 't' ? 45 \
: (_) == 'u' ? 46 \
: (_) == 'v' ? 47 \
: (_) == 'w' ? 48 \
: (_) == 'x' ? 49 \
: (_) == 'y' ? 50 \
: (_) == 'z' ? 51 \
: (_) == '0' ? 52 \
: (_) == '1' ? 53 \
: (_) == '2' ? 54 \
: (_) == '3' ? 55 \
: (_) == '4' ? 56 \
: (_) == '5' ? 57 \
: (_) == '6' ? 58 \
: (_) == '7' ? 59 \
: (_) == '8' ? 60 \
: (_) == '9' ? 61 \
: (_) == '+' ? 62 \
: (_) == '/' ? 63 \
: -1)
static const signed char b64[0x100] = {
B64 (0), B64 (1), B64 (2), B64 (3),
B64 (4), B64 (5), B64 (6), B64 (7),
B64 (8), B64 (9), B64 (10), B64 (11),
B64 (12), B64 (13), B64 (14), B64 (15),
B64 (16), B64 (17), B64 (18), B64 (19),
B64 (20), B64 (21), B64 (22), B64 (23),
B64 (24), B64 (25), B64 (26), B64 (27),
B64 (28), B64 (29), B64 (30), B64 (31),
B64 (32), B64 (33), B64 (34), B64 (35),
B64 (36), B64 (37), B64 (38), B64 (39),
B64 (40), B64 (41), B64 (42), B64 (43),
B64 (44), B64 (45), B64 (46), B64 (47),
B64 (48), B64 (49), B64 (50), B64 (51),
B64 (52), B64 (53), B64 (54), B64 (55),
B64 (56), B64 (57), B64 (58), B64 (59),
B64 (60), B64 (61), B64 (62), B64 (63),
B64 (64), B64 (65), B64 (66), B64 (67),
B64 (68), B64 (69), B64 (70), B64 (71),
B64 (72), B64 (73), B64 (74), B64 (75),
B64 (76), B64 (77), B64 (78), B64 (79),
B64 (80), B64 (81), B64 (82), B64 (83),
B64 (84), B64 (85), B64 (86), B64 (87),
B64 (88), B64 (89), B64 (90), B64 (91),
B64 (92), B64 (93), B64 (94), B64 (95),
B64 (96), B64 (97), B64 (98), B64 (99),
B64 (100), B64 (101), B64 (102), B64 (103),
B64 (104), B64 (105), B64 (106), B64 (107),
B64 (108), B64 (109), B64 (110), B64 (111),
B64 (112), B64 (113), B64 (114), B64 (115),
B64 (116), B64 (117), B64 (118), B64 (119),
B64 (120), B64 (121), B64 (122), B64 (123),
B64 (124), B64 (125), B64 (126), B64 (127),
B64 (128), B64 (129), B64 (130), B64 (131),
B64 (132), B64 (133), B64 (134), B64 (135),
B64 (136), B64 (137), B64 (138), B64 (139),
B64 (140), B64 (141), B64 (142), B64 (143),
B64 (144), B64 (145), B64 (146), B64 (147),
B64 (148), B64 (149), B64 (150), B64 (151),
B64 (152), B64 (153), B64 (154), B64 (155),
B64 (156), B64 (157), B64 (158), B64 (159),
B64 (160), B64 (161), B64 (162), B64 (163),
B64 (164), B64 (165), B64 (166), B64 (167),
B64 (168), B64 (169), B64 (170), B64 (171),
B64 (172), B64 (173), B64 (174), B64 (175),
B64 (176), B64 (177), B64 (178), B64 (179),
B64 (180), B64 (181), B64 (182), B64 (183),
B64 (184), B64 (185), B64 (186), B64 (187),
B64 (188), B64 (189), B64 (190), B64 (191),
B64 (192), B64 (193), B64 (194), B64 (195),
B64 (196), B64 (197), B64 (198), B64 (199),
B64 (200), B64 (201), B64 (202), B64 (203),
B64 (204), B64 (205), B64 (206), B64 (207),
B64 (208), B64 (209), B64 (210), B64 (211),
B64 (212), B64 (213), B64 (214), B64 (215),
B64 (216), B64 (217), B64 (218), B64 (219),
B64 (220), B64 (221), B64 (222), B64 (223),
B64 (224), B64 (225), B64 (226), B64 (227),
B64 (228), B64 (229), B64 (230), B64 (231),
B64 (232), B64 (233), B64 (234), B64 (235),
B64 (236), B64 (237), B64 (238), B64 (239),
B64 (240), B64 (241), B64 (242), B64 (243),
B64 (244), B64 (245), B64 (246), B64 (247),
B64 (248), B64 (249), B64 (250), B64 (251),
B64 (252), B64 (253), B64 (254), B64 (255)
};
#if UCHAR_MAX == 255
# define uchar_in_range(c) true
#else
# define uchar_in_range(c) ((c) <= 255)
#endif
/* Return true if CH is a character from the Base64 alphabet, and
false otherwise. Note that '=' is padding and not considered to be
part of the alphabet. */
bool
isbase64 (char ch)
{
return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
}
/* Decode base64 encoded input array IN of length INLEN to output
array OUT that can hold *OUTLEN bytes. Return true if decoding was
successful, i.e. if the input was valid base64 data, false
otherwise. If *OUTLEN is too small, as many bytes as possible will
be written to OUT. On return, *OUTLEN holds the length of decoded
bytes in OUT. Note that as soon as any non-alphabet characters are
encountered, decoding is stopped and false is returned. This means
that, when applicable, you must remove any line terminators that is
part of the data stream before calling this function. */
bool
base64_decode (const char *in, size_t inlen,
char *out, size_t *outlen)
{
size_t outleft = *outlen;
while (inlen >= 2)
{
if (!isbase64 (in[0]) || !isbase64 (in[1]))
break;
if (outleft)
{
*out++ = ((b64[to_uchar (in[0])] << 2)
| (b64[to_uchar (in[1])] >> 4));
outleft--;
}
if (inlen == 2)
break;
if (in[2] == '=')
{
if (inlen != 4)
break;
if (in[3] != '=')
break;
}
else
{
if (!isbase64 (in[2]))
break;
if (outleft)
{
*out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0)
| (b64[to_uchar (in[2])] >> 2));
outleft--;
}
if (inlen == 3)
break;
if (in[3] == '=')
{
if (inlen != 4)
break;
}
else
{
if (!isbase64 (in[3]))
break;
if (outleft)
{
*out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0)
| b64[to_uchar (in[3])]);
outleft--;
}
}
}
in += 4;
inlen -= 4;
}
*outlen -= outleft;
if (inlen != 0)
return false;
return true;
}
/* Allocate an output buffer in *OUT, and decode the base64 encoded
data stored in IN of size INLEN to the *OUT buffer. On return, the
size of the decoded data is stored in *OUTLEN. OUTLEN may be NULL,
if the caller is not interested in the decoded length. *OUT may be
NULL to indicate an out of memory error, in which case *OUTLEN
contains the size of the memory block needed. The function returns
true on successful decoding and memory allocation errors. (Use the
*OUT and *OUTLEN parameters to differentiate between successful
decoding and memory error.) The function returns false if the
input was invalid, in which case *OUT is NULL and *OUTLEN is
undefined. */
bool
base64_decode_alloc (const char *in, size_t inlen, char **out,
size_t *outlen)
{
/* This may allocate a few bytes too much, depending on input,
but it's not worth the extra CPU time to compute the exact amount.
The exact amount is 3 * inlen / 4, minus 1 if the input ends
with "=" and minus another 1 if the input ends with "==".
Dividing before multiplying avoids the possibility of overflow. */
size_t needlen = 3 * (inlen / 4) + 2;
*out = (char *)malloc (needlen);
if (!*out)
return true;
if (!base64_decode (in, inlen, *out, &needlen))
{
free (*out);
*out = NULL;
return false;
}
if (outlen)
*outlen = needlen;
return true;
#ifdef __cplusplus
}
#endif
}

View File

@@ -0,0 +1,181 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include <stdint.h>
#include "hmac.h"
#include "sha1.h"
#include "sha256.h"
#include "sha512.h"
#ifdef __cplusplus
namespace rocketmqSignature{
#endif
#define IPAD 0x36
#define OPAD 0x5c
int hmac_sha1(const void *key, size_t key_len, const void *data, size_t data_len, void *ret_buf)
{
uint32_t i;
struct sha1_ctx inner;
struct sha1_ctx outer;
struct sha1_ctx key_hash;
char ipad[64] = {0};
char opad[64] = {0};
char key_buf[SHA1_DIGEST_SIZE] = {0};
char inner_buf[SHA1_DIGEST_SIZE] = {0};
if (key == NULL || data == NULL || ret_buf == NULL) return -1;
if (key_len > 64) {
sha1_init_ctx(&key_hash);
sha1_process_bytes(key, key_len, &key_hash);
sha1_finish_ctx(&key_hash, key_buf);
key = key_buf;
key_len = SHA1_DIGEST_SIZE;
}
sha1_init_ctx (&inner);
for (i = 0; i < 64; i++) {
if (i < key_len) {
ipad[i] = ((const char *)key)[i] ^ IPAD;
opad[i] = ((const char *)key)[i] ^ OPAD;
} else {
ipad[i] = IPAD;
opad[i] = OPAD;
}
}
sha1_process_block (ipad, 64, &inner);
sha1_process_bytes (data, data_len, &inner);
sha1_finish_ctx (&inner, inner_buf);
sha1_init_ctx (&outer);
sha1_process_block (opad, 64, &outer);
sha1_process_bytes (inner_buf, SHA1_DIGEST_SIZE, &outer);
sha1_finish_ctx (&outer, ret_buf);
return 0;
}
int hmac_sha256(const void *key, size_t key_len, const void *data, size_t data_len, void *ret_buf)
{
uint32_t i;
struct sha256_ctx inner;
struct sha256_ctx outer;
struct sha256_ctx key_hash;
char ipad[64] = {0};
char opad[64] = {0};
char key_buf[SHA256_DIGEST_SIZE] = {0};
char inner_buf[SHA256_DIGEST_SIZE] = {0};
if (key == NULL || data == NULL || ret_buf == NULL) return -1;
if (key_len > 64) {
sha256_init_ctx(&key_hash);
sha256_process_bytes(key, key_len, &key_hash);
sha256_finish_ctx(&key_hash, key_buf);
key = key_buf;
key_len = SHA256_DIGEST_SIZE;
}
sha256_init_ctx (&inner);
for (i = 0; i < 64; i++) {
if (i < key_len) {
ipad[i] = ((const char *)key)[i] ^ IPAD;
opad[i] = ((const char *)key)[i] ^ OPAD;
} else {
ipad[i] = IPAD;
opad[i] = OPAD;
}
}
sha256_process_block (ipad, 64, &inner);
sha256_process_bytes (data, data_len, &inner);
sha256_finish_ctx (&inner, inner_buf);
sha256_init_ctx (&outer);
sha256_process_block (opad, 64, &outer);
sha256_process_bytes (inner_buf, SHA256_DIGEST_SIZE, &outer);
sha256_finish_ctx (&outer, ret_buf);
return 0;
}
int hmac_sha512(const void *key, size_t key_len, const void *data, size_t data_len, void *ret_buf)
{
uint32_t i;
struct sha512_ctx inner;
struct sha512_ctx outer;
struct sha512_ctx key_hash;
char ipad[128] = {0};
char opad[128] = {0};
char key_buf[SHA512_DIGEST_SIZE] = {0};
char inner_buf[SHA512_DIGEST_SIZE] = {0};
if (key == NULL || data == NULL || ret_buf == NULL) return -1;
if (key_len > 128) {
sha512_init_ctx(&key_hash);
sha512_process_bytes(key, key_len, &key_hash);
sha512_finish_ctx(&key_hash, key_buf);
key = key_buf;
key_len = SHA512_DIGEST_SIZE;
}
sha512_init_ctx (&inner);
for (i = 0; i < 128; i++) {
if (i < key_len) {
ipad[i] = ((const char *)key)[i] ^ IPAD;
opad[i] = ((const char *)key)[i] ^ OPAD;
} else {
ipad[i] = IPAD;
opad[i] = OPAD;
}
}
sha512_process_block (ipad, 128, &inner);
sha512_process_bytes (data, data_len, &inner);
sha512_finish_ctx (&inner, inner_buf);
sha512_init_ctx (&outer);
sha512_process_block (opad, 128, &outer);
sha512_process_bytes (inner_buf, SHA512_DIGEST_SIZE, &outer);
sha512_finish_ctx (&outer, ret_buf);
return 0;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,142 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include "spas_client.h"
#ifdef __cplusplus
namespace rocketmqSignature {
#endif
extern void *_mem_alloc(unsigned int size);
extern void _mem_free(void *ptr);
static int _nodecmp(SPAS_PARAM_NODE *n1, SPAS_PARAM_NODE *n2) {
int ret = strcmp(n1->name, n2->name);
if (ret == 0) {
ret = strcmp(n1->value, n2->value);
}
return ret;
}
SPAS_PARAM_LIST *create_param_list() {
return (SPAS_PARAM_LIST *)_mem_alloc(sizeof(SPAS_PARAM_LIST));
}
void free_param_list(SPAS_PARAM_LIST *list) {
SPAS_PARAM_NODE *pnode = NULL;
SPAS_PARAM_NODE *pnext = NULL;
if (list == NULL) {
return;
}
pnode = list->phead;
while (pnode != NULL) {
pnext = pnode->pnext;
_mem_free(pnode->name);
_mem_free(pnode->value);
_mem_free(pnode);
pnode = pnext;
}
_mem_free(list);
}
int add_param_to_list(SPAS_PARAM_LIST *list, const char *name,
const char *value) {
SPAS_PARAM_NODE *pnode = NULL;
SPAS_PARAM_NODE *plast = NULL;
int nlen = 0;
int vlen = 0;
if (list == NULL || name == NULL || value == NULL) {
return ERROR_INVALID_PARAM;
}
nlen = strlen(name);
vlen = strlen(value);
pnode = (SPAS_PARAM_NODE *)_mem_alloc(sizeof(SPAS_PARAM_NODE));
if (pnode == NULL) {
return ERROR_MEM_ALLOC;
}
pnode->name = (char *)_mem_alloc(nlen + 1);
if (pnode->name == NULL) {
_mem_free(pnode);
return ERROR_MEM_ALLOC;
}
pnode->value = (char *)_mem_alloc(vlen + 1);
if (pnode->value == NULL) {
_mem_free(pnode->name);
_mem_free(pnode);
return ERROR_MEM_ALLOC;
}
memcpy(pnode->name, name, nlen);
memcpy(pnode->value, value, vlen);
if (list->phead == NULL) {
list->phead = pnode;
} else if (_nodecmp(pnode, list->phead) <= 0) {
pnode->pnext = list->phead;
list->phead = pnode;
} else {
plast = list->phead;
while (plast->pnext != NULL) {
if (_nodecmp(pnode, plast->pnext) <= 0) {
pnode->pnext = plast->pnext;
plast->pnext = pnode;
break;
} else {
plast = plast->pnext;
}
}
if (plast->pnext == NULL) {
plast->pnext = pnode;
}
}
list->length++;
list->size += nlen + vlen + 1; /* 1 overhead for '=' */
return SPAS_NO_ERROR;
}
char *param_list_to_str(const SPAS_PARAM_LIST *list) {
int size = 0;
int pos = 0;
char *buf = NULL;
SPAS_PARAM_NODE *pnode = NULL;
if (list == NULL) {
return NULL;
}
if (list->length == 0) {
return (char *)_mem_alloc(1);
}
size = list->size + list->length - 1; /* overhead for '&' */
buf = (char *)_mem_alloc(size);
if (buf == NULL) {
return NULL;
}
pnode = list->phead;
if (pnode != NULL) {
sprintf(buf, "%s=%s", pnode->name, pnode->value);
pos += strlen(pnode->name) + strlen(pnode->value) + 1;
pnode = pnode->pnext;
}
while (pnode != NULL) {
sprintf(buf + pos, "&%s=%s", pnode->name, pnode->value);
pos += strlen(pnode->name) + strlen(pnode->value) + 2;
pnode = pnode->pnext;
}
return buf;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,507 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sha1.h"
#include <stddef.h>
#include <string.h>
#if USE_UNLOCKED_IO
# include "unlocked-io.h"
#endif
#ifdef __cplusplus
namespace rocketmqSignature {
#endif
#ifdef WORDS_BIGENDIAN
# define SWAP(n) (n)
#else
# define SWAP(n) \
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
#endif
#define BLOCKSIZE 4096
#if BLOCKSIZE % 64 != 0
# error "invalid BLOCKSIZE"
#endif
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (RFC 1321, 3.1: Step 1) */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
/*!
* @fn void sha1_init_ctx (struct sha1_ctx *ctx)
*
* @brief initialize a context with start constants
*
* @details Take a pointer to a 160 bit block of data (five 32 bit ints) and
* initialize it to the start constants of the SHA1 algorithm. This
* must be called before using hash in the call to sha1_hash.
*
* @param[out] ctx pointer to a context to be initialized
*/
void
sha1_init_ctx (struct sha1_ctx *ctx)
{
ctx->A = 0x67452301;
ctx->B = 0xefcdab89;
ctx->C = 0x98badcfe;
ctx->D = 0x10325476;
ctx->E = 0xc3d2e1f0;
ctx->total[0] = ctx->total[1] = 0;
ctx->buflen = 0;
}
/*!
* @fn static __inline__ void set_uint32 (char *cp, uint32_t v)
*
* @brief Copy the 4 byte value from v into the memory location pointed to
by *cp
*
* @details Copy the 4 byte value from v into the memory location pointed to by
* *cp, If your architecture allows unaligned access this is equivalent
* to * (uint32_t *) cp = v
*
* @param[out] cp memory location to copy v into
* @param[in] v 4 byte value to be copied
*/
#ifdef WIN32
static _inline void
#else
static __inline__ void
#endif
set_uint32 (char *cp, uint32_t v)
{
memcpy (cp, &v, sizeof v);
}
/*!
* @fn void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf)
*
* @brief Put result from CTX in first 20 bytes following RESBUF
*
* @details Put result from CTX in first 20 bytes following RESBUF. The result
* must be in little endian byte order.
*
* @param[in] ctx context whose results will be copied
* @param[out] resbuf result of copies saved in little endian byte order
* @return resbuf
*/
void *
sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf)
{
char *r = (char*)resbuf;
set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A));
set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B));
set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C));
set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D));
set_uint32 (r + 4 * sizeof ctx->E, SWAP (ctx->E));
return resbuf;
}
/*!
* @fn void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
*
* @brief Process the remaining bytes in the internal buffer and write
the result to RESBUF.
*
* @details Process the remaining bytes in the internal buffer and the usual
* prolog according to the standard and write the result to RESBUF.
*
* @param[in] ctx context to be used
* @param[out] resbuf resultant SHA1 hash
* @return resultant SHA1 hash
*/
void *
sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
{
/* Take yet unprocessed bytes into account. */
uint32_t bytes = ctx->buflen;
size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
/* Now count remaining bytes. */
ctx->total[0] += bytes;
if (ctx->total[0] < bytes)
++ctx->total[1];
/* Put the 64-bit file length in *bits* at the end of the buffer. */
ctx->buffer[size - 2] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
ctx->buffer[size - 1] = SWAP (ctx->total[0] << 3);
memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
/* Process last bytes. */
sha1_process_block (ctx->buffer, size * 4, ctx);
return sha1_read_ctx (ctx, resbuf);
}
/*
* @fn void *sha1_stream (FILE *stream, void *resblock)
*
* @brief Compute SHA1 message digest for A Stream.
*
* @details Compute SHA1 message digest for Stream. The
* result is always in little endian byte order, so that a byte-wise
* output yields to the wanted ASCII representation of the message
* digest.
*
* @param[in] stream message stream to be hashed
* @param[out] resblock resultant hash in little endian byte order
* @return resultant hash in little endian byte order
*/
int
sha1_stream (FILE *stream, void *resblock)
{
struct sha1_ctx ctx;
char buffer[BLOCKSIZE + 72];
size_t sum;
/* Initialize the computation context. */
sha1_init_ctx (&ctx);
/* Iterate over full file contents. */
while (1)
{
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
computation function processes the whole buffer so that with the
next round of the loop another block can be read. */
size_t n;
sum = 0;
/* Read block. Take care for partial reads. */
while (1)
{
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
sum += n;
if (sum == BLOCKSIZE)
break;
if (n == 0)
{
/* Check for the error flag IFF N == 0, so that we don't
exit the loop after a partial read due to e.g., EAGAIN
or EWOULDBLOCK. */
if (ferror (stream))
return 1;
goto process_partial_block;
}
/* We've read at least one byte, so ignore errors. But always
check for EOF, since feof may be true even though N > 0.
Otherwise, we could end up calling fread after EOF. */
if (feof (stream))
goto process_partial_block;
}
/* Process buffer with BLOCKSIZE bytes. Note that
BLOCKSIZE % 64 == 0
*/
sha1_process_block (buffer, BLOCKSIZE, &ctx);
}
process_partial_block:;
/* Process any remaining bytes. */
if (sum > 0)
sha1_process_bytes (buffer, sum, &ctx);
/* Construct result in desired memory. */
sha1_finish_ctx (&ctx, resblock);
return 0;
}
/*
* @fn void *sha1_buffer (const char *buffer, size_t len, void *resblock)
*
* @brief Compute SHA1 message digest for LEN bytes beginning at BUFFER.
*
* @details Compute SHA1 message digest for LEN bytes beginning at BUFFER. The
* result is always in little endian byte order, so that a byte-wise
* output yields to the wanted ASCII representation of the message
* digest.
*
* @param[in] buffer message to be hashed
* @param[in] len length of buffer
* @param[out] resblock resultant hash in little endian byte order
* @return resultant hash in little endian byte order
*/
void *
sha1_buffer (const char *buffer, size_t len, void *resblock)
{
struct sha1_ctx ctx;
/* Initialize the computation context. */
sha1_init_ctx (&ctx);
/* Process whole buffer but last len % 64 bytes. */
sha1_process_bytes (buffer, len, &ctx);
/* Put result in desired memory area. */
return sha1_finish_ctx (&ctx, resblock);
}
/*!
* @fn void sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
*
* @brief update the context for the next LEN bytes starting at BUFFER.
*
* @details Starting with the result of former calls of this function (or the
* initialization function) update the context for the next LEN bytes
* starting at BUFFER.
* It is NOT required that LEN is a multiple of 64.
*
* @param[in] buffer buffer used to update context values
* @param[in] len length of buffer
* @param[out] ctx context to be updated
*/
void
sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
{
/* When we already have some bits in our internal buffer concatenate
both inputs first. */
if (ctx->buflen != 0)
{
size_t left_over = ctx->buflen;
size_t add = 128 - left_over > len ? len : 128 - left_over;
memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
ctx->buflen += add;
if (ctx->buflen > 64)
{
sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
ctx->buflen &= 63;
/* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer,
&((char *) ctx->buffer)[(left_over + add) & ~63],
ctx->buflen);
}
buffer = (const char *) buffer + add;
len -= add;
}
/* Process available complete blocks. */
if (len >= 64)
{
#if !_STRING_ARCH_unaligned
# define alignof(type) offsetof (struct { char c; type x; }, x)
# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0)
if (UNALIGNED_P (buffer))
while (len > 64)
{
sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
buffer = (const char *) buffer + 64;
len -= 64;
}
else
#endif
{
sha1_process_block (buffer, len & ~63, ctx);
buffer = (const char *) buffer + (len & ~63);
len &= 63;
}
}
/* Move remaining bytes in internal buffer. */
if (len > 0)
{
size_t left_over = ctx->buflen;
memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
left_over += len;
if (left_over >= 64)
{
sha1_process_block (ctx->buffer, 64, ctx);
left_over -= 64;
memcpy (ctx->buffer, &ctx->buffer[16], left_over);
}
ctx->buflen = left_over;
}
}
/* --- Code below is the primary difference between md5.c and sha1.c --- */
/* SHA1 round constants */
#define K1 0x5a827999
#define K2 0x6ed9eba1
#define K3 0x8f1bbcdc
#define K4 0xca62c1d6
/* Round functions. Note that F2 is the same as F4. */
#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
#define F2(B,C,D) (B ^ C ^ D)
#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
#define F4(B,C,D) (B ^ C ^ D)
/*!
* @fn void sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
*
* @brief Process LEN bytes of BUFFER, accumulating context into CTX.
*
* @details Process LEN bytes of BUFFER, accumulating context into CTX.
* It is assumed that LEN % 64 == 0.
* Most of this code comes from GnuPG's cipher/sha1.c.
*
* @param[in] buffer buffer to be processed
* @param[in] len length of buffer
* @param[out] ctx context used to accumulate results
*/
void
sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
{
const uint32_t *words = (const uint32_t*)buffer;
size_t nwords = len / sizeof (uint32_t);
const uint32_t *endp = words + nwords;
uint32_t x[16];
uint32_t a = ctx->A;
uint32_t b = ctx->B;
uint32_t c = ctx->C;
uint32_t d = ctx->D;
uint32_t e = ctx->E;
/* First increment the byte count. RFC 1321 specifies the possible
length of the file up to 2^64 bits. Here we only compute the
number of bytes. Do a double word increment. */
ctx->total[0] += len;
if (ctx->total[0] < len)
++ctx->total[1];
#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n))))
#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \
^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \
, (x[I&0x0f] = rol(tm, 1)) )
#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \
+ F( B, C, D ) \
+ K \
+ M; \
B = rol( B, 30 ); \
} while(0)
while (words < endp)
{
uint32_t tm;
int t;
for (t = 0; t < 16; t++)
{
x[t] = SWAP (*words);
words++;
}
R( a, b, c, d, e, F1, K1, x[ 0] );
R( e, a, b, c, d, F1, K1, x[ 1] );
R( d, e, a, b, c, F1, K1, x[ 2] );
R( c, d, e, a, b, F1, K1, x[ 3] );
R( b, c, d, e, a, F1, K1, x[ 4] );
R( a, b, c, d, e, F1, K1, x[ 5] );
R( e, a, b, c, d, F1, K1, x[ 6] );
R( d, e, a, b, c, F1, K1, x[ 7] );
R( c, d, e, a, b, F1, K1, x[ 8] );
R( b, c, d, e, a, F1, K1, x[ 9] );
R( a, b, c, d, e, F1, K1, x[10] );
R( e, a, b, c, d, F1, K1, x[11] );
R( d, e, a, b, c, F1, K1, x[12] );
R( c, d, e, a, b, F1, K1, x[13] );
R( b, c, d, e, a, F1, K1, x[14] );
R( a, b, c, d, e, F1, K1, x[15] );
R( e, a, b, c, d, F1, K1, M(16) );
R( d, e, a, b, c, F1, K1, M(17) );
R( c, d, e, a, b, F1, K1, M(18) );
R( b, c, d, e, a, F1, K1, M(19) );
R( a, b, c, d, e, F2, K2, M(20) );
R( e, a, b, c, d, F2, K2, M(21) );
R( d, e, a, b, c, F2, K2, M(22) );
R( c, d, e, a, b, F2, K2, M(23) );
R( b, c, d, e, a, F2, K2, M(24) );
R( a, b, c, d, e, F2, K2, M(25) );
R( e, a, b, c, d, F2, K2, M(26) );
R( d, e, a, b, c, F2, K2, M(27) );
R( c, d, e, a, b, F2, K2, M(28) );
R( b, c, d, e, a, F2, K2, M(29) );
R( a, b, c, d, e, F2, K2, M(30) );
R( e, a, b, c, d, F2, K2, M(31) );
R( d, e, a, b, c, F2, K2, M(32) );
R( c, d, e, a, b, F2, K2, M(33) );
R( b, c, d, e, a, F2, K2, M(34) );
R( a, b, c, d, e, F2, K2, M(35) );
R( e, a, b, c, d, F2, K2, M(36) );
R( d, e, a, b, c, F2, K2, M(37) );
R( c, d, e, a, b, F2, K2, M(38) );
R( b, c, d, e, a, F2, K2, M(39) );
R( a, b, c, d, e, F3, K3, M(40) );
R( e, a, b, c, d, F3, K3, M(41) );
R( d, e, a, b, c, F3, K3, M(42) );
R( c, d, e, a, b, F3, K3, M(43) );
R( b, c, d, e, a, F3, K3, M(44) );
R( a, b, c, d, e, F3, K3, M(45) );
R( e, a, b, c, d, F3, K3, M(46) );
R( d, e, a, b, c, F3, K3, M(47) );
R( c, d, e, a, b, F3, K3, M(48) );
R( b, c, d, e, a, F3, K3, M(49) );
R( a, b, c, d, e, F3, K3, M(50) );
R( e, a, b, c, d, F3, K3, M(51) );
R( d, e, a, b, c, F3, K3, M(52) );
R( c, d, e, a, b, F3, K3, M(53) );
R( b, c, d, e, a, F3, K3, M(54) );
R( a, b, c, d, e, F3, K3, M(55) );
R( e, a, b, c, d, F3, K3, M(56) );
R( d, e, a, b, c, F3, K3, M(57) );
R( c, d, e, a, b, F3, K3, M(58) );
R( b, c, d, e, a, F3, K3, M(59) );
R( a, b, c, d, e, F4, K4, M(60) );
R( e, a, b, c, d, F4, K4, M(61) );
R( d, e, a, b, c, F4, K4, M(62) );
R( c, d, e, a, b, F4, K4, M(63) );
R( b, c, d, e, a, F4, K4, M(64) );
R( a, b, c, d, e, F4, K4, M(65) );
R( e, a, b, c, d, F4, K4, M(66) );
R( d, e, a, b, c, F4, K4, M(67) );
R( c, d, e, a, b, F4, K4, M(68) );
R( b, c, d, e, a, F4, K4, M(69) );
R( a, b, c, d, e, F4, K4, M(70) );
R( e, a, b, c, d, F4, K4, M(71) );
R( d, e, a, b, c, F4, K4, M(72) );
R( c, d, e, a, b, F4, K4, M(73) );
R( b, c, d, e, a, F4, K4, M(74) );
R( a, b, c, d, e, F4, K4, M(75) );
R( e, a, b, c, d, F4, K4, M(76) );
R( d, e, a, b, c, F4, K4, M(77) );
R( c, d, e, a, b, F4, K4, M(78) );
R( b, c, d, e, a, F4, K4, M(79) );
a = ctx->A += a;
b = ctx->B += b;
c = ctx->C += c;
d = ctx->D += d;
e = ctx->E += e;
}
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,559 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sha256.h"
#include <stddef.h>
#include <string.h>
#if USE_UNLOCKED_IO
# include "unlocked-io.h"
#endif
#ifdef __cplusplus
namespace rocketmqSignature {
#endif
#ifdef WORDS_BIGENDIAN
# define SWAP(n) (n)
#else
# define SWAP(n) \
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
#endif
#define BLOCKSIZE 4096
#if BLOCKSIZE % 64 != 0
# error "invalid BLOCKSIZE"
#endif
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
/*
Takes a pointer to a 256 bit block of data (eight 32 bit ints) and
intializes it to the start constants of the SHA256 algorithm. This
must be called before using hash in the call to sha256_hash
*/
void
sha256_init_ctx (struct sha256_ctx *ctx)
{
ctx->state[0] = 0x6a09e667UL;
ctx->state[1] = 0xbb67ae85UL;
ctx->state[2] = 0x3c6ef372UL;
ctx->state[3] = 0xa54ff53aUL;
ctx->state[4] = 0x510e527fUL;
ctx->state[5] = 0x9b05688cUL;
ctx->state[6] = 0x1f83d9abUL;
ctx->state[7] = 0x5be0cd19UL;
ctx->total[0] = ctx->total[1] = 0;
ctx->buflen = 0;
}
void
sha224_init_ctx (struct sha256_ctx *ctx)
{
ctx->state[0] = 0xc1059ed8UL;
ctx->state[1] = 0x367cd507UL;
ctx->state[2] = 0x3070dd17UL;
ctx->state[3] = 0xf70e5939UL;
ctx->state[4] = 0xffc00b31UL;
ctx->state[5] = 0x68581511UL;
ctx->state[6] = 0x64f98fa7UL;
ctx->state[7] = 0xbefa4fa4UL;
ctx->total[0] = ctx->total[1] = 0;
ctx->buflen = 0;
}
/* Copy the value from v into the memory location pointed to by *cp,
If your architecture allows unaligned access this is equivalent to
* (uint32_t *) cp = v */
#ifdef WIN32
static _inline void
#else
static __inline__ void
#endif
set_uint32 (char *cp, uint32_t v)
{
memcpy (cp, &v, sizeof v);
}
/* Put result from CTX in first 32 bytes following RESBUF. The result
must be in little endian byte order. */
void *
sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf)
{
int i;
char *r = (char*)resbuf;
for (i = 0; i < 8; i++)
set_uint32 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i]));
return resbuf;
}
void *
sha224_read_ctx (const struct sha256_ctx *ctx, void *resbuf)
{
int i;
char *r = (char*)resbuf;
for (i = 0; i < 7; i++)
set_uint32 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i]));
return resbuf;
}
/* Process the remaining bytes in the internal buffer and the usual
prolog according to the standard and write the result to RESBUF. */
static void
sha256_conclude_ctx (struct sha256_ctx *ctx)
{
/* Take yet unprocessed bytes into account. */
size_t bytes = ctx->buflen;
size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
/* Now count remaining bytes. */
ctx->total[0] += bytes;
if (ctx->total[0] < bytes)
++ctx->total[1];
/* Put the 64-bit file length in *bits* at the end of the buffer.
Use set_uint32 rather than a simple assignment, to avoid risk of
unaligned access. */
set_uint32 ((char *) &ctx->buffer[size - 2],
SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)));
set_uint32 ((char *) &ctx->buffer[size - 1],
SWAP (ctx->total[0] << 3));
memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
/* Process last bytes. */
sha256_process_block (ctx->buffer, size * 4, ctx);
}
void *
sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
{
sha256_conclude_ctx (ctx);
return sha256_read_ctx (ctx, resbuf);
}
void *
sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
{
sha256_conclude_ctx (ctx);
return sha224_read_ctx (ctx, resbuf);
}
/* Compute SHA256 message digest for bytes read from STREAM. The
resulting message digest number will be written into the 32 bytes
beginning at RESBLOCK. */
int
sha256_stream (FILE *stream, void *resblock)
{
struct sha256_ctx ctx;
char buffer[BLOCKSIZE + 72];
size_t sum;
/* Initialize the computation context. */
sha256_init_ctx (&ctx);
/* Iterate over full file contents. */
while (1)
{
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
computation function processes the whole buffer so that with the
next round of the loop another block can be read. */
size_t n;
sum = 0;
/* Read block. Take care for partial reads. */
while (1)
{
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
sum += n;
if (sum == BLOCKSIZE)
break;
if (n == 0)
{
/* Check for the error flag IFF N == 0, so that we don't
exit the loop after a partial read due to e.g., EAGAIN
or EWOULDBLOCK. */
if (ferror (stream))
return 1;
goto process_partial_block;
}
/* We've read at least one byte, so ignore errors. But always
check for EOF, since feof may be true even though N > 0.
Otherwise, we could end up calling fread after EOF. */
if (feof (stream))
goto process_partial_block;
}
/* Process buffer with BLOCKSIZE bytes. Note that
BLOCKSIZE % 64 == 0
*/
sha256_process_block (buffer, BLOCKSIZE, &ctx);
}
process_partial_block:;
/* Process any remaining bytes. */
if (sum > 0)
sha256_process_bytes (buffer, sum, &ctx);
/* Construct result in desired memory. */
sha256_finish_ctx (&ctx, resblock);
return 0;
}
/* FIXME: Avoid code duplication */
int
sha224_stream (FILE *stream, void *resblock)
{
struct sha256_ctx ctx;
char buffer[BLOCKSIZE + 72];
size_t sum;
/* Initialize the computation context. */
sha224_init_ctx (&ctx);
/* Iterate over full file contents. */
while (1)
{
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
computation function processes the whole buffer so that with the
next round of the loop another block can be read. */
size_t n;
sum = 0;
/* Read block. Take care for partial reads. */
while (1)
{
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
sum += n;
if (sum == BLOCKSIZE)
break;
if (n == 0)
{
/* Check for the error flag IFF N == 0, so that we don't
exit the loop after a partial read due to e.g., EAGAIN
or EWOULDBLOCK. */
if (ferror (stream))
return 1;
goto process_partial_block;
}
/* We've read at least one byte, so ignore errors. But always
check for EOF, since feof may be true even though N > 0.
Otherwise, we could end up calling fread after EOF. */
if (feof (stream))
goto process_partial_block;
}
/* Process buffer with BLOCKSIZE bytes. Note that
BLOCKSIZE % 64 == 0
*/
sha256_process_block (buffer, BLOCKSIZE, &ctx);
}
process_partial_block:;
/* Process any remaining bytes. */
if (sum > 0)
sha256_process_bytes (buffer, sum, &ctx);
/* Construct result in desired memory. */
sha224_finish_ctx (&ctx, resblock);
return 0;
}
/* Compute SHA512 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
digest. */
void *
sha256_buffer (const char *buffer, size_t len, void *resblock)
{
struct sha256_ctx ctx;
/* Initialize the computation context. */
sha256_init_ctx (&ctx);
/* Process whole buffer but last len % 64 bytes. */
sha256_process_bytes (buffer, len, &ctx);
/* Put result in desired memory area. */
return sha256_finish_ctx (&ctx, resblock);
}
void *
sha224_buffer (const char *buffer, size_t len, void *resblock)
{
struct sha256_ctx ctx;
/* Initialize the computation context. */
sha224_init_ctx (&ctx);
/* Process whole buffer but last len % 64 bytes. */
sha256_process_bytes (buffer, len, &ctx);
/* Put result in desired memory area. */
return sha224_finish_ctx (&ctx, resblock);
}
void
sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
{
/* When we already have some bits in our internal buffer concatenate
both inputs first. */
if (ctx->buflen != 0)
{
size_t left_over = ctx->buflen;
size_t add = 128 - left_over > len ? len : 128 - left_over;
memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
ctx->buflen += add;
if (ctx->buflen > 64)
{
sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
ctx->buflen &= 63;
/* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer,
&((char *) ctx->buffer)[(left_over + add) & ~63],
ctx->buflen);
}
buffer = (const char *) buffer + add;
len -= add;
}
/* Process available complete blocks. */
if (len >= 64)
{
#if !_STRING_ARCH_unaligned
# define alignof(type) offsetof (struct { char c; type x; }, x)
# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0)
if (UNALIGNED_P (buffer))
while (len > 64)
{
sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
buffer = (const char *) buffer + 64;
len -= 64;
}
else
#endif
{
sha256_process_block (buffer, len & ~63, ctx);
buffer = (const char *) buffer + (len & ~63);
len &= 63;
}
}
/* Move remaining bytes in internal buffer. */
if (len > 0)
{
size_t left_over = ctx->buflen;
memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
left_over += len;
if (left_over >= 64)
{
sha256_process_block (ctx->buffer, 64, ctx);
left_over -= 64;
memcpy (ctx->buffer, &ctx->buffer[16], left_over);
}
ctx->buflen = left_over;
}
}
/* --- Code below is the primary difference between sha1.c and sha256.c --- */
/* SHA256 round constants */
#define K(I) sha256_round_constants[I]
static const uint32_t sha256_round_constants[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL,
};
/* Round functions. */
#define F2(A,B,C) ( ( A & B ) | ( C & ( A | B ) ) )
#define F1(E,F,G) ( G ^ ( E & ( F ^ G ) ) )
/* Process LEN bytes of BUFFER, accumulating context into CTX.
It is assumed that LEN % 64 == 0.
Most of this code comes from GnuPG's cipher/sha1.c. */
void
sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx)
{
const uint32_t *words = (const uint32_t *)buffer;
size_t nwords = len / sizeof (uint32_t);
const uint32_t *endp = words + nwords;
uint32_t x[16];
uint32_t a = ctx->state[0];
uint32_t b = ctx->state[1];
uint32_t c = ctx->state[2];
uint32_t d = ctx->state[3];
uint32_t e = ctx->state[4];
uint32_t f = ctx->state[5];
uint32_t g = ctx->state[6];
uint32_t h = ctx->state[7];
/* First increment the byte count. FIPS PUB 180-2 specifies the possible
length of the file up to 2^64 bits. Here we only compute the
number of bytes. Do a double word increment. */
ctx->total[0] += len;
if (ctx->total[0] < len)
++ctx->total[1];
#define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
#define S0(x) (rol(x,25)^rol(x,14)^(x>>3))
#define S1(x) (rol(x,15)^rol(x,13)^(x>>10))
#define SS0(x) (rol(x,30)^rol(x,19)^rol(x,10))
#define SS1(x) (rol(x,26)^rol(x,21)^rol(x,7))
#define M(I) ( tm = S1(x[(I-2)&0x0f]) + x[(I-7)&0x0f] \
+ S0(x[(I-15)&0x0f]) + x[I&0x0f] \
, x[I&0x0f] = tm )
#define R(A,B,C,D,E,F,G,H,K,M) do { t0 = SS0(A) + F2(A,B,C); \
t1 = H + SS1(E) \
+ F1(E,F,G) \
+ K \
+ M; \
D += t1; H = t0 + t1; \
} while(0)
while (words < endp)
{
uint32_t tm;
uint32_t t0, t1;
int t;
/* FIXME: see sha1.c for a better implementation. */
for (t = 0; t < 16; t++)
{
x[t] = SWAP (*words);
words++;
}
R( a, b, c, d, e, f, g, h, K( 0), x[ 0] );
R( h, a, b, c, d, e, f, g, K( 1), x[ 1] );
R( g, h, a, b, c, d, e, f, K( 2), x[ 2] );
R( f, g, h, a, b, c, d, e, K( 3), x[ 3] );
R( e, f, g, h, a, b, c, d, K( 4), x[ 4] );
R( d, e, f, g, h, a, b, c, K( 5), x[ 5] );
R( c, d, e, f, g, h, a, b, K( 6), x[ 6] );
R( b, c, d, e, f, g, h, a, K( 7), x[ 7] );
R( a, b, c, d, e, f, g, h, K( 8), x[ 8] );
R( h, a, b, c, d, e, f, g, K( 9), x[ 9] );
R( g, h, a, b, c, d, e, f, K(10), x[10] );
R( f, g, h, a, b, c, d, e, K(11), x[11] );
R( e, f, g, h, a, b, c, d, K(12), x[12] );
R( d, e, f, g, h, a, b, c, K(13), x[13] );
R( c, d, e, f, g, h, a, b, K(14), x[14] );
R( b, c, d, e, f, g, h, a, K(15), x[15] );
R( a, b, c, d, e, f, g, h, K(16), M(16) );
R( h, a, b, c, d, e, f, g, K(17), M(17) );
R( g, h, a, b, c, d, e, f, K(18), M(18) );
R( f, g, h, a, b, c, d, e, K(19), M(19) );
R( e, f, g, h, a, b, c, d, K(20), M(20) );
R( d, e, f, g, h, a, b, c, K(21), M(21) );
R( c, d, e, f, g, h, a, b, K(22), M(22) );
R( b, c, d, e, f, g, h, a, K(23), M(23) );
R( a, b, c, d, e, f, g, h, K(24), M(24) );
R( h, a, b, c, d, e, f, g, K(25), M(25) );
R( g, h, a, b, c, d, e, f, K(26), M(26) );
R( f, g, h, a, b, c, d, e, K(27), M(27) );
R( e, f, g, h, a, b, c, d, K(28), M(28) );
R( d, e, f, g, h, a, b, c, K(29), M(29) );
R( c, d, e, f, g, h, a, b, K(30), M(30) );
R( b, c, d, e, f, g, h, a, K(31), M(31) );
R( a, b, c, d, e, f, g, h, K(32), M(32) );
R( h, a, b, c, d, e, f, g, K(33), M(33) );
R( g, h, a, b, c, d, e, f, K(34), M(34) );
R( f, g, h, a, b, c, d, e, K(35), M(35) );
R( e, f, g, h, a, b, c, d, K(36), M(36) );
R( d, e, f, g, h, a, b, c, K(37), M(37) );
R( c, d, e, f, g, h, a, b, K(38), M(38) );
R( b, c, d, e, f, g, h, a, K(39), M(39) );
R( a, b, c, d, e, f, g, h, K(40), M(40) );
R( h, a, b, c, d, e, f, g, K(41), M(41) );
R( g, h, a, b, c, d, e, f, K(42), M(42) );
R( f, g, h, a, b, c, d, e, K(43), M(43) );
R( e, f, g, h, a, b, c, d, K(44), M(44) );
R( d, e, f, g, h, a, b, c, K(45), M(45) );
R( c, d, e, f, g, h, a, b, K(46), M(46) );
R( b, c, d, e, f, g, h, a, K(47), M(47) );
R( a, b, c, d, e, f, g, h, K(48), M(48) );
R( h, a, b, c, d, e, f, g, K(49), M(49) );
R( g, h, a, b, c, d, e, f, K(50), M(50) );
R( f, g, h, a, b, c, d, e, K(51), M(51) );
R( e, f, g, h, a, b, c, d, K(52), M(52) );
R( d, e, f, g, h, a, b, c, K(53), M(53) );
R( c, d, e, f, g, h, a, b, K(54), M(54) );
R( b, c, d, e, f, g, h, a, K(55), M(55) );
R( a, b, c, d, e, f, g, h, K(56), M(56) );
R( h, a, b, c, d, e, f, g, K(57), M(57) );
R( g, h, a, b, c, d, e, f, K(58), M(58) );
R( f, g, h, a, b, c, d, e, K(59), M(59) );
R( e, f, g, h, a, b, c, d, K(60), M(60) );
R( d, e, f, g, h, a, b, c, K(61), M(61) );
R( c, d, e, f, g, h, a, b, K(62), M(62) );
R( b, c, d, e, f, g, h, a, K(63), M(63) );
a = ctx->state[0] += a;
b = ctx->state[1] += b;
c = ctx->state[2] += c;
d = ctx->state[3] += d;
e = ctx->state[4] += e;
f = ctx->state[5] += f;
g = ctx->state[6] += g;
h = ctx->state[7] += h;
}
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,609 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sha512.h"
#include <stddef.h>
#include <string.h>
#if USE_UNLOCKED_IO
# include "unlocked-io.h"
#endif
#ifdef __cplusplus
namespace rocketmqSignature{
#endif
#ifdef WORDS_BIGENDIAN
# define SWAP(n) (n)
#else
# define SWAP(n) \
u64or (u64or (u64or (u64shl (n, 56), \
u64shl (u64and (n, u64lo (0x0000ff00)), 40)), \
u64or (u64shl (u64and (n, u64lo (0x00ff0000)), 24), \
u64shl (u64and (n, u64lo (0xff000000)), 8))), \
u64or (u64or (u64and (u64shr (n, 8), u64lo (0xff000000)), \
u64and (u64shr (n, 24), u64lo (0x00ff0000))), \
u64or (u64and (u64shr (n, 40), u64lo (0x0000ff00)), \
u64shr (n, 56))))
#endif
#define BLOCKSIZE 4096
#if BLOCKSIZE % 128 != 0
# error "invalid BLOCKSIZE"
#endif
/* This array contains the bytes used to pad the buffer to the next
128-byte boundary. */
static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ };
/*
Takes a pointer to a 512 bit block of data (eight 64 bit ints) and
intializes it to the start constants of the SHA512 algorithm. This
must be called before using hash in the call to sha512_hash
*/
void
sha512_init_ctx (struct sha512_ctx *ctx)
{
ctx->state[0] = u64hilo (0x6a09e667, 0xf3bcc908);
ctx->state[1] = u64hilo (0xbb67ae85, 0x84caa73b);
ctx->state[2] = u64hilo (0x3c6ef372, 0xfe94f82b);
ctx->state[3] = u64hilo (0xa54ff53a, 0x5f1d36f1);
ctx->state[4] = u64hilo (0x510e527f, 0xade682d1);
ctx->state[5] = u64hilo (0x9b05688c, 0x2b3e6c1f);
ctx->state[6] = u64hilo (0x1f83d9ab, 0xfb41bd6b);
ctx->state[7] = u64hilo (0x5be0cd19, 0x137e2179);
ctx->total[0] = ctx->total[1] = u64lo (0);
ctx->buflen = 0;
}
void
sha384_init_ctx (struct sha512_ctx *ctx)
{
ctx->state[0] = u64hilo (0xcbbb9d5d, 0xc1059ed8);
ctx->state[1] = u64hilo (0x629a292a, 0x367cd507);
ctx->state[2] = u64hilo (0x9159015a, 0x3070dd17);
ctx->state[3] = u64hilo (0x152fecd8, 0xf70e5939);
ctx->state[4] = u64hilo (0x67332667, 0xffc00b31);
ctx->state[5] = u64hilo (0x8eb44a87, 0x68581511);
ctx->state[6] = u64hilo (0xdb0c2e0d, 0x64f98fa7);
ctx->state[7] = u64hilo (0x47b5481d, 0xbefa4fa4);
ctx->total[0] = ctx->total[1] = u64lo (0);
ctx->buflen = 0;
}
/* Copy the value from V into the memory location pointed to by *CP,
If your architecture allows unaligned access, this is equivalent to
* (__typeof__ (v) *) cp = v */
#ifdef WIN32
static _inline void
#else
static __inline__ void
#endif
set_uint64 (char *cp, u64 v)
{
memcpy (cp, &v, sizeof v);
}
/* Put result from CTX in first 64 bytes following RESBUF.
The result must be in little endian byte order. */
void *
sha512_read_ctx (const struct sha512_ctx *ctx, void *resbuf)
{
int i;
char *r = (char*)resbuf;
for (i = 0; i < 8; i++)
set_uint64 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i]));
return resbuf;
}
void *
sha384_read_ctx (const struct sha512_ctx *ctx, void *resbuf)
{
int i;
char *r = (char*)resbuf;
for (i = 0; i < 6; i++)
set_uint64 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i]));
return resbuf;
}
/* Process the remaining bytes in the internal buffer and the usual
prolog according to the standard and write the result to RESBUF. */
static void
sha512_conclude_ctx (struct sha512_ctx *ctx)
{
/* Take yet unprocessed bytes into account. */
size_t bytes = ctx->buflen;
size_t size = (bytes < 112) ? 128 / 8 : 128 * 2 / 8;
/* Now count remaining bytes. */
ctx->total[0] = u64plus (ctx->total[0], u64lo (bytes));
if (u64lt (ctx->total[0], u64lo (bytes)))
ctx->total[1] = u64plus (ctx->total[1], u64lo (1));
/* Put the 128-bit file length in *bits* at the end of the buffer.
Use set_uint64 rather than a simple assignment, to avoid risk of
unaligned access. */
set_uint64 ((char *) &ctx->buffer[size - 2],
SWAP (u64or (u64shl (ctx->total[1], 3),
u64shr (ctx->total[0], 61))));
set_uint64 ((char *) &ctx->buffer[size - 1],
SWAP (u64shl (ctx->total[0], 3)));
memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 8 - bytes);
/* Process last bytes. */
sha512_process_block (ctx->buffer, size * 8, ctx);
}
void *
sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
{
sha512_conclude_ctx (ctx);
return sha512_read_ctx (ctx, resbuf);
}
void *
sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
{
sha512_conclude_ctx (ctx);
return sha384_read_ctx (ctx, resbuf);
}
/* Compute SHA512 message digest for bytes read from STREAM. The
resulting message digest number will be written into the 64 bytes
beginning at RESBLOCK. */
int
sha512_stream (FILE *stream, void *resblock)
{
struct sha512_ctx ctx;
char buffer[BLOCKSIZE + 72];
size_t sum;
/* Initialize the computation context. */
sha512_init_ctx (&ctx);
/* Iterate over full file contents. */
while (1)
{
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
computation function processes the whole buffer so that with the
next round of the loop another block can be read. */
size_t n;
sum = 0;
/* Read block. Take care for partial reads. */
while (1)
{
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
sum += n;
if (sum == BLOCKSIZE)
break;
if (n == 0)
{
/* Check for the error flag IFF N == 0, so that we don't
exit the loop after a partial read due to e.g., EAGAIN
or EWOULDBLOCK. */
if (ferror (stream))
return 1;
goto process_partial_block;
}
/* We've read at least one byte, so ignore errors. But always
check for EOF, since feof may be true even though N > 0.
Otherwise, we could end up calling fread after EOF. */
if (feof (stream))
goto process_partial_block;
}
/* Process buffer with BLOCKSIZE bytes. Note that
BLOCKSIZE % 128 == 0
*/
sha512_process_block (buffer, BLOCKSIZE, &ctx);
}
process_partial_block:;
/* Process any remaining bytes. */
if (sum > 0)
sha512_process_bytes (buffer, sum, &ctx);
/* Construct result in desired memory. */
sha512_finish_ctx (&ctx, resblock);
return 0;
}
/* FIXME: Avoid code duplication */
int
sha384_stream (FILE *stream, void *resblock)
{
struct sha512_ctx ctx;
char buffer[BLOCKSIZE + 72];
size_t sum;
/* Initialize the computation context. */
sha384_init_ctx (&ctx);
/* Iterate over full file contents. */
while (1)
{
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
computation function processes the whole buffer so that with the
next round of the loop another block can be read. */
size_t n;
sum = 0;
/* Read block. Take care for partial reads. */
while (1)
{
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
sum += n;
if (sum == BLOCKSIZE)
break;
if (n == 0)
{
/* Check for the error flag IFF N == 0, so that we don't
exit the loop after a partial read due to e.g., EAGAIN
or EWOULDBLOCK. */
if (ferror (stream))
return 1;
goto process_partial_block;
}
/* We've read at least one byte, so ignore errors. But always
check for EOF, since feof may be true even though N > 0.
Otherwise, we could end up calling fread after EOF. */
if (feof (stream))
goto process_partial_block;
}
/* Process buffer with BLOCKSIZE bytes. Note that
BLOCKSIZE % 128 == 0
*/
sha512_process_block (buffer, BLOCKSIZE, &ctx);
}
process_partial_block:;
/* Process any remaining bytes. */
if (sum > 0)
sha512_process_bytes (buffer, sum, &ctx);
/* Construct result in desired memory. */
sha384_finish_ctx (&ctx, resblock);
return 0;
}
/* Compute SHA512 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
digest. */
void *
sha512_buffer (const char *buffer, size_t len, void *resblock)
{
struct sha512_ctx ctx;
/* Initialize the computation context. */
sha512_init_ctx (&ctx);
/* Process whole buffer but last len % 128 bytes. */
sha512_process_bytes (buffer, len, &ctx);
/* Put result in desired memory area. */
return sha512_finish_ctx (&ctx, resblock);
}
void *
sha384_buffer (const char *buffer, size_t len, void *resblock)
{
struct sha512_ctx ctx;
/* Initialize the computation context. */
sha384_init_ctx (&ctx);
/* Process whole buffer but last len % 128 bytes. */
sha512_process_bytes (buffer, len, &ctx);
/* Put result in desired memory area. */
return sha384_finish_ctx (&ctx, resblock);
}
void
sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
{
/* When we already have some bits in our internal buffer concatenate
both inputs first. */
if (ctx->buflen != 0)
{
size_t left_over = ctx->buflen;
size_t add = 256 - left_over > len ? len : 256 - left_over;
memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
ctx->buflen += add;
if (ctx->buflen > 128)
{
sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx);
ctx->buflen &= 127;
/* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer,
&((char *) ctx->buffer)[(left_over + add) & ~127],
ctx->buflen);
}
buffer = (const char *) buffer + add;
len -= add;
}
/* Process available complete blocks. */
if (len >= 128)
{
#if !_STRING_ARCH_unaligned
# define alignof(type) offsetof (struct { char c; type x; }, x)
# define UNALIGNED_P(p) (((size_t) p) % alignof (u64) != 0)
if (UNALIGNED_P (buffer))
while (len > 128)
{
sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128, ctx);
buffer = (const char *) buffer + 128;
len -= 128;
}
else
#endif
{
sha512_process_block (buffer, len & ~127, ctx);
buffer = (const char *) buffer + (len & ~127);
len &= 127;
}
}
/* Move remaining bytes in internal buffer. */
if (len > 0)
{
size_t left_over = ctx->buflen;
memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
left_over += len;
if (left_over >= 128)
{
sha512_process_block (ctx->buffer, 128, ctx);
left_over -= 128;
memcpy (ctx->buffer, &ctx->buffer[16], left_over);
}
ctx->buflen = left_over;
}
}
/* --- Code below is the primary difference between sha1.c and sha512.c --- */
/* SHA512 round constants */
#define K(I) sha512_round_constants[I]
static u64 const sha512_round_constants[80] = {
u64init (0x428a2f98, 0xd728ae22), u64init (0x71374491, 0x23ef65cd),
u64init (0xb5c0fbcf, 0xec4d3b2f), u64init (0xe9b5dba5, 0x8189dbbc),
u64init (0x3956c25b, 0xf348b538), u64init (0x59f111f1, 0xb605d019),
u64init (0x923f82a4, 0xaf194f9b), u64init (0xab1c5ed5, 0xda6d8118),
u64init (0xd807aa98, 0xa3030242), u64init (0x12835b01, 0x45706fbe),
u64init (0x243185be, 0x4ee4b28c), u64init (0x550c7dc3, 0xd5ffb4e2),
u64init (0x72be5d74, 0xf27b896f), u64init (0x80deb1fe, 0x3b1696b1),
u64init (0x9bdc06a7, 0x25c71235), u64init (0xc19bf174, 0xcf692694),
u64init (0xe49b69c1, 0x9ef14ad2), u64init (0xefbe4786, 0x384f25e3),
u64init (0x0fc19dc6, 0x8b8cd5b5), u64init (0x240ca1cc, 0x77ac9c65),
u64init (0x2de92c6f, 0x592b0275), u64init (0x4a7484aa, 0x6ea6e483),
u64init (0x5cb0a9dc, 0xbd41fbd4), u64init (0x76f988da, 0x831153b5),
u64init (0x983e5152, 0xee66dfab), u64init (0xa831c66d, 0x2db43210),
u64init (0xb00327c8, 0x98fb213f), u64init (0xbf597fc7, 0xbeef0ee4),
u64init (0xc6e00bf3, 0x3da88fc2), u64init (0xd5a79147, 0x930aa725),
u64init (0x06ca6351, 0xe003826f), u64init (0x14292967, 0x0a0e6e70),
u64init (0x27b70a85, 0x46d22ffc), u64init (0x2e1b2138, 0x5c26c926),
u64init (0x4d2c6dfc, 0x5ac42aed), u64init (0x53380d13, 0x9d95b3df),
u64init (0x650a7354, 0x8baf63de), u64init (0x766a0abb, 0x3c77b2a8),
u64init (0x81c2c92e, 0x47edaee6), u64init (0x92722c85, 0x1482353b),
u64init (0xa2bfe8a1, 0x4cf10364), u64init (0xa81a664b, 0xbc423001),
u64init (0xc24b8b70, 0xd0f89791), u64init (0xc76c51a3, 0x0654be30),
u64init (0xd192e819, 0xd6ef5218), u64init (0xd6990624, 0x5565a910),
u64init (0xf40e3585, 0x5771202a), u64init (0x106aa070, 0x32bbd1b8),
u64init (0x19a4c116, 0xb8d2d0c8), u64init (0x1e376c08, 0x5141ab53),
u64init (0x2748774c, 0xdf8eeb99), u64init (0x34b0bcb5, 0xe19b48a8),
u64init (0x391c0cb3, 0xc5c95a63), u64init (0x4ed8aa4a, 0xe3418acb),
u64init (0x5b9cca4f, 0x7763e373), u64init (0x682e6ff3, 0xd6b2b8a3),
u64init (0x748f82ee, 0x5defb2fc), u64init (0x78a5636f, 0x43172f60),
u64init (0x84c87814, 0xa1f0ab72), u64init (0x8cc70208, 0x1a6439ec),
u64init (0x90befffa, 0x23631e28), u64init (0xa4506ceb, 0xde82bde9),
u64init (0xbef9a3f7, 0xb2c67915), u64init (0xc67178f2, 0xe372532b),
u64init (0xca273ece, 0xea26619c), u64init (0xd186b8c7, 0x21c0c207),
u64init (0xeada7dd6, 0xcde0eb1e), u64init (0xf57d4f7f, 0xee6ed178),
u64init (0x06f067aa, 0x72176fba), u64init (0x0a637dc5, 0xa2c898a6),
u64init (0x113f9804, 0xbef90dae), u64init (0x1b710b35, 0x131c471b),
u64init (0x28db77f5, 0x23047d84), u64init (0x32caab7b, 0x40c72493),
u64init (0x3c9ebe0a, 0x15c9bebc), u64init (0x431d67c4, 0x9c100d4c),
u64init (0x4cc5d4be, 0xcb3e42b6), u64init (0x597f299c, 0xfc657e2a),
u64init (0x5fcb6fab, 0x3ad6faec), u64init (0x6c44198c, 0x4a475817),
};
/* Round functions. */
#define F2(A, B, C) u64or (u64and (A, B), u64and (C, u64or (A, B)))
#define F1(E, F, G) u64xor (G, u64and (E, u64xor (F, G)))
/* Process LEN bytes of BUFFER, accumulating context into CTX.
It is assumed that LEN % 128 == 0.
Most of this code comes from GnuPG's cipher/sha1.c. */
void
sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
{
u64 const *words = (u64 const *)buffer;
u64 const *endp = words + len / sizeof (u64);
u64 x[16];
u64 a = ctx->state[0];
u64 b = ctx->state[1];
u64 c = ctx->state[2];
u64 d = ctx->state[3];
u64 e = ctx->state[4];
u64 f = ctx->state[5];
u64 g = ctx->state[6];
u64 h = ctx->state[7];
/* First increment the byte count. FIPS PUB 180-2 specifies the possible
length of the file up to 2^128 bits. Here we only compute the
number of bytes. Do a double word increment. */
ctx->total[0] = u64plus (ctx->total[0], u64lo (len));
if (u64lt (ctx->total[0], u64lo (len)))
ctx->total[1] = u64plus (ctx->total[1], u64lo (1));
#define S0(x) u64xor (u64rol(x, 63), u64xor (u64rol (x, 56), u64shr (x, 7)))
#define S1(x) u64xor (u64rol (x, 45), u64xor (u64rol (x, 3), u64shr (x, 6)))
#define SS0(x) u64xor (u64rol (x, 36), u64xor (u64rol (x, 30), u64rol (x, 25)))
#define SS1(x) u64xor (u64rol(x, 50), u64xor (u64rol (x, 46), u64rol (x, 23)))
#define M(I) (x[(I) & 15] \
= u64plus (x[(I) & 15], \
u64plus (S1 (x[((I) - 2) & 15]), \
u64plus (x[((I) - 7) & 15], \
S0 (x[((I) - 15) & 15])))))
#define R(A, B, C, D, E, F, G, H, K, M) \
do \
{ \
u64 t0 = u64plus (SS0 (A), F2 (A, B, C)); \
u64 t1 = \
u64plus (H, u64plus (SS1 (E), \
u64plus (F1 (E, F, G), u64plus (K, M)))); \
D = u64plus (D, t1); \
H = u64plus (t0, t1); \
} \
while (0)
while (words < endp)
{
int t;
/* FIXME: see sha1.c for a better implementation. */
for (t = 0; t < 16; t++)
{
x[t] = SWAP (*words);
words++;
}
R( a, b, c, d, e, f, g, h, K( 0), x[ 0] );
R( h, a, b, c, d, e, f, g, K( 1), x[ 1] );
R( g, h, a, b, c, d, e, f, K( 2), x[ 2] );
R( f, g, h, a, b, c, d, e, K( 3), x[ 3] );
R( e, f, g, h, a, b, c, d, K( 4), x[ 4] );
R( d, e, f, g, h, a, b, c, K( 5), x[ 5] );
R( c, d, e, f, g, h, a, b, K( 6), x[ 6] );
R( b, c, d, e, f, g, h, a, K( 7), x[ 7] );
R( a, b, c, d, e, f, g, h, K( 8), x[ 8] );
R( h, a, b, c, d, e, f, g, K( 9), x[ 9] );
R( g, h, a, b, c, d, e, f, K(10), x[10] );
R( f, g, h, a, b, c, d, e, K(11), x[11] );
R( e, f, g, h, a, b, c, d, K(12), x[12] );
R( d, e, f, g, h, a, b, c, K(13), x[13] );
R( c, d, e, f, g, h, a, b, K(14), x[14] );
R( b, c, d, e, f, g, h, a, K(15), x[15] );
R( a, b, c, d, e, f, g, h, K(16), M(16) );
R( h, a, b, c, d, e, f, g, K(17), M(17) );
R( g, h, a, b, c, d, e, f, K(18), M(18) );
R( f, g, h, a, b, c, d, e, K(19), M(19) );
R( e, f, g, h, a, b, c, d, K(20), M(20) );
R( d, e, f, g, h, a, b, c, K(21), M(21) );
R( c, d, e, f, g, h, a, b, K(22), M(22) );
R( b, c, d, e, f, g, h, a, K(23), M(23) );
R( a, b, c, d, e, f, g, h, K(24), M(24) );
R( h, a, b, c, d, e, f, g, K(25), M(25) );
R( g, h, a, b, c, d, e, f, K(26), M(26) );
R( f, g, h, a, b, c, d, e, K(27), M(27) );
R( e, f, g, h, a, b, c, d, K(28), M(28) );
R( d, e, f, g, h, a, b, c, K(29), M(29) );
R( c, d, e, f, g, h, a, b, K(30), M(30) );
R( b, c, d, e, f, g, h, a, K(31), M(31) );
R( a, b, c, d, e, f, g, h, K(32), M(32) );
R( h, a, b, c, d, e, f, g, K(33), M(33) );
R( g, h, a, b, c, d, e, f, K(34), M(34) );
R( f, g, h, a, b, c, d, e, K(35), M(35) );
R( e, f, g, h, a, b, c, d, K(36), M(36) );
R( d, e, f, g, h, a, b, c, K(37), M(37) );
R( c, d, e, f, g, h, a, b, K(38), M(38) );
R( b, c, d, e, f, g, h, a, K(39), M(39) );
R( a, b, c, d, e, f, g, h, K(40), M(40) );
R( h, a, b, c, d, e, f, g, K(41), M(41) );
R( g, h, a, b, c, d, e, f, K(42), M(42) );
R( f, g, h, a, b, c, d, e, K(43), M(43) );
R( e, f, g, h, a, b, c, d, K(44), M(44) );
R( d, e, f, g, h, a, b, c, K(45), M(45) );
R( c, d, e, f, g, h, a, b, K(46), M(46) );
R( b, c, d, e, f, g, h, a, K(47), M(47) );
R( a, b, c, d, e, f, g, h, K(48), M(48) );
R( h, a, b, c, d, e, f, g, K(49), M(49) );
R( g, h, a, b, c, d, e, f, K(50), M(50) );
R( f, g, h, a, b, c, d, e, K(51), M(51) );
R( e, f, g, h, a, b, c, d, K(52), M(52) );
R( d, e, f, g, h, a, b, c, K(53), M(53) );
R( c, d, e, f, g, h, a, b, K(54), M(54) );
R( b, c, d, e, f, g, h, a, K(55), M(55) );
R( a, b, c, d, e, f, g, h, K(56), M(56) );
R( h, a, b, c, d, e, f, g, K(57), M(57) );
R( g, h, a, b, c, d, e, f, K(58), M(58) );
R( f, g, h, a, b, c, d, e, K(59), M(59) );
R( e, f, g, h, a, b, c, d, K(60), M(60) );
R( d, e, f, g, h, a, b, c, K(61), M(61) );
R( c, d, e, f, g, h, a, b, K(62), M(62) );
R( b, c, d, e, f, g, h, a, K(63), M(63) );
R( a, b, c, d, e, f, g, h, K(64), M(64) );
R( h, a, b, c, d, e, f, g, K(65), M(65) );
R( g, h, a, b, c, d, e, f, K(66), M(66) );
R( f, g, h, a, b, c, d, e, K(67), M(67) );
R( e, f, g, h, a, b, c, d, K(68), M(68) );
R( d, e, f, g, h, a, b, c, K(69), M(69) );
R( c, d, e, f, g, h, a, b, K(70), M(70) );
R( b, c, d, e, f, g, h, a, K(71), M(71) );
R( a, b, c, d, e, f, g, h, K(72), M(72) );
R( h, a, b, c, d, e, f, g, K(73), M(73) );
R( g, h, a, b, c, d, e, f, K(74), M(74) );
R( f, g, h, a, b, c, d, e, K(75), M(75) );
R( e, f, g, h, a, b, c, d, K(76), M(76) );
R( d, e, f, g, h, a, b, c, K(77), M(77) );
R( c, d, e, f, g, h, a, b, K(78), M(78) );
R( b, c, d, e, f, g, h, a, K(79), M(79) );
a = ctx->state[0] = u64plus (ctx->state[0], a);
b = ctx->state[1] = u64plus (ctx->state[1], b);
c = ctx->state[2] = u64plus (ctx->state[2], c);
d = ctx->state[3] = u64plus (ctx->state[3], d);
e = ctx->state[4] = u64plus (ctx->state[4], e);
f = ctx->state[5] = u64plus (ctx->state[5], f);
g = ctx->state[6] = u64plus (ctx->state[6], g);
h = ctx->state[7] = u64plus (ctx->state[7], h);
}
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,506 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "base64.h"
#include "hmac.h"
#include "sha1.h"
#include "sha256.h"
#include "spas_client.h"
#ifdef WIN32
#include <io.h>
#include <process.h>
#else
#include <unistd.h>
#endif
#ifdef SPAS_MT
#include <pthread.h>
#endif
#ifdef __cplusplus
namespace rocketmqSignature {
#endif
#define SPAS_VERSION "SPAS_V1_0"
static SPAS_CREDENTIAL g_credential;
static char g_path[SPAS_MAX_PATH];
static int g_loaded = 0;
static unsigned int refresh = 10;
static time_t modified = 0;
#ifdef SPAS_MT
static pthread_mutex_t cred_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_once_t cred_once = PTHREAD_ONCE_INIT;
static pthread_key_t cred_key;
#endif
extern void *_mem_alloc(unsigned int size);
extern void *_mem_realloc(void *ptr, unsigned int old_size,
unsigned int new_size);
extern void _mem_free(void *ptr);
extern void _trim(char *str);
void *_mem_alloc(unsigned int size) {
void *p = malloc(size);
if (p != NULL) {
memset(p, 0, size);
}
return p;
}
void *_mem_realloc(void *ptr, unsigned int old_size, unsigned int new_size) {
void *p = realloc(ptr, new_size);
if (p != NULL && new_size > old_size) {
memset((unsigned int *)p + old_size, 0, new_size - old_size);
}
return p;
}
void _mem_free(void *ptr) { free(ptr); }
void _trim(char *str) {
int len = strlen(str);
int i;
int done = 0;
for (i = len - 1; i >= 0; i--) {
switch (str[i]) {
case ' ':
case '\t':
case '\r':
case '\n':
str[i] = '\0';
break;
default:
done = 1;
break;
}
if (done) {
break;
}
}
}
static int _load_credential(SPAS_CREDENTIAL *pcred, char *path) {
FILE *fp = NULL;
char buf[SPAS_MAX_KEY_LEN * 2];
if (pcred == NULL || path == NULL) {
return ERROR_INVALID_PARAM;
}
fp = fopen(path, "r");
if (fp == NULL) {
return ERROR_FILE_OPEN;
}
memset(pcred, 0, sizeof(SPAS_CREDENTIAL));
while (fgets(buf, sizeof(buf), fp)) {
_trim(buf);
int len = strlen(SPAS_ACCESS_KEY_TAG);
if (strncmp(buf, SPAS_ACCESS_KEY_TAG, len) == 0 && buf[len] == '=') {
strncpy(pcred->access_key, buf + len + 1, SPAS_MAX_KEY_LEN - 1);
} else {
len = strlen(SPAS_SECRET_KEY_TAG);
if (strncmp(buf, SPAS_SECRET_KEY_TAG, len) == 0 && buf[len] == '=') {
strncpy(pcred->secret_key, buf + len + 1, SPAS_MAX_KEY_LEN - 1);
}
}
}
fclose(fp);
if (strlen(pcred->access_key) == 0 || strlen(pcred->secret_key) == 0) {
return ERROR_MISSING_KEY;
}
return SPAS_NO_ERROR;
}
#ifndef WIN32
static void _reload_credential(int sig) {
int ret;
SPAS_CREDENTIAL credential;
struct stat status;
struct sigaction act;
if (sig != SIGALRM) {
return;
}
memset(&act, 0, sizeof(act));
act.sa_handler = _reload_credential;
sigaction(SIGALRM, &act, NULL);
alarm(refresh);
if (g_path[0] != '\0') {
ret = stat(g_path, &status);
if (ret != 0) {
return;
}
if (status.st_mtime == modified) {
return;
}
ret = _load_credential(&credential, g_path);
if (ret != SPAS_NO_ERROR) {
return;
}
#ifdef SPAS_MT
pthread_mutex_lock(&cred_mutex);
#endif
memcpy(&g_credential, &credential, sizeof(SPAS_CREDENTIAL));
#ifdef SPAS_MT
pthread_mutex_unlock(&cred_mutex);
#endif
modified = status.st_mtime;
}
}
static int _update_credential_by_alarm() {
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = _reload_credential;
sigaction(SIGALRM, &act, NULL);
alarm(refresh);
return SPAS_NO_ERROR;
}
#endif
#ifdef SPAS_MT
static void *_update_credential_entry(void *arg) {
int ret;
SPAS_CREDENTIAL credential;
struct stat status;
struct timeval tv;
while (1) {
tv.tv_sec = refresh;
tv.tv_usec = 0;
select(0, NULL, NULL, NULL, &tv);
if (g_path[0] != '\0') {
ret = stat(g_path, &status);
if (ret != 0) {
continue;
}
if (status.st_mtime == modified) {
continue;
}
ret = _load_credential(&credential, g_path);
if (ret != SPAS_NO_ERROR) {
continue;
}
pthread_mutex_lock(&cred_mutex);
memcpy(&g_credential, &credential, sizeof(SPAS_CREDENTIAL));
pthread_mutex_unlock(&cred_mutex);
modified = status.st_mtime;
}
}
return NULL;
}
static int _update_credential_by_thread() {
pthread_t tid;
int ret;
ret = pthread_create(&tid, NULL, _update_credential_entry, NULL);
if (ret != 0) {
return ERROR_UPDATE_CREDENTIAL;
}
pthread_detach(tid);
return SPAS_NO_ERROR;
}
int spas_load_credential(char *path, CREDENTIAL_UPDATE_MODE mode) {
int ret = SPAS_NO_ERROR;
SPAS_CREDENTIAL credential;
if (g_loaded) {
return SPAS_NO_ERROR;
}
if (path == NULL) {
path = getenv(SPAS_CREDENTIAL_ENV);
if (path == NULL) {
return ERROR_NO_CREDENTIAL;
}
}
strncpy(g_path, path, SPAS_MAX_PATH - 1);
ret = _load_credential(&credential, path);
if (ret != SPAS_NO_ERROR) {
return ret;
}
#ifdef SPAS_MT
pthread_mutex_lock(&cred_mutex);
#endif
if (!g_loaded) {
memcpy(&g_credential, &credential, sizeof(SPAS_CREDENTIAL));
g_loaded = 1;
}
#ifdef SPAS_MT
pthread_mutex_unlock(&cred_mutex);
#endif
switch (mode) {
case UPDATE_BY_ALARM:
ret = _update_credential_by_alarm();
break;
#ifdef SPAS_MT
case UPDATE_BY_THREAD:
ret = _update_credential_by_thread();
break;
#endif
case NO_UPDATE:
default:
ret = SPAS_NO_ERROR;
break;
}
return ret;
}
#endif
SPAS_CREDENTIAL *spas_get_credential(void) {
SPAS_CREDENTIAL *credential =
(SPAS_CREDENTIAL *)_mem_alloc(sizeof(SPAS_CREDENTIAL));
if (credential != NULL) {
#ifdef SPAS_MT
pthread_mutex_lock(&cred_mutex);
#endif
memcpy(credential, &g_credential, sizeof(SPAS_CREDENTIAL));
#ifdef SPAS_MT
pthread_mutex_unlock(&cred_mutex);
#endif
}
return credential;
}
int spas_set_access_key(char *key) {
int len = 0;
if (key == NULL) {
return ERROR_INVALID_PARAM;
}
len = strlen(key);
if (len == 0 || len >= SPAS_MAX_KEY_LEN) {
return ERROR_KEY_LENGTH;
}
#ifdef SPAS_MT
pthread_mutex_lock(&cred_mutex);
#endif
memcpy(g_credential.access_key, key, len + 1);
#ifdef SPAS_MT
pthread_mutex_unlock(&cred_mutex);
#endif
return SPAS_NO_ERROR;
}
int spas_set_secret_key(char *key) {
int len = 0;
if (key == NULL) {
return ERROR_INVALID_PARAM;
}
len = strlen(key);
if (len == 0 || len >= SPAS_MAX_KEY_LEN) {
return ERROR_KEY_LENGTH;
}
#ifdef SPAS_MT
pthread_mutex_lock(&cred_mutex);
#endif
memcpy(g_credential.secret_key, key, len + 1);
#ifdef SPAS_MT
pthread_mutex_unlock(&cred_mutex);
#endif
return SPAS_NO_ERROR;
}
char *spas_get_access_key() { return g_credential.access_key; }
char *spas_get_secret_key() { return g_credential.secret_key; }
#ifdef SPAS_MT
static void _free_thread_credential(void *credential) {
if (credential != NULL) {
_mem_free(credential);
}
}
static void _init_credential_key(void) {
pthread_key_create(&cred_key, _free_thread_credential);
}
static SPAS_CREDENTIAL *_get_thread_credential(void) {
int ret = 0;
SPAS_CREDENTIAL *credential = NULL;
ret = pthread_once(&cred_once, _init_credential_key);
if (ret != 0) {
return NULL;
}
credential = pthread_getspecific(cred_key);
if (credential == NULL) {
credential = _mem_alloc(sizeof(SPAS_CREDENTIAL));
if (credential == NULL) {
return NULL;
}
ret = pthread_setspecific(cred_key, credential);
if (ret != 0) {
_mem_free(credential);
return NULL;
}
}
return credential;
}
int spas_load_thread_credential(char *path) {
int ret = SPAS_NO_ERROR;
SPAS_CREDENTIAL *credential = NULL;
credential = _get_thread_credential();
if (credential == NULL) {
return ERROR_MEM_ALLOC;
}
ret = _load_credential(credential, path);
if (ret != SPAS_NO_ERROR) {
memset(credential, 0, sizeof(SPAS_CREDENTIAL));
return ret;
}
return SPAS_NO_ERROR;
}
int spas_set_thread_access_key(char *key) {
int len = 0;
SPAS_CREDENTIAL *credential = NULL;
if (key == NULL) {
return ERROR_INVALID_PARAM;
}
len = strlen(key);
if (len == 0 || len >= SPAS_MAX_KEY_LEN) {
return ERROR_KEY_LENGTH;
}
credential = _get_thread_credential();
if (credential == NULL) {
return ERROR_MEM_ALLOC;
}
memcpy(credential->access_key, key, len + 1);
return SPAS_NO_ERROR;
}
int spas_set_thread_secret_key(char *key) {
int len = 0;
SPAS_CREDENTIAL *credential = NULL;
if (key == NULL) {
return ERROR_INVALID_PARAM;
}
len = strlen(key);
if (len == 0 || len >= SPAS_MAX_KEY_LEN) {
return ERROR_KEY_LENGTH;
}
credential = _get_thread_credential();
if (credential == NULL) {
return ERROR_MEM_ALLOC;
}
memcpy(credential->secret_key, key, len + 1);
return SPAS_NO_ERROR;
}
char *spas_get_thread_access_key(void) {
SPAS_CREDENTIAL *credential = _get_thread_credential();
if (credential == NULL) {
return NULL;
}
return credential->access_key;
}
char *spas_get_thread_secret_key(void) {
SPAS_CREDENTIAL *credential = _get_thread_credential();
if (credential == NULL) {
return NULL;
}
return credential->secret_key;
}
#endif
char *spas_get_signature(const SPAS_PARAM_LIST *list, const char *key) {
return spas_get_signature2(list, key, SIGN_HMACSHA1);
}
char *spas_get_signature2(const SPAS_PARAM_LIST *list, const char *key,
SPAS_SIGN_ALGORITHM algorithm) {
char *sign = NULL;
char *data = NULL;
if (list == NULL || key == NULL) {
return NULL;
}
data = param_list_to_str(list);
if (data == NULL) {
return NULL;
}
sign = spas_sign2(data, strlen(data), key, algorithm);
_mem_free(data);
return sign;
}
char *spas_sign(const char *data, size_t size, const char *key) {
return spas_sign2(data, size, key, SIGN_HMACSHA1);
}
char *spas_sign2(const char *data, size_t size, const char *key,
SPAS_SIGN_ALGORITHM algorithm) {
int ret;
int dsize = 0;
char *sha_buf = NULL;
char *base64_ret = NULL;
if (data == NULL || key == NULL) {
return NULL;
}
if (algorithm == SIGN_HMACSHA1) {
dsize = SHA1_DIGEST_SIZE;
sha_buf = (char *)_mem_alloc(dsize + 1);
if (sha_buf == NULL) {
return NULL;
}
ret = hmac_sha1(key, strlen(key), data, size, sha_buf);
if (ret < 0) {
_mem_free(sha_buf);
return NULL;
}
} else if (algorithm == SIGN_HMACSHA256) {
dsize = SHA256_DIGEST_SIZE;
sha_buf = (char *)_mem_alloc(dsize + 1);
if (sha_buf == NULL) {
return NULL;
}
ret = hmac_sha256(key, strlen(key), data, strlen(data), sha_buf);
if (ret < 0) {
_mem_free(sha_buf);
return NULL;
}
} else {
return NULL;
}
ret = base64_encode_alloc(sha_buf, dsize, &base64_ret);
_mem_free(sha_buf);
return base64_ret;
}
void spas_mem_free(char *pSignature) { _mem_free(pSignature); }
char *spas_get_version(void) { return SPAS_VERSION; }
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,25 @@
create librocketmq.a
addlib ../bin/lib/libboost_chrono.a
addlib ../bin/lib/libboost_date_time.a
addlib ../bin/lib/libboost_filesystem.a
addlib ../bin/lib/libboost_iostreams.a
addlib ../bin/lib/libboost_locale.a
addlib ../bin/lib/libboost_log.a
addlib ../bin/lib/libboost_log_setup.a
addlib ../bin/lib/libboost_regex.a
addlib ../bin/lib/libboost_serialization.a
addlib ../bin/lib/libboost_system.a
addlib ../bin/lib/libboost_thread.a
addlib ../bin/lib/libboost_wserialization.a
addlib ../bin/lib/libssl.a
addlib ../bin/lib/libcrypto.a
addlib ../bin/lib/libevent.a
addlib ../bin/lib/libevent_core.a
addlib ../bin/lib/libevent_extra.a
addlib ../bin/lib/libevent_pthreads.a
addlib ../bin/lib/libevent_openssl.a
addlib ../bin/lib/libjsoncpp.a
addlib ../bin/lib/libSignature.a
addlib ../bin/librocketmq.a
save
end

View File

@@ -0,0 +1,79 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# source files
project(rocketmq-client)
file(GLOB_RECURSE SRC_FILES ${CMAKE_SOURCE_DIR}/src/*)
list(REMOVE_ITEM SRC_FILES ${CMAKE_SOURCE_DIR}/src/dllmain.cpp)
# subdirs
SET(SUB_DIRS)
file(GLOB children ${CMAKE_SOURCE_DIR}/src/*)
FOREACH (child ${children})
IF (IS_DIRECTORY ${child})
LIST(APPEND SUB_DIRS ${child})
ENDIF ()
ENDFOREACH ()
LIST(APPEND SUB_DIRS ${CMAKE_SOURCE_DIR}/src)
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${SUB_DIRS})
# libs_directories
file(GLOB LIB_DIRS ${CMAKE_SOURCE_DIR}/libs/*)
foreach (dir ${LIB_DIRS})
if (IS_DIRECTORY ${dir})
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH};${dir})
include_directories(${dir}/include)
endif ()
endforeach ()
# static
if (BUILD_ROCKETMQ_STATIC)
add_library(rocketmq_static STATIC ${SRC_FILES})
set_target_properties(rocketmq_static PROPERTIES OUTPUT_NAME "rocketmq")
add_dependencies(rocketmq_static Signature)
target_link_libraries(rocketmq_static Signature)
target_link_libraries(rocketmq_static ${JSONCPP_LIBRARIES})
target_link_libraries(rocketmq_static ${LIBEVENT_LIBRARIES})
target_link_libraries(rocketmq_static ${Boost_LIBRARIES})
target_link_libraries(rocketmq_static ${OPENSSL_LIBRARIES})
target_link_libraries(rocketmq_static ${deplibs})
endif ()
# shared
if (BUILD_ROCKETMQ_SHARED)
set(CMAKE_SHARED_LINKER_FLAGS "-DBOOST_ALL_DYN_LINK -shared ")
add_library(rocketmq_shared SHARED ${SRC_FILES})
set_target_properties(rocketmq_shared PROPERTIES OUTPUT_NAME "rocketmq")
add_dependencies(rocketmq_shared Signature)
target_link_libraries(rocketmq_shared Signature)
target_link_libraries(rocketmq_shared ${JSONCPP_LIBRARIES})
target_link_libraries(rocketmq_shared ${LIBEVENT_LIBRARIES})
target_link_libraries(rocketmq_shared ${Boost_LIBRARIES})
target_link_libraries(rocketmq_shared ${OPENSSL_LIBRARIES})
target_link_libraries(rocketmq_shared ${deplibs})
endif ()
# install
if (BUILD_ROCKETMQ_STATIC)
install(TARGETS rocketmq_static DESTINATION lib)
endif ()
if (BUILD_ROCKETMQ_SHARED)
install(TARGETS rocketmq_shared DESTINATION lib)
endif ()
install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/rocketmq)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/doc/ DESTINATION doc)

View File

@@ -0,0 +1,32 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
BASEDIR=$(dirname "$0")
if [[ ! -d ${BASEDIR}/rocketmq_x64/CENTOS/ ]]; then
echo "Can not find SPEC FILE"
exit 1
fi
if [[ ! -d /root/rpmbuild/SOURCES/rocketmq/include ]]; then
mkdir -p /root/rpmbuild/SOURCES/rocketmq
mkdir -p /root/rpmbuild/SOURCES/rocketmq/include
mkdir -p /root/rpmbuild/SOURCES/rocketmq/bin
fi
cp -R ${BASEDIR}/../include/* /root/rpmbuild/SOURCES/rocketmq/include
cp ${BASEDIR}/../bin/librocketmq.so /root/rpmbuild/SOURCES/rocketmq/bin
cp ${BASEDIR}/../bin/librocketmq.a /root/rpmbuild/SOURCES/rocketmq/bin
cp ${BASEDIR}/rocketmq_x64/CENTOS/rocketmq-client-cpp.spec /root/rpmbuild/SPECS
rpmbuild -bb /root/rpmbuild/SPECS/rocketmq-client-cpp.spec
cp /root/rpmbuild/RPMS/x86_64/*.rpm ${BASEDIR}/rocketmq_x64

View File

@@ -0,0 +1,68 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Summary: A C++ Client of Apache RocketMQ
Name: rocketmq-client-cpp
Version: 2.2.0
Release: centos
Group: Apache
License: APLv2
Source: https://github.com/apache/rocketmq-client-cpp
URL: http://rocketmq.apache.org/
Distribution: Linux
%define _prefix /usr/local
AutoReqProv: no
%description
A C++ Client of Apache RocketMQ
%prep
pwd
cat /etc/redhat-release|sed -r 's/.* ([0-9]+)\..*/\1/'
OS_VERSION=`cat /etc/redhat-release|sed -r 's/.* ([0-9]+)\..*/\1/'`
echo "OS_VERSION=${OS_VERSION}"
%build
%install
# create dirs
mkdir -p $RPM_BUILD_ROOT%{_prefix}
# create dirs
mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib
mkdir -p $RPM_BUILD_ROOT%{_prefix}/include/rocketmq
# copy files
cp -f ${RPM_SOURCE_DIR}/rocketmq/bin/librocketmq.so $RPM_BUILD_ROOT%{_prefix}/lib
cp -f ${RPM_SOURCE_DIR}/rocketmq/bin/librocketmq.a $RPM_BUILD_ROOT%{_prefix}/lib
cp -rf ${RPM_SOURCE_DIR}/rocketmq/include/* $RPM_BUILD_ROOT%{_prefix}/include/rocketmq
# package information
%files
# set file attribute here
%defattr(-, root, root, 0755)
%{_prefix}/lib
%{_prefix}/include
%define debug_package %{nil}
%define __os_install_post %{nil}

View File

@@ -0,0 +1,939 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "MQClientAPIImpl.h"
#include <assert.h>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <fstream>
#include "CommunicationMode.h"
#include "Logging.h"
#include "MQDecoder.h"
#include "PullResultExt.h"
namespace rocketmq {
//<!************************************************************************
MQClientAPIImpl::MQClientAPIImpl(const string& mqClientId, bool enableSsl, const std::string& sslPropertyFile)
: m_firstFetchNameSrv(true), m_mqClientId(mqClientId) {}
MQClientAPIImpl::MQClientAPIImpl(const string& mqClientId,
ClientRemotingProcessor* clientRemotingProcessor,
int pullThreadNum,
uint64_t tcpConnectTimeout,
uint64_t tcpTransportTryLockTimeout,
string unitName,
bool enableSsl,
const std::string& sslPropertyFile)
: m_firstFetchNameSrv(true), m_mqClientId(mqClientId) {
m_pRemotingClient.reset(
new TcpRemotingClient(pullThreadNum, tcpConnectTimeout, tcpTransportTryLockTimeout, enableSsl, sslPropertyFile));
m_pRemotingClient->registerProcessor(CHECK_TRANSACTION_STATE, clientRemotingProcessor);
m_pRemotingClient->registerProcessor(RESET_CONSUMER_CLIENT_OFFSET, clientRemotingProcessor);
m_pRemotingClient->registerProcessor(GET_CONSUMER_STATUS_FROM_CLIENT, clientRemotingProcessor);
m_pRemotingClient->registerProcessor(GET_CONSUMER_RUNNING_INFO, clientRemotingProcessor);
m_pRemotingClient->registerProcessor(NOTIFY_CONSUMER_IDS_CHANGED, clientRemotingProcessor);
m_pRemotingClient->registerProcessor(CONSUME_MESSAGE_DIRECTLY, clientRemotingProcessor);
m_topAddressing.reset(new TopAddressing(unitName));
}
MQClientAPIImpl::~MQClientAPIImpl() {
m_pRemotingClient = NULL;
m_topAddressing = NULL;
}
void MQClientAPIImpl::stopAllTcpTransportThread() {
m_pRemotingClient->stopAllTcpTransportThread();
}
bool MQClientAPIImpl::writeDataToFile(string filename, string data, bool isSync) {
if (data.size() == 0)
return false;
FILE* pFd = fopen(filename.c_str(), "w+");
if (NULL == pFd) {
LOG_ERROR("fopen failed, filename:%s", filename.c_str());
return false;
}
int byte_write = 0;
int byte_left = data.size();
const char* pData = data.c_str();
while (byte_left > 0) {
byte_write = fwrite(pData, sizeof(char), byte_left, pFd);
if (byte_write == byte_left) {
if (ferror(pFd)) {
LOG_ERROR("write data fail, data len:" SIZET_FMT ", file:%s, msg:%s", data.size(), filename.c_str(),
strerror(errno));
fclose(pFd);
return false;
}
}
byte_left -= byte_write;
pData += byte_write;
}
pData = NULL;
if (isSync) {
LOG_INFO("fsync with filename:%s", filename.c_str());
fflush(pFd);
}
fclose(pFd);
return true;
}
string MQClientAPIImpl::fetchNameServerAddr(const string& NSDomain) {
try {
string homeDir(UtilAll::getHomeDirectory());
string storePath = homeDir + "/logs/rocketmq-cpp/snapshot";
boost::filesystem::path dir(storePath);
boost::system::error_code ec;
if (!boost::filesystem::exists(dir, ec)) {
if (!boost::filesystem::create_directory(dir, ec)) {
LOG_ERROR("create data dir:%s error", storePath.c_str());
return "";
}
}
string file(storePath);
string fileBak(storePath);
vector<string> ret_;
int retSize = UtilAll::Split(ret_, m_mqClientId, "@");
if (retSize == 2) {
file.append("/nameserver_addr-").append(ret_[retSize - 1]);
} else {
LOG_ERROR("split mqClientId:%s fail", m_mqClientId.c_str());
file.append("/nameserver_addr-DEFAULT");
}
boost::filesystem::path snapshot_file(file);
fileBak.append("/nameserver_addr.bak");
const string addrs = m_topAddressing->fetchNSAddr(NSDomain);
if (addrs.empty()) {
if (m_nameSrvAddr.empty()) {
LOG_INFO("Load the name server snapshot local file:%s", file.c_str());
if (boost::filesystem::exists(snapshot_file)) {
ifstream snapshot_file(file, ios::binary);
istreambuf_iterator<char> beg(snapshot_file), end;
string filecontent(beg, end);
updateNameServerAddr(filecontent);
m_nameSrvAddr = filecontent;
} else {
LOG_WARN("The name server snapshot local file not exists");
}
}
} else {
if (m_firstFetchNameSrv == true) {
// it is the first time, so need to create the name server snapshot
// local file
m_firstFetchNameSrv = false;
}
if (addrs.compare(m_nameSrvAddr) != 0) {
LOG_INFO("name server address changed, old: %s, new: %s", m_nameSrvAddr.c_str(), addrs.c_str());
updateNameServerAddr(addrs);
m_nameSrvAddr = addrs;
} else {
if (!m_firstFetchNameSrv)
return m_nameSrvAddr;
}
// update the snapshot local file if nameSrv changes or
// m_firstFetchNameSrv==true
if (writeDataToFile(fileBak, addrs, true)) {
if (!UtilAll::ReplaceFile(fileBak, file))
LOG_ERROR("could not rename bak file:%s", strerror(errno));
}
}
if (!boost::filesystem::exists(snapshot_file)) {
// the name server snapshot local file maybe deleted by force, create it
if (writeDataToFile(fileBak, m_nameSrvAddr, true)) {
if (!UtilAll::ReplaceFile(fileBak, file))
LOG_ERROR("could not rename bak file:%s", strerror(errno));
}
}
} catch (...) {
}
return m_nameSrvAddr;
}
void MQClientAPIImpl::updateNameServerAddr(const string& addrs) {
if (m_pRemotingClient != NULL)
m_pRemotingClient->updateNameServerAddressList(addrs);
}
void MQClientAPIImpl::callSignatureBeforeRequest(const string& addr,
RemotingCommand& request,
const SessionCredentials& session_credentials) {
ClientRPCHook rpcHook(session_credentials);
rpcHook.doBeforeRequest(addr, request);
}
// Note: all request rules: throw exception if got broker error response,
// exclude getTopicRouteInfoFromNameServer and unregisterClient
void MQClientAPIImpl::createTopic(const string& addr,
const string& defaultTopic,
TopicConfig topicConfig,
const SessionCredentials& sessionCredentials) {
string topicWithProjectGroup = topicConfig.getTopicName();
CreateTopicRequestHeader* requestHeader = new CreateTopicRequestHeader();
requestHeader->topic = (topicWithProjectGroup);
requestHeader->defaultTopic = (defaultTopic);
requestHeader->readQueueNums = (topicConfig.getReadQueueNums());
requestHeader->writeQueueNums = (topicConfig.getWriteQueueNums());
requestHeader->perm = (topicConfig.getPerm());
requestHeader->topicFilterType = (topicConfig.getTopicFilterType());
RemotingCommand request(UPDATE_AND_CREATE_TOPIC, requestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request));
if (response) {
switch (response->getCode()) {
case SUCCESS_VALUE:
return;
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
}
void MQClientAPIImpl::endTransactionOneway(std::string addr,
EndTransactionRequestHeader* requestHeader,
std::string remark,
const SessionCredentials& sessionCredentials) {
RemotingCommand request(END_TRANSACTION, requestHeader);
request.setRemark(remark);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
m_pRemotingClient->invokeOneway(addr, request);
return;
}
SendResult MQClientAPIImpl::sendMessage(const string& addr,
const string& brokerName,
const MQMessage& msg,
SendMessageRequestHeader* pRequestHeader,
int timeoutMillis,
int maxRetrySendTimes,
int communicationMode,
SendCallback* pSendCallback,
const SessionCredentials& sessionCredentials) {
// RemotingCommand request(SEND_MESSAGE, pRequestHeader);
// Using MQ V2 Protocol to end messages.
SendMessageRequestHeaderV2* pRequestHeaderV2 = new SendMessageRequestHeaderV2(*pRequestHeader);
RemotingCommand request(SEND_MESSAGE_V2, pRequestHeaderV2);
delete pRequestHeader; // delete to avoid memory leak.
string body = msg.getBody();
request.SetBody(body.c_str(), body.length());
request.setMsgBody(body);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
switch (communicationMode) {
case ComMode_ONEWAY:
m_pRemotingClient->invokeOneway(addr, request);
break;
case ComMode_ASYNC:
sendMessageAsync(addr, brokerName, msg, request, pSendCallback, timeoutMillis, maxRetrySendTimes, 1);
break;
case ComMode_SYNC:
return sendMessageSync(addr, brokerName, msg, request, timeoutMillis);
default:
break;
}
return SendResult();
}
void MQClientAPIImpl::sendHeartbeat(const string& addr,
HeartbeatData* pHeartbeatData,
const SessionCredentials& sessionCredentials) {
RemotingCommand request(HEART_BEAT, NULL);
string body;
pHeartbeatData->Encode(body);
request.SetBody(body.data(), body.length());
request.setMsgBody(body);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
if (m_pRemotingClient->invokeHeartBeat(addr, request)) {
LOG_DEBUG("sendHeartbeat to broker:%s success", addr.c_str());
} else {
LOG_WARN("sendHeartbeat to broker:%s failed", addr.c_str());
}
}
void MQClientAPIImpl::unregisterClient(const string& addr,
const string& clientID,
const string& producerGroup,
const string& consumerGroup,
const SessionCredentials& sessionCredentials) {
LOG_INFO("unregisterClient to broker:%s", addr.c_str());
RemotingCommand request(UNREGISTER_CLIENT, new UnregisterClientRequestHeader(clientID, producerGroup, consumerGroup));
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request));
if (response) {
switch (response->getCode()) {
case SUCCESS_VALUE:
LOG_INFO("unregisterClient to:%s success", addr.c_str());
return;
default:
break;
}
LOG_WARN("unregisterClient fail:%s,%d", response->getRemark().c_str(), response->getCode());
}
}
// return NULL if got no response or error response
TopicRouteData* MQClientAPIImpl::getTopicRouteInfoFromNameServer(const string& topic,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
RemotingCommand request(GET_ROUTEINTO_BY_TOPIC, new GetRouteInfoRequestHeader(topic));
callSignatureBeforeRequest("", request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync("", request, timeoutMillis));
if (pResponse != NULL) {
if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
switch (pResponse->getCode()) {
case SUCCESS_VALUE: {
const MemoryBlock* pbody = pResponse->GetBody();
if (pbody->getSize()) {
TopicRouteData* topicRoute = TopicRouteData::Decode(pbody);
return topicRoute;
}
}
case TOPIC_NOT_EXIST: {
LOG_WARN("Get topic[%s] route failed [TOPIC_NOT_EXIST].", topic.c_str());
return NULL;
}
default:
break;
}
LOG_WARN("%s,%d", pResponse->getRemark().c_str(), pResponse->getCode());
return NULL;
}
}
LOG_WARN("Get topic[%s] route failed [Null Response].", topic.c_str());
return NULL;
}
TopicList* MQClientAPIImpl::getTopicListFromNameServer(const SessionCredentials& sessionCredentials) {
RemotingCommand request(GET_ALL_TOPIC_LIST_FROM_NAMESERVER, NULL);
callSignatureBeforeRequest("", request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync("", request));
if (pResponse != NULL) {
if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
switch (pResponse->getCode()) {
case SUCCESS_VALUE: {
const MemoryBlock* pbody = pResponse->GetBody();
if (pbody->getSize()) {
TopicList* topicList = TopicList::Decode(pbody);
return topicList;
}
}
default:
break;
}
THROW_MQEXCEPTION(MQClientException, pResponse->getRemark(), pResponse->getCode());
}
}
return NULL;
}
int MQClientAPIImpl::wipeWritePermOfBroker(const string& namesrvAddr, const string& brokerName, int timeoutMillis) {
return 0;
}
void MQClientAPIImpl::deleteTopicInBroker(const string& addr, const string& topic, int timeoutMillis) {}
void MQClientAPIImpl::deleteTopicInNameServer(const string& addr, const string& topic, int timeoutMillis) {}
void MQClientAPIImpl::deleteSubscriptionGroup(const string& addr, const string& groupName, int timeoutMillis) {}
string MQClientAPIImpl::getKVConfigByValue(const string& projectNamespace,
const string& projectGroup,
int timeoutMillis) {
return "";
}
KVTable MQClientAPIImpl::getKVListByNamespace(const string& projectNamespace, int timeoutMillis) {
return KVTable();
}
void MQClientAPIImpl::deleteKVConfigByValue(const string& projectNamespace,
const string& projectGroup,
int timeoutMillis) {}
SendResult MQClientAPIImpl::sendMessageSync(const string& addr,
const string& brokerName,
const MQMessage& msg,
RemotingCommand& request,
int timeoutMillis) {
//<!block util response;
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (pResponse != NULL) {
try {
SendResult result = processSendResponse(brokerName, msg, pResponse.get());
LOG_DEBUG("sendMessageSync success:%s to addr:%s,brokername:%s, send status:%d", msg.toString().c_str(),
addr.c_str(), brokerName.c_str(), (int)result.getSendStatus());
return result;
} catch (...) {
LOG_ERROR("send error");
}
}
THROW_MQEXCEPTION(MQClientException, "response is null", -1);
}
void MQClientAPIImpl::sendMessageAsync(const string& addr,
const string& brokerName,
const MQMessage& msg,
RemotingCommand& request,
SendCallback* pSendCallback,
int64 timeoutMilliseconds,
int maxRetryTimes,
int retrySendTimes) {
int64 begin_time = UtilAll::currentTimeMillis();
//<!delete in future;
// AsyncCallbackWrap* cbw = new SendCallbackWrap(brokerName, msg, pSendCallback, this);
LOG_DEBUG("sendMessageAsync request:%s, timeout:%lld, maxRetryTimes:%d retrySendTimes:%d", request.ToString().data(),
timeoutMilliseconds, maxRetryTimes, retrySendTimes);
// Use smart ptr to control cbw.
std::shared_ptr<AsyncCallbackWrap> cbw = std::make_shared<SendCallbackWrap>(brokerName, msg, pSendCallback, this);
if (m_pRemotingClient->invokeAsync(addr, request, cbw, timeoutMilliseconds, maxRetryTimes, retrySendTimes) == false) {
LOG_WARN("invokeAsync failed to addr:%s,topic:%s, timeout:%lld, maxRetryTimes:%d, retrySendTimes:%d", addr.c_str(),
msg.getTopic().data(), timeoutMilliseconds, maxRetryTimes, retrySendTimes);
// when getTcp return false, need consider retrySendTimes
int retry_time = retrySendTimes + 1;
int64 time_out = timeoutMilliseconds - (UtilAll::currentTimeMillis() - begin_time);
while (retry_time < maxRetryTimes && time_out > 0) {
begin_time = UtilAll::currentTimeMillis();
if (m_pRemotingClient->invokeAsync(addr, request, cbw, time_out, maxRetryTimes, retry_time) == false) {
retry_time += 1;
time_out = time_out - (UtilAll::currentTimeMillis() - begin_time);
LOG_WARN("invokeAsync retry failed to addr:%s,topic:%s, timeout:%lld, maxRetryTimes:%d, retrySendTimes:%d",
addr.c_str(), msg.getTopic().data(), time_out, maxRetryTimes, retry_time);
continue;
} else {
return; // invokeAsync success
}
}
LOG_ERROR("sendMessageAsync failed to addr:%s,topic:%s, timeout:%lld, maxRetryTimes:%d, retrySendTimes:%d",
addr.c_str(), msg.getTopic().data(), time_out, maxRetryTimes, retrySendTimes);
if (cbw && pSendCallback != nullptr) {
cbw->onException();
// deleteAndZero(cbw);
} else {
THROW_MQEXCEPTION(MQClientException, "sendMessageAsync failed", -1);
}
}
}
PullResult* MQClientAPIImpl::pullMessage(const string& addr,
PullMessageRequestHeader* pRequestHeader,
int timeoutMillis,
int communicationMode,
PullCallback* pullCallback,
void* pArg,
const SessionCredentials& sessionCredentials) {
RemotingCommand request(PULL_MESSAGE, pRequestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
switch (communicationMode) {
case ComMode_ONEWAY:
break;
case ComMode_ASYNC:
pullMessageAsync(addr, request, timeoutMillis, pullCallback, pArg);
break;
case ComMode_SYNC:
return pullMessageSync(addr, request, timeoutMillis);
default:
break;
}
return NULL;
}
void MQClientAPIImpl::pullMessageAsync(const string& addr,
RemotingCommand& request,
int timeoutMillis,
PullCallback* pullCallback,
void* pArg) {
// AsyncCallbackWrap* cbw = new PullCallbackWrap(pullCallback, this, pArg);
std::shared_ptr<AsyncCallbackWrap> cbw = std::make_shared<PullCallbackWrap>(pullCallback, this, pArg);
if (m_pRemotingClient->invokeAsync(addr, request, cbw, timeoutMillis) == false) {
LOG_ERROR("pullMessageAsync failed of addr:%s, mq:%s", addr.c_str(),
static_cast<AsyncArg*>(pArg)->mq.toString().data());
// deleteAndZero(cbw);
THROW_MQEXCEPTION(MQClientException, "pullMessageAsync failed", -1);
}
}
PullResult* MQClientAPIImpl::pullMessageSync(const string& addr, RemotingCommand& request, int timeoutMillis) {
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (pResponse != NULL) {
if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
try {
PullResult* pullResult = processPullResponse(pResponse.get()); // pullMessage will handle
// exception from
// processPullResponse
return pullResult;
} catch (MQException& e) {
LOG_ERROR("%s", e.what());
return NULL;
}
}
}
return NULL;
}
SendResult MQClientAPIImpl::processSendResponse(const string& brokerName,
const MQMessage& msg,
RemotingCommand* pResponse) {
SendStatus sendStatus = SEND_OK;
int res = 0;
switch (pResponse->getCode()) {
case FLUSH_DISK_TIMEOUT:
sendStatus = SEND_FLUSH_DISK_TIMEOUT;
break;
case FLUSH_SLAVE_TIMEOUT:
sendStatus = SEND_FLUSH_SLAVE_TIMEOUT;
break;
case SLAVE_NOT_AVAILABLE:
sendStatus = SEND_SLAVE_NOT_AVAILABLE;
break;
case SUCCESS_VALUE:
sendStatus = SEND_OK;
break;
default:
res = -1;
break;
}
if (res == 0) {
SendMessageResponseHeader* responseHeader = (SendMessageResponseHeader*)pResponse->getCommandHeader();
MQMessageQueue messageQueue(msg.getTopic(), brokerName, responseHeader->queueId);
string unique_msgId = msg.getProperty(MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX);
return SendResult(sendStatus, unique_msgId, responseHeader->msgId, messageQueue, responseHeader->queueOffset,
responseHeader->regionId);
}
LOG_ERROR("processSendResponse error remark:%s, error code:%d", (pResponse->getRemark()).c_str(),
pResponse->getCode());
THROW_MQEXCEPTION(MQClientException, pResponse->getRemark(), pResponse->getCode());
}
PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* pResponse) {
PullStatus pullStatus = NO_NEW_MSG;
switch (pResponse->getCode()) {
case SUCCESS_VALUE:
pullStatus = FOUND;
break;
case PULL_NOT_FOUND:
pullStatus = NO_NEW_MSG;
break;
case PULL_RETRY_IMMEDIATELY:
pullStatus = NO_MATCHED_MSG;
break;
case PULL_OFFSET_MOVED:
pullStatus = OFFSET_ILLEGAL;
break;
default:
THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode());
break;
}
PullMessageResponseHeader* responseHeader = static_cast<PullMessageResponseHeader*>(pResponse->getCommandHeader());
if (!responseHeader) {
LOG_ERROR("processPullResponse:responseHeader is NULL");
THROW_MQEXCEPTION(MQClientException, "processPullResponse:responseHeader is NULL", -1);
}
//<!get body,delete outsite;
MemoryBlock bodyFromResponse = *(pResponse->GetBody()); // response data judgement had been done outside
// of processPullResponse
if (bodyFromResponse.getSize() == 0) {
if (pullStatus != FOUND) {
return new PullResultExt(pullStatus, responseHeader->nextBeginOffset, responseHeader->minOffset,
responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId);
} else {
THROW_MQEXCEPTION(MQClientException, "memoryBody size is 0, but pullStatus equals found", -1);
}
} else {
return new PullResultExt(pullStatus, responseHeader->nextBeginOffset, responseHeader->minOffset,
responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId, bodyFromResponse);
}
}
//<!***************************************************************************
int64 MQClientAPIImpl::getMinOffset(const string& addr,
const string& topic,
int queueId,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
GetMinOffsetRequestHeader* pRequestHeader = new GetMinOffsetRequestHeader();
pRequestHeader->topic = topic;
pRequestHeader->queueId = queueId;
RemotingCommand request(GET_MIN_OFFSET, pRequestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (response) {
switch (response->getCode()) {
case SUCCESS_VALUE: {
GetMinOffsetResponseHeader* responseHeader = (GetMinOffsetResponseHeader*)response->getCommandHeader();
int64 offset = responseHeader->offset;
return offset;
}
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
}
int64 MQClientAPIImpl::getMaxOffset(const string& addr,
const string& topic,
int queueId,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
GetMaxOffsetRequestHeader* pRequestHeader = new GetMaxOffsetRequestHeader();
pRequestHeader->topic = topic;
pRequestHeader->queueId = queueId;
RemotingCommand request(GET_MAX_OFFSET, pRequestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (response) {
switch (response->getCode()) {
case SUCCESS_VALUE: {
GetMaxOffsetResponseHeader* responseHeader = (GetMaxOffsetResponseHeader*)response->getCommandHeader();
int64 offset = responseHeader->offset;
return offset;
}
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
}
int64 MQClientAPIImpl::searchOffset(const string& addr,
const string& topic,
int queueId,
uint64_t timestamp,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
SearchOffsetRequestHeader* pRequestHeader = new SearchOffsetRequestHeader();
pRequestHeader->topic = topic;
pRequestHeader->queueId = queueId;
pRequestHeader->timestamp = timestamp;
RemotingCommand request(SEARCH_OFFSET_BY_TIMESTAMP, pRequestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (response) {
switch (response->getCode()) {
case SUCCESS_VALUE: {
SearchOffsetResponseHeader* responseHeader = (SearchOffsetResponseHeader*)response->getCommandHeader();
int64 offset = responseHeader->offset;
return offset;
}
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
}
MQMessageExt* MQClientAPIImpl::viewMessage(const string& addr,
int64 phyoffset,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
ViewMessageRequestHeader* pRequestHeader = new ViewMessageRequestHeader();
pRequestHeader->offset = phyoffset;
RemotingCommand request(VIEW_MESSAGE_BY_ID, pRequestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (response) {
switch (response->getCode()) {
case SUCCESS_VALUE: {
}
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
}
int64 MQClientAPIImpl::getEarliestMsgStoretime(const string& addr,
const string& topic,
int queueId,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
GetEarliestMsgStoretimeRequestHeader* pRequestHeader = new GetEarliestMsgStoretimeRequestHeader();
pRequestHeader->topic = topic;
pRequestHeader->queueId = queueId;
RemotingCommand request(GET_EARLIEST_MSG_STORETIME, pRequestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (response) {
switch (response->getCode()) {
case SUCCESS_VALUE: {
GetEarliestMsgStoretimeResponseHeader* responseHeader =
(GetEarliestMsgStoretimeResponseHeader*)response->getCommandHeader();
int64 timestamp = responseHeader->timestamp;
return timestamp;
}
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
}
void MQClientAPIImpl::getConsumerIdListByGroup(const string& addr,
const string& consumerGroup,
vector<string>& cids,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
GetConsumerListByGroupRequestHeader* pRequestHeader = new GetConsumerListByGroupRequestHeader();
pRequestHeader->consumerGroup = consumerGroup;
RemotingCommand request(GET_CONSUMER_LIST_BY_GROUP, pRequestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (pResponse != NULL) {
if ((pResponse->GetBody()->getSize() == 0) || (pResponse->GetBody()->getData() != NULL)) {
switch (pResponse->getCode()) {
case SUCCESS_VALUE: {
const MemoryBlock* pbody = pResponse->GetBody();
if (pbody->getSize()) {
GetConsumerListByGroupResponseBody::Decode(pbody, cids);
return;
}
}
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode());
}
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
}
int64 MQClientAPIImpl::queryConsumerOffset(const string& addr,
QueryConsumerOffsetRequestHeader* pRequestHeader,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
RemotingCommand request(QUERY_CONSUMER_OFFSET, pRequestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (response) {
switch (response->getCode()) {
case SUCCESS_VALUE: {
QueryConsumerOffsetResponseHeader* responseHeader =
(QueryConsumerOffsetResponseHeader*)response->getCommandHeader();
int64 consumerOffset = responseHeader->offset;
return consumerOffset;
}
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
return -1;
}
void MQClientAPIImpl::updateConsumerOffset(const string& addr,
UpdateConsumerOffsetRequestHeader* pRequestHeader,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
RemotingCommand request(UPDATE_CONSUMER_OFFSET, pRequestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (response) {
switch (response->getCode()) {
case SUCCESS_VALUE: {
return;
}
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
}
void MQClientAPIImpl::updateConsumerOffsetOneway(const string& addr,
UpdateConsumerOffsetRequestHeader* pRequestHeader,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
RemotingCommand request(UPDATE_CONSUMER_OFFSET, pRequestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
m_pRemotingClient->invokeOneway(addr, request);
}
void MQClientAPIImpl::consumerSendMessageBack(const string addr,
MQMessageExt& msg,
const string& consumerGroup,
int delayLevel,
int timeoutMillis,
int maxReconsumeTimes,
const SessionCredentials& sessionCredentials) {
ConsumerSendMsgBackRequestHeader* pRequestHeader = new ConsumerSendMsgBackRequestHeader();
pRequestHeader->group = consumerGroup;
pRequestHeader->offset = msg.getCommitLogOffset();
pRequestHeader->delayLevel = delayLevel;
pRequestHeader->unitMode = false;
pRequestHeader->originTopic = msg.getTopic();
pRequestHeader->originMsgId = msg.getMsgId();
pRequestHeader->maxReconsumeTimes = maxReconsumeTimes;
// string addr = socketAddress2IPPort(msg.getStoreHost());
RemotingCommand request(CONSUMER_SEND_MSG_BACK, pRequestHeader);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (response) {
switch (response->getCode()) {
case SUCCESS_VALUE: {
return;
}
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
}
void MQClientAPIImpl::lockBatchMQ(const string& addr,
LockBatchRequestBody* requestBody,
vector<MQMessageQueue>& mqs,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
RemotingCommand request(LOCK_BATCH_MQ, NULL);
string body;
requestBody->Encode(body);
request.SetBody(body.data(), body.length());
request.setMsgBody(body);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (pResponse != NULL) {
if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
switch (pResponse->getCode()) {
case SUCCESS_VALUE: {
const MemoryBlock* pbody = pResponse->GetBody();
if (pbody->getSize()) {
LockBatchResponseBody::Decode(pbody, mqs);
}
return;
} break;
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode());
}
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
}
void MQClientAPIImpl::unlockBatchMQ(const string& addr,
UnlockBatchRequestBody* requestBody,
int timeoutMillis,
const SessionCredentials& sessionCredentials) {
RemotingCommand request(UNLOCK_BATCH_MQ, NULL);
string body;
requestBody->Encode(body);
request.SetBody(body.data(), body.length());
request.setMsgBody(body);
callSignatureBeforeRequest(addr, request, sessionCredentials);
request.Encode();
unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
if (pResponse != NULL) {
switch (pResponse->getCode()) {
case SUCCESS_VALUE: {
return;
} break;
default:
break;
}
THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode());
}
THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
}
//<!************************************************************************
} // namespace rocketmq

View File

@@ -0,0 +1,233 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MQCLIENTAPIIMPL_H__
#define __MQCLIENTAPIIMPL_H__
#include "AsyncCallback.h"
#include "ClientRPCHook.h"
#include "ClientRemotingProcessor.h"
#include "CommandHeader.h"
#include "HeartbeatData.h"
#include "KVTable.h"
#include "LockBatchBody.h"
#include "MQClientException.h"
#include "MQMessageExt.h"
#include "MQProtos.h"
#include "SendResult.h"
#include "SocketUtil.h"
#include "TcpRemotingClient.h"
#include "TopAddressing.h"
#include "TopicConfig.h"
#include "TopicList.h"
#include "TopicRouteData.h"
#include "UtilAll.h"
#include "VirtualEnvUtil.h"
namespace rocketmq {
//<!wrap all API to net ;
//<!************************************************************************
class MQClientAPIImpl {
public:
MQClientAPIImpl(const string& mqClientId, bool enableSsl, const std::string& sslPropertyFile);
MQClientAPIImpl(const string& mqClientId,
ClientRemotingProcessor* clientRemotingProcessor,
int pullThreadNum,
uint64_t tcpConnectTimeout,
uint64_t tcpTransportTryLockTimeout,
string unitName,
bool enableSsl,
const std::string& sslPropertyFile);
virtual ~MQClientAPIImpl();
virtual void stopAllTcpTransportThread();
virtual bool writeDataToFile(string filename, string data, bool isSync);
virtual string fetchNameServerAddr(const string& NSDomain);
virtual void updateNameServerAddr(const string& addrs);
virtual void callSignatureBeforeRequest(const string& addr,
RemotingCommand& request,
const SessionCredentials& session_credentials);
virtual void createTopic(const string& addr,
const string& defaultTopic,
TopicConfig topicConfig,
const SessionCredentials& sessionCredentials);
virtual void endTransactionOneway(std::string addr,
EndTransactionRequestHeader* requestHeader,
std::string remark,
const SessionCredentials& sessionCredentials);
virtual SendResult sendMessage(const string& addr,
const string& brokerName,
const MQMessage& msg,
SendMessageRequestHeader* pRequestHeader,
int timeoutMillis,
int maxRetrySendTimes,
int communicationMode,
SendCallback* pSendCallback,
const SessionCredentials& sessionCredentials);
virtual PullResult* pullMessage(const string& addr,
PullMessageRequestHeader* pRequestHeader,
int timeoutMillis,
int communicationMode,
PullCallback* pullCallback,
void* pArg,
const SessionCredentials& sessionCredentials);
virtual void sendHeartbeat(const string& addr,
HeartbeatData* pHeartbeatData,
const SessionCredentials& sessionCredentials);
virtual void unregisterClient(const string& addr,
const string& clientID,
const string& producerGroup,
const string& consumerGroup,
const SessionCredentials& sessionCredentials);
virtual TopicRouteData* getTopicRouteInfoFromNameServer(const string& topic,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual TopicList* getTopicListFromNameServer(const SessionCredentials& sessionCredentials);
virtual int wipeWritePermOfBroker(const string& namesrvAddr, const string& brokerName, int timeoutMillis);
virtual void deleteTopicInBroker(const string& addr, const string& topic, int timeoutMillis);
virtual void deleteTopicInNameServer(const string& addr, const string& topic, int timeoutMillis);
virtual void deleteSubscriptionGroup(const string& addr, const string& groupName, int timeoutMillis);
virtual string getKVConfigByValue(const string& projectNamespace, const string& projectGroup, int timeoutMillis);
virtual KVTable getKVListByNamespace(const string& projectNamespace, int timeoutMillis);
virtual void deleteKVConfigByValue(const string& projectNamespace, const string& projectGroup, int timeoutMillis);
virtual SendResult processSendResponse(const string& brokerName, const MQMessage& msg, RemotingCommand* pResponse);
virtual PullResult* processPullResponse(RemotingCommand* pResponse);
virtual int64 getMinOffset(const string& addr,
const string& topic,
int queueId,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual int64 getMaxOffset(const string& addr,
const string& topic,
int queueId,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual int64 searchOffset(const string& addr,
const string& topic,
int queueId,
uint64_t timestamp,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual MQMessageExt* viewMessage(const string& addr,
int64 phyoffset,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual int64 getEarliestMsgStoretime(const string& addr,
const string& topic,
int queueId,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual void getConsumerIdListByGroup(const string& addr,
const string& consumerGroup,
vector<string>& cids,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual int64 queryConsumerOffset(const string& addr,
QueryConsumerOffsetRequestHeader* pRequestHeader,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual void updateConsumerOffset(const string& addr,
UpdateConsumerOffsetRequestHeader* pRequestHeader,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual void updateConsumerOffsetOneway(const string& addr,
UpdateConsumerOffsetRequestHeader* pRequestHeader,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual void consumerSendMessageBack(const string addr,
MQMessageExt& msg,
const string& consumerGroup,
int delayLevel,
int timeoutMillis,
int maxReconsumeTimes,
const SessionCredentials& sessionCredentials);
virtual void lockBatchMQ(const string& addr,
LockBatchRequestBody* requestBody,
vector<MQMessageQueue>& mqs,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual void unlockBatchMQ(const string& addr,
UnlockBatchRequestBody* requestBody,
int timeoutMillis,
const SessionCredentials& sessionCredentials);
virtual void sendMessageAsync(const string& addr,
const string& brokerName,
const MQMessage& msg,
RemotingCommand& request,
SendCallback* pSendCallback,
int64 timeoutMilliseconds,
int maxRetryTimes = 1,
int retrySendTimes = 1);
private:
SendResult sendMessageSync(const string& addr,
const string& brokerName,
const MQMessage& msg,
RemotingCommand& request,
int timeoutMillis);
/*
void sendMessageAsync(const string& addr, const string& brokerName,
const MQMessage& msg, RemotingCommand& request,
SendCallback* pSendCallback, int64 timeoutMilliseconds);
*/
PullResult* pullMessageSync(const string& addr, RemotingCommand& request, int timeoutMillis);
void pullMessageAsync(const string& addr,
RemotingCommand& request,
int timeoutMillis,
PullCallback* pullCallback,
void* pArg);
protected:
unique_ptr<TcpRemotingClient> m_pRemotingClient;
private:
unique_ptr<TopAddressing> m_topAddressing;
string m_nameSrvAddr;
bool m_firstFetchNameSrv;
string m_mqClientId;
};
} // namespace rocketmq
//<!***************************************************************************
#endif

Some files were not shown because too many files have changed in this diff Show More