Failure of a single number duing bulk SMS sending - sms

I am sending SMS to my clients via my application. Suppose if am sending a message to 100 mobile numbers, one of it happens to be a non existing mob number. How can I skip that number alone and send rest of them? I use a try catch block in the method when the message can't be delivered, it goes to catch and the rest of the numbers can't be sent. Any ideas how this can be done?

Sounds like you are using something like this:
try {
foreach(string number in numbers) {
// send sms here
}
}
catch()
{
// do error handling here
}
Do it like this:
foreach(string number in numbers) {
try {
// send sms here
}
catch() {
// do error handling here
}
}

You need to do a "look up" on the number, usually the Aggregator you use will have this service

Check the mobile number before sending the message and if it is a mobile number youu just send.

Related

Masstransit How to disconnect from from RabbitMq

I am using Masstransit with RabbitMQ. As part of some deployment procedure, At some point in time I need my service to disconnect and stop receiving any messages.
Assuming that I won't need the bus until the next restart of the service, will it be Ok to use bus.StopAsync()?
Is there a way to get list of end points and then remove them from listining ?
You should StopAsync the bus, and then when ready, call StartAsync to bring it back up (or start it at the next service restart).
To stop receiving messages without stopping the buss I needed a solution that will avoid the consume message pipeline from consuming any type of message. I tried with observers but unsuccessfully. My solution came up with custom consuming message filter.
The filter part looks like this
public class ComsumersBlockingFilter<T> :
IFilter<ConsumeContext<T>>
where T : class
{
public void Probe(ProbeContext context)
{
var scope = context.CreateFilterScope("messageFilter");
}
public async Task Send(ConsumeContext<T> context, IPipe<ConsumeContext<T>> next)
{
// Check if the service is degraded (true for this demo)
var isServiceDegraded = true;
if (isServiceDegraded)
{
//Suspend the message for 5 seconds
await Task.Delay(TimeSpan.FromMilliseconds(5000), context.CancellationToken);
if (!context.CancellationToken.IsCancellationRequested)
{
//republish the message
await context.Publish(context.Message);
Console.WriteLine($"Message {context.MessageId} has been republished");
}
// NotifyConsumed to avoid skipped message
await context.NotifyConsumed(TimeSpan.Zero, "messageFilter");
}
else
{
//Next filter in the pipe is called
await next.Send(context);
}
}
}
The main idea is to delay with cancellation token and the republish the message. After that call contect.NotifyConsumed to avoid the next pipeline filters and return normally.

How to tell RSocket to read data stream by Java 8 Stream which backed by Blocking queue

I have the following scenario whereby my program is using blocking queue to process message asynchronously. There are multiple RSocket clients who wish to receive this message. My design is such a way that when a message arrives in the blocking queue, the stream that binds to the Flux will emit. I have tried to implement this requirement as below, but the client doesn't receive any response. However, I could see Stream supplier getting triggered correctly.
Can someone pls help.
#MessageMapping("addListenerHook")
public Flux<QueryResult> addListenerHook(String clientName){
System.out.println("Adding Listener:"+clientName);
BlockingQueue<QueryResult> listenerQ = new LinkedBlockingQueue<>();
Datalistener.register(clientName,listenerQ);
return Flux.fromStream(
()-> Stream.generate(()->streamValue(listenerQ))).map(q->{
System.out.println("I got an event : "+q.getResult());
return q;
});
}
private QueryResult streamValue(BlockingQueue<QueryResult> inStream){
try{
return inStream.take();
}catch(Exception e){
return null;
}
}
This is tough to solve simply and cleanly because of the blocking API. I think this is why there aren't simple bridge APIs here to help you implement this. You should come up with a clean solution to turn the BlockingQueue into a Flux first. Then the spring-boot part becomes a non-event.
This is why the correct solution is probably involving a custom BlockingQueue implementation like ObservableQueue in https://www.nurkiewicz.com/2015/07/consuming-javautilconcurrentblockingque.html
A alternative approach is in How can I create reactor Flux from a blocking queue?
If you need to retain the LinkedBlockingQueue, a starting solution might be something like the following.
val f = flux<String> {
val listenerQ = LinkedBlockingQueue<QueryResult>()
Datalistener.register(clientName,listenerQ);
while (true) {
send(bq.take())
}
}.subscribeOn(Schedulers.elastic())
With an API like flux you should definitely avoid any side effects before the subscribe, so don't register your listener until inside the body of the method. But you will need to improve this example to handle cancellation, or however you cancel the listener and interrupt the thread doing the take.

