Merge pull request #13 from ShannonDing/licence

Add license in the head of files and add Notice
diff --git a/doc/api-doc/consumer-push.md b/doc/api-doc/consumer-push.md
new file mode 100644
index 0000000..a783e47
--- /dev/null
+++ b/doc/api-doc/consumer-push.md
@@ -0,0 +1,80 @@
+----------
+## Api docs
+
+### 1. Push Consumer
+* consumer = CreatePushConsumer(consumerGroup) <br />
+  - function description<br />
+    create a push consumer instance, by setting consumer group<br />
+
+  - input <br />
+    consumerGroup: consumer group<br />
+    
+  - return<br />
+    consumer: consumer instance
+
+* SetPushConsumerNameServerAddress(consumer, namesrv) <br />
+  - function description<br />
+    set name srv address for the consumer instance<br />
+
+  - input <br />
+    consumer: consumer intance<br />
+    namesrv: name srv address. like : 127.0.0.1:9876
+
+  - return : no<br />
+
+* Subscribe(consumer, topic, tag) <br />
+  - function description<br />
+    make consumer subscribe the topic and tag <br />
+
+  - input <br />
+    consumer: consumer intance<br />
+    topic: topic name
+    tag: topic tag
+
+* RegisterMessageCallback(consumer, pyCallBack) <br />
+  - function description<br />
+    set callback for push consumer instance <br />
+
+  - input <br />
+    consumer: consumer intance<br />
+    pyCallBack: py callback method. when message pulled, they would be send to a pyCallback method
+
+* SetPushConsumerThreadCount(consumer, threadCount)
+  - function description<br />
+    set push consumer thread count<br />
+
+  - input <br />
+    consumer: consumer intance<br />
+    threadCount: thread count
+
+* SetPushConsumerMessageBatchMaxSize(consumer, batchSize)
+  - function description<br />
+    set message count for one push<br />
+
+  - input <br />
+    consumer: consumer intance<br />
+    batchSize: message count 
+
+* SetPushConsumerInstanceName(consumer, instanceName)
+  - function description<br />
+    set consumer instance name<br />
+
+  - input <br />
+    consumer: consumer intance<br />
+    instanceName: consumer instance name
+
+* SetPushConsumerSessionCredentials(consumer, accessKey, secretKey,channel)
+  - function description<br />
+    set consumer access keys<br />
+
+  - input <br />
+    consumer: consumer intance<br />
+    accessKey: accessKey<br />
+    secretKey: secretKey<br />
+    channel: channel<br />
+    
+
+
+
+
+
diff --git a/doc/api-doc/message.md b/doc/api-doc/message.md
new file mode 100644
index 0000000..b727a6d
--- /dev/null
+++ b/doc/api-doc/message.md
@@ -0,0 +1,135 @@
+----------
+## Api docs
+
+### 1. Message
+* message = CreateMessage("topicName") <br />
+  - function description<br />
+    create a message instance, by setting topic field<br />
+
+  - input <br />
+    topicName: a topic name<br />
+
+  - return<br />
+    a new message instance, after used it, you need call DestroyMessage(message)<br />
+
+* DestroyMessage(message) <br />
+  - function description<br />
+    destroy a message instance, delete memmory<br />
+
+  - input <br />
+    message: message instance<br />
+
+* SetMessageTopic(message, topic) <br />
+  - function description<br />
+    set topic field value for the message<br />
+
+  - input <br />
+    message: message instance<br />
+    topic: a topic name
+
+* SetMessageTags(message, tags) <br />
+  - function description<br />
+    set tag field value for the message<br />
+
+  - input <br />
+    message: message instance<br />
+    tags: tag for the topic
+
+* SetMessageKeys(message, keys) <br />
+  - function description<br />
+    set key field value for the message<br />
+
+  - input <br />
+    message: message instance<br />
+    keys: key for the topic
+
+* SetMessageBody(message, stringBody) <br />
+  - function description<br />
+    set body for the message<br />
+
+  - input <br />
+    message: message instance<br />
+    body: message body as string
+
+* SetByteMessageBody(message, byteBody, byteLength) <br />
+  - function description<br />
+    set body for the message<br />
+
+  - input <br />
+    message: message instance<br />
+    byteBody: message body as byte[]
+    byteLength: byteBody's length
+
+* SetMessageProperty(message, key, value) <br />
+  - function description<br />
+    set extend k-v for message<br />
+
+  - input <br />
+    message: message instance<br />
+    key: string key
+    value: string value
+
+* SetMessageDelayTimeLevel(message, level) <br />
+  - function description<br />
+    set delay level<br />
+
+  - input <br />
+    message: message instance<br />
+    level: delay level as int
+
+
+### 2. MessageExt
+* topic = GetMessageTopic(msgExt) <br />
+  - function description<br />
+    get topic name from a message instance<br />
+
+  - input <br />
+    msgExt: message instance<br />
+  - return<br />
+    topic: topic name
+
+* tag = GetMessageTags(msgExt) <br />
+  - function description<br />
+    get tag from a message instance<br />
+
+  - input <br />
+    msgExt: message instance<br />
+  - return<br />
+    tag: tag
+
+* key = GetMessageKeys(msgExt) <br />
+  - function description<br />
+    get message key from a message instance<br />
+
+  - input <br />
+    msgExt: message instance<br />
+  - return<br />
+    key: message key
+
+* body = GetMessageBody(msgExt) <br />
+  - function description<br />
+    get message body from a message instance<br />
+
+  - input <br />
+    msgExt: message instance<br />
+  - return<br />
+    body: message body as string
+
+* value = GetMessageProperty(msgExt, key) <br />
+  - function description<br />
+    get a message proprty value from a message instance<br />
+
+  - input <br />
+    msgExt: message instance<br />
+    key: property key
+  - return<br />
+    value: property value as string
+
+* messageId = GetMessageId(msgExt) <br />
+  - function description<br />
+    get a message id from a message instance<br />
+
+  - input <br />
+    msgExt: message instance<br />
+  - return<br />
+    messageId: message id as string
\ No newline at end of file
diff --git a/doc/api-doc/producer.md b/doc/api-doc/producer.md
new file mode 100644
index 0000000..6af4c99
--- /dev/null
+++ b/doc/api-doc/producer.md
@@ -0,0 +1,94 @@
+----------
+## Api docs
+
+### Producer
+* producer = CreateProducer("producerName") <br />
+  - function description<br />
+    create a producer instance<br />
+
+  - input <br />
+    producerName: producer group name<br />
+
+  - return<br />
+    a new producer instance, can send messages<br />
+
+* SetProducerNameServerAddress(producer, "namesrv address")
+  - function description<br />
+    set namesrv address for the producer instance<br />
+
+  - input<br />
+    producer : a producer instance <br />
+
+    namesrv address : like 127.0.0.1:9876<br />
+  - return : no <br />
+* SetProducerInstanceName(producer, "instance name")
+  - function description<br />
+    set instance name for the producer
+
+  - input<br />
+    producer : a producer instance <br />
+    intance name : a producer instance name<br />
+  - return : no <br />
+    
+* SetProducerSessionCredentials(producer, accessKey, secretKey, channel)
+  - function description<br />
+    set access keys for accessing broker in the session
+
+  - input<br />
+    producer : a producer instance <br />
+    accessKey : accessKey<br />
+    secretKey : secretKey<br />
+    channel : channel<br />
+  - return : no <br />
+
+* StartProducer(producer)
+  - function description<br />
+    start the producer instance
+
+  - input<br />
+    producer : a producer instance <br />
+   
+  - return : no <br />
+
+* ShutdownProducer(producer)
+  - function description<br />
+    shutdown the producer instance
+
+  - input<br />
+    producer : a producer instance <br />
+   
+  - return : no <br />
+
+* DestroyProducer(producer)
+  - function description<br />
+    destroy the producer instance
+
+  - input<br />
+    producer : a producer instance <br />
+   
+  - return : no <br />
+
+* PySendResult result = SendMessageSync(producer, msg)
+  - function description<br />
+    send a message sync
+
+  - input<br />
+    producer : a producer instance <br />
+    msg : a message instance <br />
+    
+  - return<br />
+    result.GetMsgId(): if send successfuly, it is the message id<br />
+    result.offset : message offset in broker<br />
+    result.sendStatus<br />
+      SEND_OK: <br />
+      SEND_FLUSH_DISK_TIMEOUT,<br />
+      SEND_FLUSH_SLAVE_TIMEOUT,<br />
+      SEND_SLAVE_NOT_AVAILABLE<br />
+
+* SendMessageOneway(producer, msg)
+  - function description<br />
+    send a message one way, no matter about the result
+
+  - input<br />
+    producer : a producer instance <br />
+    msg : a message instance <br />
\ No newline at end of file
diff --git a/sample/testProducer.py b/sample/testProducer.py
index 558eb6b..6938fd2 100644
--- a/sample/testProducer.py
+++ b/sample/testProducer.py
@@ -42,6 +42,16 @@
     DestroyMessage(msg)
     print("Done...............")
 
