Amazon SNS Confirmation Token - spring-mvc

I was trying to implement Amazon SNS service to my project. I am able to create a topic and subscribe to a topic as well. Here, I am using sms as a protocol and phone number as endpoint. The main problem is I am not getting any confirmation to my mobile phone number and unable to publish message. How can I get a token to confirmSubscription? //subscriptionRequest.withToken(token);
public class SNSServiceImpl implements SNSService {
private static final Logger logger = LoggerFactory.getLogger(SNSServiceImpl.class);
#Value("${AWS_ACCESS_KEY_ID:key}")
private String awsAccessKeyId;
#Value("${AWS_SECRET_ACCESS_KEY:secret}")
private String awsAccessKeySecret;
#Value("${AWS_REGION:us-west-2}")
private String awsRegion;
private AmazonSNS snsClient;
private String subscriptionArn;
#PostConstruct
public void setConnection() {
AWSCredentials awsCredentials = new BasicAWSCredentials(awsAccessKeyId, awsAccessKeySecret);
AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
snsClient = AmazonSNSClient.builder()
.withRegion(awsRegion)
.withCredentials(awsCredentialsProvider)
.build();
}
#Override
public String createTopic(String topicName) {
CreateTopicRequest topicRequest = new CreateTopicRequest(topicName);
CreateTopicResult topicResult = snsClient.createTopic(topicRequest);
return topicResult.getTopicArn();
}
#Override
public void subscribeToTopic(String topicArn) {
SubscribeRequest subscribeRequest = new SubscribeRequest();
subscribeRequest.setTopicArn(topicArn);
subscribeRequest.setProtocol("sms");
subscribeRequest.setEndpoint("+14699011920");
SubscribeResult subscribeResult = snsClient.subscribe(subscribeRequest);
subscriptionArn = subscribeResult.getSubscriptionArn();
}
#Override
public void confirmSubscription(String topicArn) {
ConfirmSubscriptionRequest subscriptionRequest = new ConfirmSubscriptionRequest();
subscriptionRequest.withTopicArn(topicArn);
//subscriptionRequest.withToken(token);
ConfirmSubscriptionResult confirmSubscriptionResult = snsClient.confirmSubscription(subscriptionRequest);
confirmSubscriptionResult.withSubscriptionArn(subscriptionArn);
}
#Override
public void publishMessage(String topicArn, String message) {
PublishRequest publishRequest = new PublishRequest(topicArn, message);
PublishResult publishResult = snsClient.publish(publishRequest);
System.out.println(publishResult);
}
}

I just change the publishMessage method and delete the confirmSubscription this method from my service.
#Component
public class SNSServiceImpl implements SNSService {
private static final Logger logger = LoggerFactory.getLogger(SNSServiceImpl.class);
#Value("${AWS_ACCESS_KEY_ID:key}")
private String awsAccessKeyId;
#Value("${AWS_SECRET_ACCESS_KEY:secret}")
private String awsAccessKeySecret;
#Value("${AWS_REGION:us-west-2}")
private String awsRegion;
private AmazonSNS snsClient;
#PostConstruct
public void setConnection() {
AWSCredentials awsCredentials = new BasicAWSCredentials(awsAccessKeyId, awsAccessKeySecret);
AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
snsClient = AmazonSNSClient.builder()
.withRegion(awsRegion)
.withCredentials(awsCredentialsProvider)
.build();
}
#Override
public String createTopic(String topicName) {
CreateTopicRequest topicRequest = new CreateTopicRequest(topicName);
CreateTopicResult topicResult = snsClient.createTopic(topicRequest);
logger.info("Create topic request: " + snsClient.getCachedResponseMetadata(topicRequest));
logger.info("Create topic result: " + topicResult);
return topicResult.getTopicArn();
}
#Override
public void subscribeSNSToTopic(String topicArn, String phoneNumber) {
String protocol = "sms";
SubscribeRequest subscribeRequest = new SubscribeRequest(topicArn, protocol, phoneNumber);
SubscribeResult subscribeResult = snsClient.subscribe(subscribeRequest);
logger.info("Subscribe request: " + snsClient.getCachedResponseMetadata(subscribeRequest));
logger.info("Subscribe result: " + subscribeResult);
}
#Override
public void sendSMSMessageToTopic(String topicArn, String message) {
Map<String, MessageAttributeValue> smsAttributes =
new HashMap<>();
smsAttributes.put("AWS.SNS.SMS.SenderID", new MessageAttributeValue()
.withStringValue("mySenderID") //The sender ID shown on the device.
.withDataType("String"));
smsAttributes.put("AWS.SNS.SMS.MaxPrice", new MessageAttributeValue()
.withStringValue("0.50") //Sets the max price to 0.50 USD.
.withDataType("Number"));
smsAttributes.put("AWS.SNS.SMS.SMSType", new MessageAttributeValue()
.withStringValue("Promotional") //Sets the type to promotional.
.withDataType("String"));
PublishResult publishResult = snsClient.publish(new PublishRequest()
.withTopicArn(topicArn)
.withMessage(message)
.withMessageAttributes(smsAttributes));
logger.info("Public Result: " + publishResult);
}
}

