I have created a java application to send/receive the topic messages using Azure Service Bus java SDK and it is working perfectly fine if I run it as a Java Application.
I exported the application as jar along with all the dependency jars to the {ColdFusionInstallation}\cfusion\lib and restarted ColdFusion Application Server.
I am able to create the class objects and see their definitions while dumping but when I trying to call any particular method from the class, it's taking forever.
<cfset objSender = createObject( "java", "com.test.Sender" ).init()>
<cfset objSender.sendAsync( JavaCast( "string", "cftest" ) )>
Sender.java
package com.test;
import java.util.concurrent.CompletableFuture;
import org.apache.log4j.Logger;
import com.microsoft.azure.servicebus.IMessage;
import com.microsoft.azure.servicebus.ITopicClient;
import com.microsoft.azure.servicebus.Message;
import com.microsoft.azure.servicebus.TopicClient;
import com.microsoft.azure.servicebus.primitives.ConnectionStringBuilder;
import com.microsoft.azure.servicebus.primitives.ServiceBusException;
public class Sender {
private final String namespaceConnectionString = "Endpoint=sb.......";
private final String namespaceTopicName = "test";
private static Logger logger = Logger.getRootLogger();
public CompletableFuture<Void> sendAsync( String message ) {
// Get client
ITopicClient topicClient = this.createTopicClient( this.namespaceTopicName );
// Send Async
CompletableFuture<Void> future = topicClient.sendAsync(
new Message( message )
).thenRunAsync( () -> {
try {
topicClient.close();
} catch (Exception e) {
logger.info( "Unable to close topic client!" );
}
} );
return future;
}
private ITopicClient createTopicClient( String topicName ) throws RuntimeException {
// Create client for topic
ITopicClient topicClient = null;
try {
// Create
topicClient = new TopicClient(
new ConnectionStringBuilder( this.namespaceConnectionString, topicName )
);
} catch ( InterruptedException | ServiceBusException e ) {
logger.info( "Unable to client for topic: " + topicName );
throw new RuntimeException( "Unable to create client for topic: " + topicName );
}
return topicClient;
}
}
I am not sure what is wrong as it is working when running directly.
Any suggestions greatly appreciated!
Related
Can some one give me a direction how can I implement this aws email template tutorial by a java code? Through java code I want to set this AWS Email Template and through java only I want to set the parameter values to the template and through java only I want to send the email.
I cant find any tutorial or direction from which I can translate above requests in java code.
The "code" in your link is actually just some JSON templates for sending and formatting email, and a few calls to an AWS command line tool. If you need to make AWS send email calls from a Java process then you need to take a look at:
The SES API
The Javadoc for the Java client lib
I am able to code it successfully. Pasting the example code here.
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClientBuilder;
import com.amazonaws.services.simpleemail.model.BulkEmailDestination;
import com.amazonaws.services.simpleemail.model.BulkEmailDestinationStatus;
import com.amazonaws.services.simpleemail.model.Destination;
import com.amazonaws.services.simpleemail.model.SendBulkTemplatedEmailRequest;
import com.amazonaws.services.simpleemail.model.SendBulkTemplatedEmailResult;
public class AmazonSESSample2 {
public static void main(String[] args) throws IOException {
String accessKeyId = "accessKeyId";
String secretKeyId = "secretKeyId";
String region = "us-east-1";
List<BulkEmailDestination> listBulkEmailDestination = null;
SendBulkTemplatedEmailRequest sendBulkTemplatedEmailRequest = null;
try {
AmazonSimpleEmailService client = getAmazonSESClient(accessKeyId, secretKeyId, region);
listBulkEmailDestination = new ArrayList<>();
for(String email : getRecievers()) {
String replacementData="{"
+ "\"FULL_NAME\":\"AAA BBB\","
+ "\"USERNAME\":\""+email+"\","
+ "}";
BulkEmailDestination bulkEmailDestination = new BulkEmailDestination();
bulkEmailDestination.setDestination(new Destination(Arrays.asList(email)));
bulkEmailDestination.setReplacementTemplateData(replacementData);
listBulkEmailDestination.add(bulkEmailDestination);
}
sendBulkTemplatedEmailRequest = new SendBulkTemplatedEmailRequest();
sendBulkTemplatedEmailRequest.setSource("noreply#mydomain.com");
sendBulkTemplatedEmailRequest.setTemplate("welcome-email-en_GB-v1");
sendBulkTemplatedEmailRequest.setDefaultTemplateData("{\"FULL_NAME\":\"friend\", \"USERNAME\":\"unknown\"}");
sendBulkTemplatedEmailRequest.setDestinations(listBulkEmailDestination);
SendBulkTemplatedEmailResult res = client.sendBulkTemplatedEmail(sendBulkTemplatedEmailRequest);
System.out.println("======================================");
System.out.println(res.getSdkResponseMetadata());
System.out.println("======================================");
for(BulkEmailDestinationStatus status : res.getStatus()) {
System.out.println(status.getStatus());
System.out.println(status.getError());
System.out.println(status.getMessageId());
}
} catch (Exception ex) {
System.out.println("The email was not sent. Error message: " + ex.getMessage());
ex.printStackTrace();
}
}
public static List<String> getRecievers() {
ArrayList<String> list = new ArrayList<>();
list.add("aaa+1#gmail.com");
list.add("aaa+2#gmail.com");
list.add("aaa+3#gmail.com");
list.add("aaa+4#gmail.com");
return list;
}
public static AmazonSimpleEmailService getAmazonSESClient(String accessKeyId, String secretKeyId, String region) {
BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKeyId, secretKeyId);
AmazonSimpleEmailService client = AmazonSimpleEmailServiceClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(awsCreds))
.withRegion(region)
.build();
return client;
}
}
I am new to IoTHub. I have successfully sent messages to IOT hub (D2C) using python.The protocol we used is mqtt.We are trying to retrieve data from cloud(IOT hub) using java,but could not able to find out a proper way to recieve message from the cloud..My doubt is whether we can read messages from IOT Hub directly or we need to redirect the incoming messages to an event hub to retrieve the message.
Also I tried to read messages from iothub in java simultaneously while sending data to cloud,but I got the error as follows..(Lost connection to the server. Reconnecting 0 time.)
I use this code to read data from iothub,
import com.microsoft.azure.sdk.iot.device.DeviceClient;
import com.microsoft.azure.sdk.iot.device.IotHubMessageResult;
import com.microsoft.azure.sdk.iot.device.Message;
import com.microsoft.azure.sdk.iot.device.MessageCallback;
import com.microsoft.azure.sdk.iot.device.IotHubClientProtocol;
import com.microsoft.azure.sdk.iot.service.sdk.IotHubServiceClientProtocol;
import java.io.IOException;
import java.net.URISyntaxException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Kafkareception {
public static void main(String[] args) throws IOException {
try {
String connString = "HostName=";
IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
DeviceClient client = new DeviceClient(connString, protocol);
MessageCallback callback = new AppMessageCallback();
client.setMessageCallback(callback, null);
client.open();
} catch (URISyntaxException ex) {
Logger.getLogger(Kafkareception.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static class AppMessageCallback implements MessageCallback {
public IotHubMessageResult execute(Message msg, Object context) {
System.out.println(new String(msg.getBytes(), Message.DEFAULT_IOTHUB_MESSAGE_CHARSET) + "Received message from hub: ");
return IotHubMessageResult.COMPLETE;
}
}
}
From information you provided, you may tried to setup two active connections of one device to Azure IoT Hub using DeviceClient: one is sending D2C messages and one is "reading data from iothub". You get the error maybe because:
IoT Hub only supports one active MQTT connection per device. Any new
MQTT connection on behalf of the same device ID causes IoT Hub to drop
the existing connection.
Ref:Communicate with your IoT hub using the MQTT protocol.
If you want to receive D2C message that sent to Azure IoT Hub you can use Event Hub-compatible endpoint(Java). No need to redirect the incoming messages to an event hub by yourself.
IoT Hub exposes the messages/events built-in endpoint for your
back-end services to read the device-to-cloud messages received by
your hub. This endpoint is Event Hub-compatible, which enables you to
use any of the mechanisms the Event Hubs service supports for reading
messages.
Ref: Understand Azure IoT Hub messaging and IoT Hub endpoints.
I read the data from iothub.We can use the code
import java.io.IOException;
import com.microsoft.azure.eventhubs.*;
import com.microsoft.azure.servicebus.*;
import java.nio.charset.Charset;
import java.time.*;
import java.util.function.*;
public class Datafetch {
public static void main(String[] args) throws IOException {
EventHubClient client0 = receiveMessages("0");
EventHubClient client1 = receiveMessages("1");
System.out.println("Press ENTER to exit.");
System.in.read();
try {
client0.closeSync();
client1.closeSync();
System.exit(0);
} catch (ServiceBusException sbe) {
System.exit(1);
}
}
private static EventHubClient receiveMessages(final String partitionId) {
String connStr = "Endpoint={youreventhubcompatibleendpoint};EntityPath={youreventhubcompatiblename};SharedAccessKeyName=iothubowner;SharedAccessKey={youriothubkey}";
EventHubClient client = null;
try {
client = EventHubClient.createFromConnectionStringSync(connStr);
} catch (Exception e) {
System.out.println("Failed to create client: " + e.getMessage());
System.exit(1);
}
try {
client.createReceiver(
EventHubClient.DEFAULT_CONSUMER_GROUP_NAME,
partitionId,
Instant.now()).thenAccept(new Consumer<PartitionReceiver>() {
public void accept(PartitionReceiver receiver) {
System.out.println("** Created receiver on partition " + partitionId);
try {
while (true) {
Iterable<EventData> receivedEvents = receiver.receive(100).get();
System.out.println(receivedEvents);
int batchSize = 0;
if (receivedEvents != null) {
for (EventData receivedEvent : receivedEvents) {
System.out.println(String.format("Offset: %s, SeqNo: %s, EnqueueTime: %s",
receivedEvent.getSystemProperties().getOffset(),
receivedEvent.getSystemProperties().getSequenceNumber(),
receivedEvent.getSystemProperties().getEnqueuedTime()));
System.out.println(String.format("| Device ID: %s", receivedEvent.getSystemProperties().getClass()));
System.out.println(String.format("| Message Payload: %s", new String(receivedEvent.getBody(),
Charset.defaultCharset())));
batchSize++;
}
}
System.out.println(String.format("Partition: %s, ReceivedBatch Size: %s", partitionId, batchSize));
}
} catch (Exception e) {
System.out.println("Failed to receive messages: " + e.getMessage());
}
}
});
} catch (Exception e) {
System.out.println("Failed to create receiver: " + e.getMessage());
}
return client;
}
}
I’m user of CXF in an SOA development context.
I’m wondering if my problem has a solution with CXF. Here’s my need.
We have developed a webapp serving JAXWS endpoints, the endpoint implementations consists in analyzing the request via interceptors, storing data from the request to a database from the service layer in Java, and resend the original request to another server via a CXF client.
The point is that some of our requests contains a DSIG signature (https://www.w3.org/TR/xmldsig-core/) or an signed SAML Assertion.
Our need is to resend the requests without altering them (such as a proxy) from a CXFClient. CXF uses to send the marshalled object to the server, but this way the original stream is not sent
Is there a way to resend the incoming request from the service layer from a Java CXFClient without altering it (the Signatures depends on the format of the request: blanks, namespaces prefixes, carriage returns…) ? We prefer the CXFClient because we would like to reuse our homemade CXF interceptor which logs the outgoing request.
We have tested an interceptor to intend to replace the outputStream by the original request before sending it to the server, we used this answer: How To Modify The Raw XML message of an Outbound CXF Request?, but we are still KO, CXF still sends the stream made from the marshalled object. See code below.
Context:
- CXF 2.7.18 (JDK 6), and 3.1.10 (JDK 8)
- Platform: windows 7 64bit/ rhel 7 64bit
- Apache Tomcat 7
- Tcpdump to analyse incoming traffic
Sample of code of our client:
final Client cxfClient = org.apache.cxf.frontend.ClientProxy.getClient( portType );
cxfClient.getInInterceptors().clear();
cxfClient.getOutInterceptors().clear();
cxfClient.getOutFaultInterceptors().clear();
cxfClient.getRequestContext().put(CustomStreamerInterceptor.STREAM_TO_SEND,
PhaseInterceptorChain.getCurrentMessage().getContent( InputStream.class ) );
cxfClient.getOutInterceptors().add( new CustomStreamerInterceptor() );
org.apache.cxf.transport.http.HTTPConduit http = (org.apache.cxf.transport.http.HTTPConduit) cxfClient.getConduit();
...
port.doSomething(someRequest);
CustomStreamerInterceptor:
package test;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor.SoapOutEndingInterceptor;
import org.apache.cxf.helpers.LoadingByteArrayOutputStream;
import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.io.CacheAndWriteOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.Phase;
public class CustomStreamerInterceptor extends AbstractOutDatabindingInterceptor {
public static final String STREAM_TO_SEND = "STREAM_TO_SEND";
public CustomStreamerInterceptor () {
super( Phase.WRITE_ENDING );
addAfter( SoapOutEndingInterceptor.class.getName() );
}
#Override
public void handleMessage( Message message ) throws Fault {
try {
InputStream toSend = (InputStream) message.get( STREAM_TO_SEND );
if ( toSend != null ) {
toSend.reset();
LoadingByteArrayOutputStream lBos = new LoadingByteArrayOutputStream();
IOUtils.copy( toSend, lBos );
CacheAndWriteOutputStream cawos = (CacheAndWriteOutputStream) message.getContent( OutputStream.class );
cawos.resetOut( lBos, false );//fail !
}
}
catch ( Exception e ) {
throw new Fault( e );
}
}
}
Thanks you for any help, it would be very usefull.
I think it's better to create a "classic" HTTP client because CXF is not designed for that kind of situation, it's more common to use it to marshal objects from java to XML...
Fortunately for you I deal with this problem with an interceptor. You can write an interceptor that copy the stream in the output stream object that CXF is preparing to send to the server. You need to be carefull to the phase and the order of you interceptors because if you use a Logging interceptor you may want to log the outgoing stream. This interceptor may do the job, be sure it runs after any logging interceptor. Code for CXF 2.7.18 :
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.lang.CharEncoding;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.interceptor.StaxOutInterceptor;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PassePlatClientInterceptorOut extends AbstractPhaseInterceptor<Message> {
private static final Logger LOG = LoggerFactory.getLogger( PassePlatClientInterceptorOut.class );
private final Exchange exchangeToReadFrom;
public PassePlatClientInterceptorOut( final Exchange exchange ) {
super( Phase.PRE_STREAM );
addBefore( StaxOutInterceptor.class.getName() );
this.exchangeToReadFrom = exchange;
}
#Override
public void handleMessage( Message message ) {
InputStream is = (InputStream) exchangeToReadFrom.get( PassePlatServerInterceptorIn.PASSE_PLAT_INTERCEPTOR_STREAM_SERVEUR );
if ( is != null ) {
message.put( org.apache.cxf.message.Message.ENCODING, CharEncoding.UTF_8 );
OutputStream os = message.getContent( OutputStream.class );
try {
IOUtils.copy( is, os );
is.close();
}
catch ( IOException e ) {
LOG.error( "Error ...", e );
message.setContent( Exception.class, e );
throw new Fault( new Exception( "Error ...", e ) );
}
boolean everythingOK = message.getInterceptorChain().doInterceptStartingAt( message,
org.apache.cxf.interceptor.MessageSenderInterceptor.MessageSenderEndingInterceptor.class.getName() );
if ( !everythingOK ) {
LOG.error( "Error ?" );
throw new Fault( new Exception( "Error ..." ) );
}
}
}
}
To create the interceptor:
cxfClient.getInInterceptors().add( new PassePlatClientInterceptorIn( exchange ) );
I have a java code that sends PDF files to printers.
Java code goes something like this:
import java.awt.print.PrinterJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.pdmodel.PDDocument;
public class PrintPdf {
protected final Log logger = LogFactory.getLog(getClass());
public void print(String pdfFile, String printer, int copies) throws Exception {
PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
PDDocument document = null;
try
{
document = PDDocument.load( pdfFile );
PrinterJob printJob = PrinterJob.getPrinterJob();
PrintService[] printServices = PrinterJob.lookupPrintServices();
PrintService myService = null;
if (printServices.length > 0)
{
for(PrintService service : printServices) {
if(service.getName().toLowerCase().contains(printer.toLowerCase())) {
myService = service;
break;
}
}
if (myService == null) {
throw new Exception("Printer not found " + printer);
} else {
logger.info("Printer found " + myService.getName());
}
} else {
throw new Exception("No print services found");
}
printJob.setPrintService(myService);
printJob.setCopies(copies);
document.silentPrint( printJob );
}
finally {
if( document != null ) {
document.close();
}
}
}
This java is called from batch file. I've scheduled a windows task to run the file every X minutes. Scheduled Task is run with a user that has admin rights. All this is run on a Windows 2003 server.
Printers are set up using a TCP/IP address.
The problem: When the user is logged in, the Task runs and can send PDF files to the printers.
When the user is not logged in, the Task runs but java returns an error:
java.awt.print.PrinterException: Invalid name of PrintService
Java program successfully lists available Print Services in the loop, just before the print command, but for some reason is not able to print the document while the user is not logged in.
Could anyone, please, give me some advice on what might be the problem here?
EDIT:
Exception occurs in the line:
printJob.setPrintService(myService);
The solution to this problem was to upgrade the existing java on the OS from version 6u45 to 7u21.
In my application (java) I need to support two types of RPCs:
Administration RPC and User RPC. I am using avro to create these RPCs, currently I am opening two HttpServers one per RPC using code similar to the following:
Server serverAdmins = new HttpServer(new ReflectResponder(AdministrationRPC.class, arpcImpl), adminRpcPort);
Server serverUsers = new HttpServer(new ReflectResponder(UsersRPC.class, urpcImpl), usersRpcPort);
...
This works, but it look like a waste for me - I am looking for a way to use a single http server with two ports or two urls on the same port (any of these options is good for me), something like:
Server server = new new HttpServer(new ReflectResponder(AdministrationRPC.class, arpcImpl), adminRpcPort);
server.addResponder(new ReflectResponder(UsersRPC.class, urpcImpl), usersRpcPort);
...
the addResponder method does not exists of course, the only method that looks similar is the addConnector method - but even after thorough googling I couldn't find how to apply it to my needs..
Is there a way to start two avro responders on the same http server?
I managed to resolve this issue by writing a simple class which allow for what I want, see code below.
import java.io.IOException;
import java.net.URL;
import org.apache.avro.ipc.HttpTransceiver;
import org.apache.avro.ipc.Responder;
import org.apache.avro.ipc.ResponderServlet;
import org.apache.avro.ipc.reflect.ReflectRequestor;
import org.apache.avro.ipc.reflect.ReflectResponder;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
/**
*
* #author bennyl
*/
public class MultiResponderHttpServer {
private final Context context;
private final Server server;
private final int port;
public MultiResponderHttpServer(int port) {
this.port = port;
server = new Server(port);
context = new Context(server, "/", Context.SESSIONS);
}
public void addResponder(String baseUri, Responder responder) throws IOException {
ResponderServlet servlet = new ResponderServlet(responder);
ServletHolder holder = new ServletHolder(servlet);
context.addServlet(holder, baseUri);
}
public int getPort() {
return port;
}
public void close() throws Exception {
server.stop();
}
public void start() throws Exception {
server.start();
}
public void join() throws InterruptedException {
server.join();
}
public static void main(String[] args) throws IOException, InterruptedException {
MultiResponderHttpServer server = new MultiResponderHttpServer(8888);
server.addResponder("/test_a/*", new ReflectResponder(TestProtocol.class,
(TestProtocol) why -> "a received a message: '" + why + "'"));
server.addResponder("/test_b/*", new ReflectResponder(TestProtocol.class,
(TestProtocol) why -> "b received a message: '" + why + "'"));
server.start();
HttpTransceiver atrans = new HttpTransceiver(new URL("http://localhost:" + server.getPort() + "/test_a/"));
HttpTransceiver btrans = new HttpTransceiver(new URL("http://localhost:" + server.getPort() + "/test_b/"));
System.out.println(ReflectRequestor.getClient(TestProtocol.class, atrans).go("message to a"));
System.out.println(ReflectRequestor.getClient(TestProtocol.class, btrans).go("message to b"));
server.close();
server.join();
}
public interface TestProtocol {
String go(String why);
}
}