GRPC: Client streaming with configuration message

Here's a proto definition for a service that consumes a stream of events
from a client
message Event {
// ...
}
service EventService {
rpc Publisher(stream Event) returns (google.protobuf.Empty);
}
The problem is that the server needs to be told what to do with this stream.
Ideally, it would first recieve an Options message:
message Event {
// ...
}
message Options {
// ...
}
service EventService {
rpc Publisher(Options, stream Event) returns (google.protobuf.Empty);
}
However, grpc only supports one parameter for rpc methods.
One solution is to introduce an additional PublishMessage message which
can contain either an Options or Event message.
message PublishMessage {
oneof content {
Options options = 1;
Event event = 2;
}
}
The service would then expect the first PublishMessage to contain an Options message, with all subsequent ones containing Event messages. This introduces additional overhead from the wrapping message and makes the api a little clunky.
Is there a cleaner way to achieve the same result?
Using oneof is the suggested approach when many fields or messages are in play. The overhead is minimal, so wouldn't generally be a concern. There is the clunkiness though.
If there's only a few fields, you may want to combine the fields from Options and Event into a single message. Or similarly add Options to Event as a field. You'd expect the Options fields to be present on the first request and missing from subsequent. This works better when there's fewer configuration fields, like just a "name."

How to make Camel's "Netty4" component output an endpoint's results, but NOT echo back all the input as well?

I am experimenting with using Apache Camel to implement a TCP game server. It will accept bi-directional, synchronous telnet or SSH connections from multiple human or bot players.
The communication "protocol" is a bit crude, and based on legacy infrastructure that's already in place from an earlier version. Basically, the client and server exchange I/O over a socket (one connection per client).
Usually, this consists of one-line command strings, or one-line response strings. However, in some cases the input or output can span multiple line breaks before it is considered "complete" and ready for the other side's response. So my plan is to:
Create a TCP socket server using Spring Boot and Apache Camel, with the latter's "Netty4" component.
Use aggregation to collect the incoming lines of text from a socket connection. Roll them up into messages of one or more lines, depending on the type of input detected.
Pass the resulting message to an endpoint, which parses the input and returns the appropriate response back to the socket.
I can show any other code or Spring config, but the heart of my question seems to be the route I'm declaring:
#Component
public class EchoRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
// "sync=true" seems necessary to return any response to the client at all
//
// "textline=true&autoAppendDelimiter=false" seem necessary to properly handle
// the socket input at newline-terminated strings, rather than processing
// input byte-by-byte
from("netty4:tcp://localhost:4321?sync=true&textline=true&autoAppendDelimiter=false")
// This line, and the corresponding `.header("incoming")` line below, are
// perhaps a bit dodgy. I'm assuming that all messages on the route
// from a given client socket are already effectively "correlated", and
// that messages from multiple client sockets are not inter-mingled
// here. So I'm basically wildcard-ing the correlation mechanism. If my
// assumption is wrong, then I'm not sure how to correlate by
// client socket.
.setHeader("incoming", constant(true))
// Taken from numerous examples I've seen in Camel books and website
// pages. Just concatenates the correlated messages until
// completion occurs.
.aggregate(new AggregationStrategy() {
#Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
if (oldExchange == null) {
return newExchange;
}
final String oldBody = oldExchange.getIn().getBody(String.class);
final String newBody = newExchange.getIn().getBody(String.class);
oldExchange.getIn().setBody(oldBody + newBody);
return oldExchange;
}
})
// See comment on "setHeader(...) above.
.header("incoming")
// In this initial testing, aggregation of a particular message is
// considered complete when the last line received is "EOM".
.completionPredicate(exchange -> {
final String body = exchange.getIn().getBody(String.class);
final boolean done = body.endsWith("EOM");
return done;
})
// This endpoint will eventually parse the aggregated message and
// perform logic on it. Right now, it just returning the input message
// with a prefix.
.to("bean:echoService");
}
}
When I start my server, and telnet to port 4321 from a separate terminal window, I can verify in the debugger that:
The .completetionPredicate(...) logic is being invoked upon each line of input as expected, and
The echoService endpoint is being invoked as expected after an EOM line of input. The message passed to the endpoint contains the expected aggregated content.
However, there are two problems:
The server is echoing each line of input back to the client connection, rather than letting the endpoint determine the response content.
The server is not sending the endpoint return value to the client. I log it to the server console, but otherwise it's silently discarded.
Any suggestions on what I might be missing here? The desired behavior is for the route to send the endpoint's return value to the client socket, and nothing but the endpoint's return value. Thanks!

