What does redis.publish(); method do in the following module.
redis.publish("WordCountTopology", exclamatedWord.toString() + "|" + Long.toString(count));
public void execute(Tuple tuple)
{
String word = tuple.getString(0);
StringBuilder exclamatedWord = new StringBuilder();
exclamatedWord.append(word).append("!!!");
_collector.emit(tuple, new Values(exclamatedWord.toString()));
long count = 30;
redis.publish("WordCountTopology", exclamatedWord.toString() + "|" + Long.toString(count));
}
It publishes the string (ExclamatedWord + "|30") to a Redis channel called WordCountTopology - subscribers to that channel will get the message once redis.publish executes.
For more information about Redis' Pub/Sub see: http://redis.io/topics/pubsub
Related
I am using #RabbitListner annotation to recieve messages from a RabbitMq queue.
How to make threads receive messages no more often than 1 second?
#RabbitListener(queues = "message", priority = "3",concurrency = "2")
public void receiveCheck(RequestMessage message){
}
Your task is a bit strange. Don't you think that the problem should be solved differently (maybe you can send messages with a certain frequency - 1 message/sec)?
But if you're sure that's what you need, you could use primitive solution:
#RabbitListener(queues = "message", priority = "3", concurrency = "2")
public void receiveMessage(String message) throws InterruptedException {
System.out.println("Received <" + message + ">" + " Message time: " + LocalDateTime.now());
Thread.sleep(1000);
}
Or with the calculation of the operation time:
#RabbitListener(queues = "message", priority = "3", concurrency = "2")
public void receiveMessageWithTimer(String message) throws InterruptedException {
long start = System.currentTimeMillis();
System.out.println("Received <" + message + ">" + " Message time: " + LocalDateTime.now());
long finish = System.currentTimeMillis();
long operationTime = finish - start;
Thread.sleep(1000 - operationTime);
}
But in this case you should remeber that concurrency level = 2. And you will receive 2 message/sec.
For receiving of only one message you could set concurrency level = 1.
In my application ,i am consuming json messages from kafka topic and Multiple instances are running of my application. I have set kafka prop as: props.put("enable.auto.commit", "false")
So When i consume message ,i push it to my DB and then commit it as :
private static void commitMessage(KafkaConsumer<String, String> kafkaConsumer, ConsumerRecord message, String kafkaTopic) {
long nextOffset = message.offset() + 1;
TopicPartition topicPartition = new TopicPartition(kafkaTopic, message.partition());
OffsetAndMetadata offsetAndMetadata = new OffsetAndMetadata(nextOffset);
Map<TopicPartition, OffsetAndMetadata> offsetAndMetadataMap = new HashMap<>();
offsetAndMetadataMap.put(topicPartition, offsetAndMetadata);
//
log.info("Commiting processed kafka message, topic [" + kafkaTopic + "], partition [" + message.partition() + "], next offset [" + nextOffset + "]");
kafkaConsumer.commitSync(offsetAndMetadataMap);
}
Now it may happen after consuming message(but before pushing it to DB) my Application restarts for some reason. Now i want to consume uncommitted message again from kafka after restart. I am able to do using seek:
private static void seekAllPartitions(KafkaConsumer<String, String> kafkaConsumer, String kafkaTopic) {
List<PartitionInfo> partitionInfos = kafkaConsumer.partitionsFor(kafkaTopic);
println 'Size ofpartition list : ' + partitionInfos.size()
for (PartitionInfo partitionInfo : partitionInfos) {
TopicPartition topicPartition = new TopicPartition(kafkaTopic, partitionInfo.partition());
OffsetAndMetadata committedForPartition = kafkaConsumer.committed(topicPartition);
try {
if (committedForPartition != null) {
println 'Seeking offset...' + committedForPartition.offset()
kafkaConsumer.seek(topicPartition, committedForPartition.offset());
}
} catch (Exception ex) {}
}
}
Now problem is - seek(topicPartition,committedForPartition.offset()) gives me last uncommitted message and not the intermediate uncommitted messages.As i mentioned ,multiple instance are running - i may end up with intermediate uncommitted messages for ex : Instance a -2nd msg was not committed and Instance b - 5 the msg not committed but it gives me 5th message only and not 2nd.
I'm having an issue where I can't send SMS more than 255 words. I did my research a bit on how to concatenate the messages but I still can't get it to work. Can somebody advise me on this? Below is my code:
private int SMSMt(String pstrLoginName, String pstrServiceID, String
pstrCPID, String pstrMSISDN, String pstrKeyword, String pstrPriceCode,
String pstrChargeMSISDN, String pstrSubID, String pstrDstTrxID, String
pstrShortCode, String pstrSMS, String pstrLanguage, SubmitResult pobjRst)
{
int intResult = 0;
try
{
if (!this.mobjSMPP.mblnBound)
{
intResult = 9910;
}
else
{
SubmitSM objReq = new SubmitSM();
Address objSrcAddress = new Address();
Address objDstAddress = new Address();
objSrcAddress.setNpi((byte)1);
objSrcAddress.setTon((byte)0);
objSrcAddress.setAddress(pstrShortCode);
objDstAddress.setNpi((byte)1);
objDstAddress.setTon((byte)0);
objDstAddress.setAddress(pstrMSISDN);
objReq.setServiceType("");
objReq.setSourceAddr(objSrcAddress);
objReq.setDestAddr(objDstAddress);
objReq.setReplaceIfPresentFlag((byte)0);
objReq.setScheduleDeliveryTime("");
objReq.setValidityPeriod("");
objReq.setPriorityFlag((byte)1);
objReq.setRegisteredDelivery((byte)1);
objReq.setUserMessageReference((short)25);
WriteLog("pstrLanguage=" + pstrLanguage);
if (pstrLanguage.equals("1")) {
objReq.setDataCoding((byte)8);
WriteLog("Ori pstrSMS=" + pstrSMS);
objReq.setShortMessage(pstrSMS,"UTF_16BE");
//String HexStr = new String("A" + "\u00ea" + "\u00f1" + "\u00fc" + "\u0eaa" + "C");
//WriteLog("HexStr=" + HexStr);
//pstrSMS = stringToHex(pstrSMS);
//StringConverter TestRun = new StringConverter(pstrSMS);
/*pstrSMS = HexStr;*/
//pstrSMS = new String("\u0eaa");
//pstrSMS = new String("0x0eaa");
/*pstrSMS = "世界您好";
WriteLog("Ori pstrSMS=" + pstrSMS);
//byte[] messageData = new ASCIIEncoding().encode(pstrSMS);
byte[] b = s.getBytes(StandardCharsets.US_ASCII);*/
WriteLog("Ori pstrSMS [unicode]=" + pstrSMS);
//byte[] textByte = pstrSMS.getBytes("UTF-16BE");
//WriteLog("HexCode [encoded with UTF-16BE]= " + textByte);
//pstrSMS = textByte.toString(); //cannot convert byte[] to string
}
else {
objReq.setDataCoding((byte)0);
objReq.setShortMessage(pstrSMS);
}
Setting user reference (setUserMessageReference) is not enough. You must set also number of fragments and fragment number. Depending on library methods.
Also, you must split message to 255 chunks on hand.
So if you have message 400 bytes, then you do something like this:
First fragment:
setReference=25
numberOfFragments=2
fragmentNumber=1
message=first 255 bytes
Second fragment:
setReference=25
numberOfFragments=2
fragmentNumber=2
message=rest 145 bytes
Also note, that many SMSC vendors allow SMPP to be fragmented internally.
There are 2 parameters in SMPP to deal with message:
1)Message(mandatory) (limited to 255 bytes)
2)Payload message(optional) (not limited)
Is there a way to write a PCF program to get channel status for Cluster Sender/Receiver channels which are in "Running" status?
I have something like this which gives me channel status of only one channel!
// send the request and collect the responses
String checkStatus="";
String channelName ="";
// build a request
request = new PCFMessage(CMQCFC.MQCMD_INQUIRE_CHANNEL_STATUS);
// add a parameter designating the name of the channel for which status is requested
request.addParameter(CMQCFC.MQCACH_CHANNEL_NAME, "TO.*");
// add a parameter designating the instance type (current) desired
request.addParameter(CMQCFC.MQIACH_CHANNEL_INSTANCE_TYPE, CMQC.MQOT_CURRENT_CHANNEL);
responses = agent.send(request);
for (int j = 0; j < responses.length; j++) {
// get the channel name and trim the spaces
String temp ="";
temp = responses[j].getStringParameterValue(CMQCFC.MQCACH_CHANNEL_NAME);
channelName = temp.trim();
int chlStatus = responses[j].getIntParameterValue(CMQCFC.MQIACH_CHANNEL_STATUS);
//System.out.println("channel status: " + chlStatus);
String[] chStatusText = {
"", "MQCHS_BINDING", "MQCHS_STARTING", "MQCHS_RUNNING",
"MQCHS_STOPPING", "MQCHS_RETRYING", "MQCHS_STOPPED",
"MQCHS_REQUESTING", "MQCHS_PAUSED",
"", "", "", "", "MQCHS_INITIALIZING"
};
checkStatus = chStatusText[chlStatus];
//System.out.println("channel status: " + checkStatus);
}
System.out.println("chl: " + channelName + " STATUS: " + checkStatus + ")");
The above code gives channel status for only one channel and not all the channels. What is wrong here?
The PCF part of your code looks fine, but the printing out of the result is the code in error.
responses = agent.send(request);
for (int j = 0; j < responses.length; j++) {
:
:
checkStatus = chStatusText[chlStatus];
}
System.out.println("chl: " + channelName + " STATUS: " + checkStatus + ")");
You have a for loop going round all the responses, but then the println is outside the for loop and thus is only printing out the result for the final response.
Go grab my open source project called MQ Channel Monitor. Download the source code and review the 'PCFChlStatus.java' file. There is a method called getMCAStatus() which is basically what you are after.
Having a very simple poc such as this one:
IndexedChronicle chronicle = getChronicle("basic");
ExcerptAppender appender = chronicle.createAppender();
appender.startExcerpt();
appender.writeObject(new MessageKey("type", 123L));
appender.finish();
ExcerptTailer tailer = chronicle.createTailer();
while(tailer.nextIndex()) {
MessageKey key = (MessageKey) tailer.readObject();
System.out.println("key " + key);
}
VanillaChronicle vcron = getVainllaChronicle("vanilla");
VanillaAppender app = vcron.createAppender();
app.startExcerpt();
app.writeObject(new MessageKey("type", 123L));
app.finish();
ExcerptTailer vtail = vcron.createTailer();
while(vtail.nextIndex()) {
MessageKey key = (MessageKey) vtail.readObject();
System.out.println("key " + key);
}
Gives me an IndexOutOfBoundsException in the writeObject method on the VanillaAppender.
However, there is little difference, and nothing exceptionally different in the docs
Can anyone suggest how it should be used?
Update:
I re-arranged the code so it became identical to peters (copied it in, actually), but I still get this exception:
Exception in thread "main" java.lang.IndexOutOfBoundsException: position is beyond the end of the buffer 372 > -190495716
at net.openhft.lang.io.NativeBytes.checkEndOfBuffer(NativeBytes.java:518)
at net.openhft.lang.io.AbstractBytes.writeObject(AbstractBytes.java:1897)
at main.ChronicleTest.main(ChronicleTest.java:31)
The version imported is 3.2.1
<dependency>
<groupId>net.openhft</groupId>
<artifactId>chronicle</artifactId>
<version>3.2.1</version>
</dependency>
When I try this with Chronicle 3.2.1
public class SO25623856Main {
public static void main(String[] args) throws IOException {
Chronicle vcron = new VanillaChronicle("vanilla");
ExcerptAppender app = vcron.createAppender();
app.startExcerpt();
app.writeObject(new MessageKey("type", 123L));
app.finish();
ExcerptTailer vtail = vcron.createTailer();
while (vtail.nextIndex()) {
MessageKey key = (MessageKey) vtail.readObject();
System.out.println("key " + key);
}
vcron.close();
}
}
class MessageKey implements Serializable {
private String type;
private long l;
public MessageKey(String type, long l) {
this.type = type;
this.l = l;
}
#Override
public String toString() {
return "MessageKey{" +
"type='" + type + '\'' +
", l=" + l +
'}';
}
}
it prints
key MessageKey{type='type', l=123}
BTW I suggest you use Externalizable or ByteMarshallable for improved performance and smaller messages.