+def testSendMessageOneway(producer, topic, key, body):
+    print("Starting Sending(Oneway).....")
+    msg = CreateMessage(topic)
+    SetMessageBody(msg, body)
+    SetMessageKeys(msg, key)
+    SetMessageTags(msg, "Send Message Oneway Test.")
+    SendMessageOneway(producer,msg)
+    DestroyMessage(msg)
+    print("Done...............")
+
 def releaseProducer(producer):
     ShutdownProducer(producer)
     DestroyProducer(producer)
@@ -59,4 +69,9 @@
     
     print("Now Send Message:",i)
 
+while i < 10:
+    i += 1
+    testSendMessageOneway(producer, topic, key, body)
+    print("Now Send Message One way:",i)
+
 releaseProducer(producer)
diff --git a/src/PythonWrapper.cpp b/src/PythonWrapper.cpp
index b6c04b6..75b5167 100644
--- a/src/PythonWrapper.cpp
+++ b/src/PythonWrapper.cpp
@@ -133,6 +133,10 @@
     return ret;
 }
 
+int PySendMessageOneway(void *producer, void *msg) {
+    return SendMessageOneway((CProducer *) producer, (CMessage *) msg);
+}
+
 //SendResult
 const char *PyGetSendResultMsgID(CSendResult &sendResult) {
     return (const char *) (sendResult.msgId);
@@ -263,6 +267,7 @@
     def("SetProducerInstanceName", PySetProducerInstanceName);
     def("SetProducerSessionCredentials", PySetProducerSessionCredentials);
     def("SendMessageSync", PySendMessageSync);
+    def("SendMessageOneway", PySendMessageOneway);
 
     //For Consumer
     def("CreatePushConsumer", PyCreatePushConsumer, return_value_policy<return_opaque_pointer>());
diff --git a/src/PythonWrapper.h b/src/PythonWrapper.h
index 887e6f7..04b3164 100644
--- a/src/PythonWrapper.h
+++ b/src/PythonWrapper.h
@@ -74,6 +74,7 @@
 int PySetProducerInstanceName(void *producer, const char *instanceName);
 int PySetProducerSessionCredentials(void *producer, const char *accessKey, const char *secretKey, const char *channel);
 PySendResult PySendMessageSync(void *producer, void *msg);
+int PySendMessageOneway(void *producer, void *msg);
 
 //sendResult
 const char *PyGetSendResultMsgID(CSendResult &sendResult);
diff --git a/test/TestConsumeMessages.py b/test/TestConsumeMessages.py
new file mode 100644
index 0000000..6b9f6d2
--- /dev/null
+++ b/test/TestConsumeMessages.py
@@ -0,0 +1,78 @@
+# /*
+# * 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.
+# */
+
+import __init__
+from librocketmqclientpython import *
+
+import time
+import sys
+
+topic = 'test'
+name_srv = '127.0.0.1:9876'
+tag = 'rmq-tag'
+consumer_group = 'test-consumer-group'
+totalMsg = 0
+
+
+def sigint_handler(signum, frame):
+    global is_sigint_up
+    is_sigint_up = True
+    sys.exit(0)
+
+
+def consumer_message(msg):
+    global totalMsg
+    totalMsg += 1
+    print 'total count %d' % totalMsg
+    print 'topic=%s' % GetMessageTopic(msg)
+    print 'tag=%s' % GetMessageTags(msg)
+    print 'body=%s' % GetMessageBody(msg)
+    print 'msg id=%s' % GetMessageId(msg)
+
+    print 'map.keys %s' % GetMessageKeys(msg)
+
+    print 'map.name %s' % GetMessageProperty(msg, 'name')
+    print 'map.id %s' % GetMessageProperty(msg, 'id')
+    return 0
+
+
+def init_producer(_group, _topic, _tag):
+    consumer = CreatePushConsumer(_group)
+    SetPushConsumerNameServerAddress(consumer, name_srv)
+    SetPushConsumerThreadCount(consumer, 1)
+    Subscribe(consumer, _topic, _tag)
+    RegisterMessageCallback(consumer, consumerMessage)
+    StartPushConsumer(consumer)
+    print 'consumer is ready...'
+    return consumer
+
+
+def start_one_consumer(_group, _topic, _tag):
+    consumer = init_producer(_group, _topic, _tag)
+    i = 1
+    while i <= 10:
+        print 'clock: ' + str(i)
+        i += 1
+        time.sleep(10)
+
+    ShutdownPushConsumer(consumer)
+    DestroyPushConsumer(consumer)
+    print("Consumer Down....")
+
+
+if __name__ == '__main__':
+    start_one_consumer(consumer_group, topic, '*')
diff --git a/test/TestSendMessages.py b/test/TestSendMessages.py
new file mode 100644
index 0000000..69871a2
--- /dev/null
+++ b/test/TestSendMessages.py
@@ -0,0 +1,206 @@
+# /*
+# * 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.
+# */
+
+import __init__
+from librocketmqclientpython import *
+import time
+
+topic = 'test'
+name_srv = '127.0.0.1:9876'
+
+
+def init_producer():
+    producer = CreateProducer('TestProducer')
+    SetProducerNameServerAddress(producer, name_srv)
+    StartProducer(producer)
+    return producer
+
+
+producer = init_producer()
+tag = 'rmq-tag'
+key = 'rmq-key'
+
+
+def send_messages_sync(count):
+    for a in range(count):
+        print 'start sending...'
+        body = 'hi rmq, now is ' + \
+            time.strftime('%Y.%m.%d', time.localtime(time.time()))
+        msg = CreateMessage(topic)
+        SetMessageBody(msg, body)
+        result = SendMessageSync(producer, msg)
+        DestroyMessage(msg)
+        print '[RMQ-PRODUCER]start sending...done, msg id = ' + \
+            result.GetMsgId()
+
+
+def send_messages_sync_with_map(count):
+    print 'sending message with properties...id, name'
+    for a in range(count):
+        body = 'hi rmq, now is ' + \
+            time.strftime('%Y.%m.%d', time.localtime(time.time()))
+        msg = CreateMessage(topic)
+        SetMessageBody(msg, body)
+
+        SetMessageProperty(msg, 'name', 'test')
+        SetMessageProperty(msg, 'id', str(time.time()))
+
+        result = SendMessageSync(producer, msg)
+        DestroyMessage(msg)
+        print '[RMQ-PRODUCER]start sending...done, msg id = ' + \
+            result.GetMsgId()
+
+
+def send_messages_with_tag_sync(count):
+    print 'sending message with tag...' + tag
+    for a in range(count):
+        body = 'hi rmq, now is ' + \
+            time.strftime('%Y.%m.%d', time.localtime(time.time()))
+        msg = CreateMessage(topic)
+        SetMessageBody(msg, body)
+        SetMessageTags(msg, tag)
+        result = SendMessageSync(producer, msg)
+        DestroyMessage(msg)
+        print 'msg id = ' + result.GetMsgId()
+
+
+def send_messages_with_tag_and_map_sync(count):
+    print 'sending message with tag...' + tag + ' and properties id, name'
+    for a in range(count):
+        body = 'hi rmq, now is ' + \
+            time.strftime('%Y.%m.%d', time.localtime(time.time()))
+        msg = CreateMessage(topic)
+        SetMessageBody(msg, body)
+
+        SetMessageProperty(msg, 'name', 'test')
+        SetMessageProperty(msg, 'id', str(time.time()))
+
+        SetMessageTags(msg, tag)
+        result = SendMessageSync(producer, msg)
+        DestroyMessage(msg)
+        print 'msg id = ' + result.GetMsgId()
+
+
+def send_messages_with_key_sync(count):
+    print 'sending message with keys...' + key
+    for a in range(count):
+        body = 'hi rmq, now is ' + \
+            time.strftime('%Y.%m.%d', time.localtime(time.time()))
+        msg = CreateMessage(topic)
+        SetMessageBody(msg, body)
+        SetMessageKeys(msg, key)
+        result = SendMessageSync(producer, msg)
+        DestroyMessage(msg)
+        print 'msg id = ' + result.GetMsgId()
+
+
+def send_messages_with_key_and_map_sync(count):
+    print 'sending message with keys...' + key + ' and properties id, name'
+    for a in range(count):
+        body = 'hi rmq, now is ' + \
+            time.strftime('%Y.%m.%d', time.localtime(time.time()))
+        msg = CreateMessage(topic)
+        SetMessageBody(msg, body)
+        SetMessageKeys(msg, key)
+
+        SetMessageProperty(msg, 'name', 'test')
+        SetMessageProperty(msg, 'id', str(time.time()))
+
+        result = SendMessageSync(producer, msg)
+        DestroyMessage(msg)
+        print 'msg id = ' + result.GetMsgId()
+
+
+def send_messages_with_key_and_tag_sync(count):
+    key = 'rmq-key'
+    print 'sending message with keys and tag...' + key + ', ' + tag
+    for a in range(count):
+        body = 'hi rmq, now is ' + \
+            time.strftime('%Y.%m.%d', time.localtime(time.time()))
+        msg = CreateMessage(topic)
+        SetMessageBody(msg, body)
+        SetMessageKeys(msg, key)
+        SetMessageTags(msg, tag)
+        result = SendMessageSync(producer, msg)
+        DestroyMessage(msg)
+        print 'msg id = ' + result.GetMsgId()
+
+
+def send_messages_with_key_and_tag_and_map_sync(count):
+    key = 'rmq-key'
+    print 'sending message with keys and tag...' + \
+        key + ', ' + tag + ' and properties id, name'
+    for a in range(count):
+        body = 'hi rmq, now is ' + \
+            time.strftime('%Y.%m.%d', time.localtime(time.time()))
+        msg = CreateMessage(topic)
+        SetMessageBody(msg, body)
+        SetMessageKeys(msg, key)
+
+        SetMessageProperty(msg, 'name', 'test')
+        SetMessageProperty(msg, 'id', str(time.time()))
+
+        SetMessageTags(msg, tag)
+        result = SendMessageSync(producer, msg)
+        DestroyMessage(msg)
+        print 'msg id = ' + result.GetMsgId()
+
+
+def send_messages_oneway(count):
+    for a in range(count):
+        print 'start sending...'
+        body = 'hi rmq, this is oneway message. now is ' + \
+            time.strftime('%Y.%m.%d', time.localtime(time.time()))
+        msg = CreateMessage(topic)
+        SetMessageBody(msg, body)
+
+        SetMessageKeys(msg, key)
+        SetMessageProperty(msg, 'name', 'test')
+        SetMessageProperty(msg, 'id', str(time.time()))
+
+        SendMessageOneway(producer, msg)
+        DestroyMessage(msg)
+        print 'send oneway is over'
+
+
+def send_delay_messages(producer, topic, count):
+    key = 'rmq-key'
+    print 'start sending message'
+    tag = 'test'
+    for n in range(count):
+        body = 'hi rmq, now is' + str(time.time())
+        msg = CreateMessage(topic)
+        SetMessageBody(msg, body)
+        SetMessageKeys(msg, key)
+        SetMessageProperty(msg, 'name', 'hello world')
+        SetMessageProperty(msg, 'id', str(time.time()))
+        SetMessageTags(msg, tag)
+        # messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
+
+        SetDelayTimeLevel(msg, 5)
+
+        print str(msg)
+        result = SendMessageSync(producer, msg)
+        DestroyMessage(msg)
+        print 'msg id =' + result.GetMsgId()
+
+
+if __name__ == '__main__':
+    # print GetVersion()
+    while True:
+        send_messages_oneway(1)
+        time.sleep(1)
diff --git a/test/__init__.py b/test/__init__.py
new file mode 100644
index 0000000..f3a3a82
--- /dev/null
+++ b/test/__init__.py
@@ -0,0 +1,22 @@
+# /*
+# * 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.
+# */
+
+import sys
+sys.path.append('/usr/local/lib')
+print("__________Python Version:___________")
+print(sys.version)
+print("______Add Path /usr/local/lib_______")
diff --git a/third_party/googletest/Readme.md b/third_party/googletest/Readme.md
index e713348..39da329 100644
--- a/third_party/googletest/Readme.md
+++ b/third_party/googletest/Readme.md
@@ -1,4 +1,4 @@
 ### Google Test 
 
 -----------------------
-Download [Here](!https://github.com/abseil/googletest)
+Download [googletest source](https://github.com/abseil/googletest)