RxJS5 WebSocketSubject - how to filter and complete messages?

I'm looking for some guidance on the correct way to setup a WebSocket connection with RxJS 5. I am connecting to a WebSocket that uses JSON-RPC 2.0. I want to be able to execute a function which sends a request to the WS and returns an Observable of the associated response from the server.
I set up my initial WebSocketSubject like so:
const ws = Rx.Observable.webSocket("<URL>")
From this observable, I have been able to send requests using ws.next(myRequest), and I have been able to see responses coming back through the ws` observable.
I have struggled with creating functions that will filter the ws responses to the correct response and then complete. These seem to complete the source subject, stopping all future ws requests.
My intended output is something like:
function makeRequest(msg) {
// 1. send the message
// 2. return an Observable of the response from the message, and complete
}
I tried the following:
function makeRequest(msg) {
const id = msg.id;
ws.next(msg);
return ws
.filter(f => f.id === id)
.take(1);
}
When I do that however, only the first request will work. Subsequent requests won't work, I believe because I am completing with take(1)?
Any thoughts on the appropriate architecture for this type of situation?
There appears to be either a bug or a deliberate design decision to close the WebSocket on unsubscribe if there are no further subscribers. If you are interested here is the relevant source.
Essentially you need to guarantee that there is always a subscriber otherwise the WebSocket will be closed down. You can do this in two ways.
Route A is the more semantic way, essentially you create a published version of the Observable part of the Subject which you have more fine grained control over.
const ws = Rx.Observable.webSocket("<URL>");
const ws$ = ws.publish();
//When ready to start receiving messages
const totem = ws$.connect();
function makeRequest(msg) {
const { id } = msg;
ws.next(msg);
return ws$.first(f => f.id === id)
}
//When finished
totem.unsubscribe();
Route B is to create a token subscription that simply holds the socket, but depending on the actual life cycle of your application you would do well to attach to some sort of closing event just to make sure it always gets closed down. i.e.
const ws = Rx.Observable.webSocket("<URL>");
const totem = ws.subscribe();
//Later when closing:
totem.unsubscribe();
As you can see both approaches are fairly similar, since they both create a subscription. B's primary disadvantage is that you create an empty subscription which will get pumped all the events only to throw them away. They only advantage of B is that you can refer to the Subject for emission and subscription using the same variable whereas A you must be careful that you are using ws$ for subscription.
If you were really so inclined you could refine Route A using the Subject creation function:
const safeWS = Rx.Subject.create(ws, ws$);
The above would allow you to use the same variable, but you would still be responsible for shutting down ws$ and transitively, the WebSocket, when you are done with it.

Resources