Related

Android Studio Firebase Cloud Messaging Not Working?

I am developing an e-commerce application in which when user orders places an order, the seller should receive a notification of new order. I am able to send notifications as it shows a toast message of "Response" but no notification is received on the seller part. I checked the code multiple times but I am still unable to find out where I am making the mistake. Here is my code
public class MyFirebaseMessaging extends FirebaseMessagingService {
private static final String NOTIFICATION_CHANNEL_ID = "MY_NOTIFICATION_CHANNEL_ID";
FirebaseAuth firebaseAuth;
FirebaseUser firebaseUser;
#Override
public void onMessageReceived(#NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
firebaseAuth = FirebaseAuth.getInstance();
firebaseUser = firebaseAuth.getCurrentUser();
String notificationType = remoteMessage.getData().get("notificationType");
if (notificationType.equals("NewOrder")){
String buyerUid = remoteMessage.getData().get("buyerUid");
String sellerUid = remoteMessage.getData().get("sellerUid");
String orderId = remoteMessage.getData().get("orderId");
String notificationTitle = remoteMessage.getData().get("notificationTitle");
String notificationMessage = remoteMessage.getData().get("notificationMessage");
if (firebaseUser != null && firebaseAuth.getUid().equals(sellerUid)){
showNotification(orderId,sellerUid,buyerUid,notificationTitle,notificationMessage,notificationType);
}
}
if (notificationType.equals("OrderStatusChanged")){
String buyerUid = remoteMessage.getData().get("buyerUid");
String sellerUid = remoteMessage.getData().get("sellerUid");
String orderId = remoteMessage.getData().get("orderId");
String notificationTitle = remoteMessage.getData().get("notificationTitle");
String notificationMessage = remoteMessage.getData().get("notificationMessage");
if (firebaseUser != null && firebaseAuth.getUid().equals(buyerUid)){
showNotification(orderId,sellerUid,buyerUid,notificationTitle,notificationMessage,notificationType);
}
}
}
private void showNotification(String orderId,String sellerUid,String buyerUid,String notificationTitle,String notificationDescription,String notificationType){
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
int notificationID = new Random().nextInt(3000);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
setUpNotificationChannel(notificationManager);
}
Intent intent = null;
if (notificationType.equals("NewOrder")){
intent = new Intent(this,ShopOrderDetails.class);
intent.putExtra("orderId",orderId);
intent.putExtra("orderBy",buyerUid);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
} else if (notificationType.equals("OrderStatusChanged")){
intent = new Intent(this,UserOrderDetailsActivity.class);
intent.putExtra("orderId",orderId);
intent.putExtra("orderTo",sellerUid);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
}
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),R.drawable.indianflag);
//notification sound
Uri notificationSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this,NOTIFICATION_CHANNEL_ID);
notificationBuilder.setSmallIcon(R.drawable.indianflag)
.setLargeIcon(largeIcon)
.setContentTitle(notificationTitle)
.setContentText(notificationDescription)
.setSound(notificationSoundUri)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
//show notification
notificationManager.notify(notificationID,notificationBuilder.build());
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void setUpNotificationChannel(NotificationManager notificationManager) {
CharSequence channelName = "Some sample text";
String channelDescription = "Channel Description Here";
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,channelName,NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setDescription(channelDescription);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
if (notificationManager != null){
notificationManager.createNotificationChannel(notificationChannel);
}
}
}
private void prepareNotification(String orderId){
String NOTIFICATION_TOPIC = "/topics/"+ Constants.FCM_TOPIC;
String NOTIFICATION_TITLE = "New Order "+orderId;
String NOTIFICATION_MESSAGE = "You have a new order";
String NOTIFICATION_TYPE = "NewOrder";
JSONObject notificationJo = new JSONObject();
JSONObject notificationBodyJo = new JSONObject();
Log.d("userId",mAuth.getUid());
Log.d("shopId",shopId);
Log.d("orderId",orderId);
try{
notificationBodyJo.put("notificationType",NOTIFICATION_TYPE);
notificationBodyJo.put("buyerUid",mAuth.getUid());
notificationBodyJo.put("sellerUid",shopId);
notificationBodyJo.put("orderId",orderId);
notificationBodyJo.put("notificationTitle",NOTIFICATION_TITLE);
notificationBodyJo.put("notificationMessage",NOTIFICATION_MESSAGE);
notificationJo.put("to",NOTIFICATION_TOPIC);
notificationJo.put("data",notificationBodyJo);
}catch (Exception e){
Toast.makeText(ProceedToCheckoutActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
}
sendFCMNotification(notificationJo,orderId);
}
private void sendFCMNotification(JSONObject notificationJo, String timeStamp1) {
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("https://fcm.googleapis.com/fcm/send", notificationJo, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Toast.makeText(ProceedToCheckoutActivity.this, "Response", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(ProceedToCheckoutActivity.this,UserOrderDetailsActivity.class);
intent.putExtra("shopID",shopId);
intent.putExtra("orderId",timeStamp1);
startActivity(intent);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error Here",error.toString());
Toast.makeText(ProceedToCheckoutActivity.this, "Error", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(ProceedToCheckoutActivity.this,UserOrderDetailsActivity.class);
intent.putExtra("shopID",shopId);
intent.putExtra("orderId",timeStamp1);
startActivity(intent);
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> headers = new HashMap<>();
headers.put("Content-Type","application/json");
headers.put("Authorization","key="+Constants.FCM_KEY);
return headers;
}
};
Volley.newRequestQueue(this).add(jsonObjectRequest);
}
Please use retrofit or volley to send notifications to second user.
Link: sending fcm push notifications using retrofit library in android
Module:app dependencies
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
ApiClient
public class ApiClient {
private static final String BASE_URL = "https://fcm.googleapis.com/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
ApiInterface
public interface ApiInterface {
#Headers({"Authorization: key=" + ConstantKey.SERVER_KEY, "Content-Type:application/json"})
#POST("fcm/send")
Call<ResponseBody> sendNotification(#Body RootModel root);
}
RootModel
public class RootModel {
#SerializedName("to") // "to" changed to token
private String token;
#SerializedName("notification")
private NotificationModel notification;
#SerializedName("data")
private DataModel data;
public RootModel(String token, NotificationModel notification, DataModel data) {
this.token = token;
this.notification = notification;
this.data = data;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public NotificationModel getNotification() {
return notification;
}
public void setNotification(NotificationModel notification) {
this.notification = notification;
}
public DataModel getData() {
return data;
}
public void setData(DataModel data) {
this.data = data;
}
}
NotificationModel
public class NotificationModel {
private String title;
private String body;
public NotificationModel(String title, String body) {
this.title = title;
this.body = body;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
DataModel
public class DataModel {
private String name;
private String age;
public DataModel(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
Send notification by using this method
private void sendNotificationToUser(String token) {
RootModel rootModel = new RootModel(token, new NotificationModel("Title", "Body"), new DataModel("Name", "30"));
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
retrofit2.Call<ResponseBody> responseBodyCall = apiService.sendNotification(rootModel);
responseBodyCall.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(retrofit2.Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
Log.d(TAG,"Successfully notification send by using retrofit.");
}
#Override
public void onFailure(retrofit2.Call<ResponseBody> call, Throwable t) {
}
});
}

How can i capture record key and value when there is a DeserializationException while consuming a message from kafka topic?

I'm using spring boot 2.1.7.RELEASE and spring-kafka 2.2.8.RELEASE.And I'm using #KafkaListener annotation to create a consumer and I'm using all default settings for the consumer.And I'm using below configuration as specified in the Spring-Kafka documentation.
// other props
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ErrorHandlingDeserializer2.class);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, ErrorHandlingDeserializer2.class);
props.put(ErrorHandlingDeserializer.KEY_DESERIALIZER_CLASS, StringDeserializer.class);
props.put(ErrorHandlingDeserializer.VALUE_DESERIALIZER_CLASS, AvroDeserializer.class.getName());
return new DefaultKafkaConsumerFactory<>(props);
Now, I've implemented my custom SeekToCurrentErrorHandler by extending SeekToCurrentErrorHandler as per the below thread but the record value is coming as null and the record key is not in a readable format. Please suggest me how can i get the record key and value?
How to capture the exception and message key when using ErrorHandlingDeserializer2 to handle exceptions during deserialization
Here is my custom SeekToCurrentErrorHandler code
#Component
public class MySeekToCurrentErrorHandler extends SeekToCurrentErrorHandler {
private final MyDeadLetterRecoverer deadLetterRecoverer;
#Autowired
public MySeekToCurrentErrorHandler(MyDeadLetterRecoverer deadLetterRecoverer) {
super(-1);
this.deadLetterRecoverer = deadLetterRecoverer;
}
#Override
public void handle(Exception thrownException, List<ConsumerRecord<?, ?>> data, Consumer<?, ?> consumer, MessageListenerContainer container) {
if (thrownException instanceof DeserializationException) {
//Improve to support multiple records
DeserializationException deserializationException = (DeserializationException) thrownException;
deadLetterRecoverer.accept(data.get(0), deserializationException);
ConsumerRecord<?, ?>. consumerRecord = data.get(0);
sout(consumerRecord.key());
sout(consumerRecord.value());
} else {
//Calling super method to let the 'SeekToCurrentErrorHandler' do what it is actually designed for
super.handle(thrownException, data, consumer, container);
}
}
}
If the key fails deserialization, the original byte[] can be obtained by calling getData() on the exception.
Similarly, if the value fails deserialization, use getData() to get the original data.
The DeadLetterPublishingRecoverer does this (since 2.3).
You can tell which of the key or value failed by calling isKey() on the exception.
EDIT
I was wrong, the key and value are available if the value or key failed.
This is written with Boot 2.3.4:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
SeekToCurrentErrorHandler errorHandler(ProducerFactory<String, String> pf) {
Map<String, Object> configs = new HashMap<>(pf.getConfigurationProperties());
configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class);
configs.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class);
ProducerFactory<byte[], byte[]> bytesPF = new DefaultKafkaProducerFactory<>(configs);
KafkaOperations<byte[], byte[]> template = new KafkaTemplate<>(bytesPF);
return new SeekToCurrentErrorHandler(new DeadLetterPublishingRecoverer(template),
new FixedBackOff(1000, 5));
}
#KafkaListener(id = "so64597061", topics = "so64597061",
properties = {
ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG
+ ":org.springframework.kafka.support.serializer.ErrorHandlingDeserializer",
ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG
+ ":org.springframework.kafka.support.serializer.ErrorHandlingDeserializer",
ErrorHandlingDeserializer.KEY_DESERIALIZER_CLASS
+ ":com.example.demo.Application$FailSometimesDeserializer",
ErrorHandlingDeserializer.VALUE_DESERIALIZER_CLASS
+ ":com.example.demo.Application$FailSometimesDeserializer"
})
public void listen(String val, #Header(name = KafkaHeaders.RECEIVED_MESSAGE_KEY) String key) {
System.out.println(key + ":" + val);
}
#KafkaListener(id = "so64597061.dlt", topics = "so64597061.DLT",
properties = {
ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG
+ ":org.apache.kafka.common.serialization.ByteArrayDeserializer",
ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG
+ ":org.apache.kafka.common.serialization.ByteArrayDeserializer"
})
public void dltListen(byte[] val, #Header(name = KafkaHeaders.RECEIVED_MESSAGE_KEY, required = false) byte[] key) {
String keyStr = key != null ? new String(key) : null;
String valStr = val != null ? new String(val) : null;
System.out.println("DLT:" + keyStr + ":" + valStr);
}
#Bean
public ApplicationRunner runner(KafkaTemplate<String, String> template) {
return args -> {
template.send("so64597061", "foo", "bar");
template.send("so64597061", "fail", "keyFailed");
template.send("so64597061", "valueFailed", "fail");
};
}
#Bean
public NewTopic topic() {
return TopicBuilder.name("so64597061").partitions(1).replicas(1).build();
}
#Bean
public NewTopic dlt() {
return TopicBuilder.name("so64597061.DLT").partitions(1).replicas(1).build();
}
public static class FailSometimesDeserializer implements Deserializer<byte[]> {
#Override
public void configure(Map<String, ?> configs, boolean isKey) {
}
#Override
public byte[] deserialize(String topic, byte[] data) {
return data;
}
#Override
public void close() {
}
#Override
public byte[] deserialize(String topic, Headers headers, byte[] data) {
String string = new String(data);
if ("fail".equals(string)) {
throw new RuntimeException("fail");
}
return data;
}
}
}
spring.kafka.consumer.auto-offset-reset=earliest
foo:bar
DLT:fail:keyFailed
DLT:valueFailed:fail

Get the userId (or interact with other users) in Firebase Database

I am building a chat app with Firebase and I am having issues identifying who is who, when a user sends another user a message, he needs to post it to the receivers node and he needs to know his UID to do that. I need to know how to get the receiver's UID, so I can post directly to his own node.
I tried using intent.putExtra and intent.getExtras from my MainActivity which lists out every user from their directories, this is my current code that does not successfully pass the data I need.
public static class PlaceholderFragment extends Fragment {
private DatabaseReference mDatabase;
private FirebaseAuth mAuth;
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public static class UserHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
View mView;
public UserHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
mView = itemView;
}
public void setName(String name) {
TextView field = (TextView) mView.findViewById(R.id.thename);
field.setText(name);
}
public void setImage(String image){
ImageView pp = (ImageView) mView.findViewById(R.id.imageurl);
try{
Picasso.with(Application.getAppContext()).load(image).placeholder(R.drawable.nodp).error(R.drawable.nodp).transform(new CircleTransform()).into(pp);
}
catch (IllegalArgumentException e){
Picasso.with(Application.getAppContext()).load(R.drawable.nodp).transform(new CircleTransform()).into(pp);
}
}
#Override
public void onClick(View mView) {
//what to do here
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
//textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
//private static final String TAG = "UserListActivity";
//final TextView name = (TextView) rootView.findViewById(R.id.lastname) ;
//final ImageView profileImage = (ImageView) rootView.findViewById(R.id.imageView4);
mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
final DatabaseReference root = FirebaseDatabase.getInstance().getReference();
DatabaseReference userRef = root.child("users");
RecyclerView recycler = (RecyclerView) rootView.findViewById(R.id.recyclerview3);
recycler.setHasFixedSize(true);
recycler.setLayoutManager(new LinearLayoutManager(getActivity()));
FirebaseRecyclerAdapter mAdapter = new FirebaseRecyclerAdapter<UserList, UserHolder>(UserList.class, R.layout.userlistrow, UserHolder.class, userRef) {
#Override
public void populateViewHolder(UserHolder userViewHolder, final UserList userList, final int position) {
//try catch block to catch events of no posts, it will most likely return a null error, so im catching it, else
//find its exception and catch it
try {
String firstname = userList.getFirstname().toString();
String lastname = userList.getLastname().toString();
firstname = firstname.substring(0, 1).toUpperCase() + firstname.substring(1); //convert first string to uppercase
lastname = lastname.substring(0, 1).toUpperCase() + lastname.substring(1);// same thing happening here
String name = (firstname + " " + lastname); // concatenate firstname and lastname variable.
userViewHolder.setName(name);
}
catch(NullPointerException e) {
String firstname = "Not";
String lastname = "set";
String name = (firstname + " " + lastname );
userViewHolder.setName(name);
}
catch (StringIndexOutOfBoundsException e) {
String firstname = "No";
String lastname = "name";
String name = (firstname + " " + lastname );
userViewHolder.setName(name);
}
//note that picasso view holder was applied in the view holder instead
//String image = userList.getImgUrl().toString();
//userViewHolder.setImage(image);
//findViewById(R.id.progressBar3).setVisibility(View.GONE);
This is where I am passing the extras, and it doesnt seem to work
userViewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Log.w(TAG, "You clicked on "+position);
//String firstname = userList.getFirstname();
//String lastname = userList.getLastname();
//firstname = firstname.substring(0, 1).toUpperCase() + firstname.substring(1); //convert first string to uppercase
//lastname = lastname.substring(0, 1).toUpperCase() + lastname.substring(1);// same thing happening here
//String name = (firstname + " " + lastname); // concatenate firstname and lastname variable.
Intent intent = new Intent(getActivity(), Userdetail.class); //change to onclick
intent.putExtra("userId", userList.getUserId());//you can name the keys whatever you like
intent.putExtra("lastname", userList.getLastname().toString());
intent.putExtra("firstname", userList.getFirstname().toString());
intent.putExtra("image", userList.getImgUrl().toString()); //note that all these values have to be primitive (i.e boolean, int, double, String, etc.)
startActivity(intent);
}
});
}
};
recycler.setAdapter(mAdapter);
return rootView;
}
}
If you need more information, please ask in the comments. Ive googled around but no help
package com.mordred.theschoolapp;
import com.google.firebase.database.IgnoreExtraProperties;
/**
* Created by mordred on 11/28/16.
*/
public class UserList {
public String firstname;
public String lastname;
public String userId;
public String imgUrl;
public UserList() {
// Default constructor required for calls to DataSnapshot.getValue(User.class)
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}

GXT 3 Can't fill Grid

I want to load data from a remote server in the grid. The following code:
final RepServiceAsync service = GWT.create(RepService.class);
final RepProperties props = GWT.create(RepProperties.class);
RpcProxy<PagingLoadConfig, PagingLoadResult<ReportsList>> proxy = new RpcProxy<PagingLoadConfig, PagingLoadResult<ReportsList>>() {
#SuppressWarnings("unchecked")
#Override
public void load(PagingLoadConfig loadConfig, AsyncCallback callback) {
service.getReports(callback);
}
};
ListStore<ReportsList> store = new ListStore<ReportsList>(props.key());
final PagingLoader<PagingLoadConfig, PagingLoadResult<ReportsList>> loader = new PagingLoader<PagingLoadConfig, PagingLoadResult<ReportsList>>(
proxy);
loader.setRemoteSort(true);
loader.addLoadHandler(new LoadResultListStoreBinding<PagingLoadConfig, ReportsList, PagingLoadResult<ReportsList>>(
store));
final PagingToolBar toolBar = new PagingToolBar(50);
toolBar.getElement().getStyle().setProperty("borderBottom", "none");
toolBar.bind(loader);
ColumnConfig<ReportsList, String> nameCol = new ColumnConfig<ReportsList, String>(
props.name(), 150, "Name");
ColumnConfig<ReportsList, String> pathCol = new ColumnConfig<ReportsList, String>(
props.path_name(), 150, "Path");
List<ColumnConfig<ReportsList, ?>> l = new ArrayList<ColumnConfig<ReportsList, ?>>();
l.add(nameCol);
l.add(pathCol);
ColumnModel<ReportsList> cm = new ColumnModel<ReportsList>(l);
Grid<ReportsList> grid = new Grid<ReportsList>(store, cm) {
#Override
protected void onAfterFirstAttach() {
super.onAfterFirstAttach();
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
loader.load();
}
});
}
};
grid.getView().setForceFit(true);
grid.setLoadMask(true);
grid.setLoader(loader);
RepProperties:
public interface RepProperties extends PropertyAccess<ReportsList> {
#Path("id")
ModelKeyProvider<ReportsList> key();
ValueProvider<ReportsList, String> name();
ValueProvider<ReportsList, String> path_name();
}
ReportsList code:
public class ReportsList implements Serializable {
private static final long serialVersionUID = 1L;
int id;
String name;
String path_name;
public ReportsList() {
}
public ReportsList(int id, String name, String path_name) {
super();
this.id = id;
this.name = name;
this.path_name = path_name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath_name() {
return path_name;
}
public void setPath_name(String path_name) {
this.path_name = path_name;
}
}
GWT Servlet Impl:
public class RepServiceImpl extends RemoteServiceServlet implements RepService {
private static final long serialVersionUID = 1L;
#EJB
private ReportEjb repManager;
#Override
public List<Report> getReports() {
List<Report> reports = null;
reports = repManager.getReports();
return reports ;
}
}
The code is executed without error, the query to the database is performed ( EJB-call ), but the Grid is not populated.
In what could be the problem?
In my experience this usually means that there is an exception while trying to put data into the grid itself. Try attaching a LoadExceptionHandler to your loader and see what it gives you
e.g.
public class DebugLoadHandler implements LoadExceptioniHandler<ListLoadConfig> {
#Override
public void onLoadException(LoadExceptionEvent<ListLoadConfig> event) {
Window.alert("Load Exception" + event.getException().getMessage());
}
}

FFmpeg multicast with multiple network interfaces

I have java-application as wrapper on FFmpeg. I need to capture mp2 multicast stream, convert it to mp3 and send converted multicast stream to another address.
It works well. But now I have two network interfaces. And one of them for internet/local network (eth1). Need to configure second network interface (eth2) to capture and send multicast streams.
But ffmpeg try to capture from first network interface by default. I can see packets in tcpdump, but ffmpeg don't capture it from eth2.
How can I specify interface for stream capturing and interface for stream sending?
This was solved by smcroute utility.
application.properties:
smcroute.config.file = /etc/smcroute.conf
RoutingConfig.java:
public class RoutingConfig {
private final File file;
public RoutingConfig(String filename) {
this.file = new File(filename);
}
public List<RoutingRecord> read() throws IOException {
List<String> lines = Files.readAllLines(file.toPath());
return lines.stream().map(RoutingRecord::new).collect(Collectors.toList());
}
public void write(List<RoutingRecord> records) throws IOException {
List<String> lines = records.stream().map(RoutingRecord::toString).collect(Collectors.toList());
Files.write(file.toPath(), lines);
}
}
RoutingRecord.java:
public class RoutingRecord {
private String sourceInterface;
private String multicastAddress;
private String sourceMulticastAddress;
private List<String> destinationInterfaces;
public RoutingRecord() {
}
public RoutingRecord(String line) {
String[] words = line.split(" ");
this.sourceInterface = words[2];
this.multicastAddress = words[4];
this.sourceMulticastAddress = words[6];
this.destinationInterfaces = new ArrayList<>(Arrays.asList(words).subList(8, words.length));
}
public RoutingRecord(String sourceInterface,
String multicastAddress,
String sourceMulticastAddress,
List<String> destinationInterfaces
) {
this.sourceInterface = sourceInterface;
this.multicastAddress = multicastAddress;
this.sourceMulticastAddress = sourceMulticastAddress;
this.destinationInterfaces = destinationInterfaces;
}
public String getSourceInterface() {return sourceInterface;}
public String getMulticastAddress() {return multicastAddress;}
public String getSourceMulticastAddress() {return sourceMulticastAddress;}
public List<String> getDestinationInterfaces() {return destinationInterfaces;}
public String getDestinationInterfacesLine() {return String.join(", ", destinationInterfaces);}
public RoutingRecord setSourceInterface(String sourceInterface) {
this.sourceInterface = sourceInterface;
return this;
}
public RoutingRecord setMulticastAddress(String multicastAddress) {
this.multicastAddress = multicastAddress;
return this;
}
public RoutingRecord setSourceMulticastAddress(String sourceMulticastAddress) {
this.sourceMulticastAddress = sourceMulticastAddress;
return this;
}
public RoutingRecord setDestinationInterfaces(List<String> destinationInterfaces) {
this.destinationInterfaces = destinationInterfaces;
return this;
}
#Override
public String toString() {
return "mroute from " + sourceInterface + " " +
"group " + multicastAddress + " " +
"source " + sourceMulticastAddress + " " +
"to " + String.join(" ", destinationInterfaces);
}
RoutingServiceImpl.java:
#Service
public class RoutingServiceImpl implements RoutingService {
private final Environment environment;
#Autowired
public RoutingServiceImpl(Environment environment) {
this.environment = environment;
}
#Override
public List<RoutingRecord> getRoutingLines() throws IOException {
String filename = environment.getProperty("smcroute.config.file");
RoutingConfig routingConfig = new RoutingConfig(filename);
return routingConfig.read();
}
#Override
public void saveRoutingLines(List<RoutingRecord> records) throws IOException {
String filename = environment.getProperty("smcroute.config.file");
RoutingConfig routingConfig = new RoutingConfig(filename);
routingConfig.write(records);
}
#Override
public void saveRoutingLine(RoutingRecord routingRecord) throws IOException {
String filename = environment.getProperty("smcroute.config.file");
RoutingConfig routingConfig = new RoutingConfig(filename);
List<RoutingRecord> records = routingConfig.read();
records.add(routingRecord);
routingConfig.write(records);
}
#Override
public void applyRoutes() throws IOException {
Runtime rt = Runtime.getRuntime();
rt.exec(new String[] {
"service",
"smcroute",
"restart"
});
}
}

Resources