My question is how can i upload the attachment in flow test to make this test successful.
This is the test that im doing in trader-demo flowtest
private fun issue_commercial_paper( amount: Amount<Currency>,
issueRef: OpaqueBytes,
recipient: Party,
notary: Party,
progressTracker: ProgressTracker): SignedTransaction {
val p = CommercialPaperIssueFlow(amount,issueRef,recipient,notary,progressTracker)
val future = BankCorpNode.services.startFlow(p)
mockNet.runNetwork()
return future.resultFuture.getOrThrow()
}
#Test
fun `trade issuance`(){
issue_commercial_paper(1000.DOLLARS,OpaqueBytes.of(42.toByte()),ACorp,notary,CommercialPaperIssueFlow.tracker())
val pass = SellerFlow(BCorp ,500.DOLLARS, SellerFlow.tracker() )
val future = ACorpNode.services.startFlow(pass)
mockNet.runNetwork()
val results = future.resultFuture.getOrThrow()
assertNotNull(results)
}
This is the error
kotlin.KotlinNullPointerException
at net.corda.traderdemo.flow.CommercialPaperIssueFlow.call(CommercialPaperIssueFlow.kt:54)
at net.corda.traderdemo.flow.CommercialPaperIssueFlow.call(CommercialPaperIssueFlow.kt:25)
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:96)
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:44)
at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63)
you can refer to this sample to see if you can help me guys thanks in advance
https://github.com/corda/corda/tree/c4ceca378762fe1959f075a1c8b1c301e411b6b8/samples/trader-demo
Suppose your attachment is under main/resources/my-attachment.jar. Within a Java flow test, you upload this attachment to the node as follows:
nodeA.transaction(() -> {
InputStream attachmentStream = getClass().getClassLoader().getResourceAsStream("my-attachment.jar");
try {
nodeA.getServices().getAttachments().importAttachment(attachmentStream, "joel", "myAttachment");
} catch (IOException e) {
e.printStackTrace();
}
// The attachment is now uploaded to the node.
// TODO: Remainder of the test.
return null;
});
Or in Kotlin:
nodeA.transaction {
val attachmentStream = javaClass.classLoader.getResourceAsStream("my-attachment.jar")
nodeA.services.attachments.importAttachment(attachmentStream, "joel", "myAttachment")
// The attachment is now uploaded to the node.
// TODO: Remainder of the test.
}
Related
Here I have a method where fetchReport is an external call to a vendor API. I want to copy that data to Azure Blob Storage but not if There was an error. If there was an error then I want to return the CustomResponse with the error details. writeToBlob() also returns a CustomResponse. I want to be able to preserve the error message from the external API to give to the consumer.
Is there any way I can use some conditional logic like
if response.contains("Failed") -> then return response with error details
else -> write to blob
public Flux<CustomResponse> getAndSaveReport(Mono<JsonNode> fetchReport, String reportFilePrefix) {
Mono<JsonNode> reportMono = fetchReport
.doOnSuccess(result -> {
log.info(Logger.EVENT_UNSPECIFIED, "Successfully retrieved report");
})
.switchIfEmpty(Mono.just(objectMapper.convertValue(new CustomResponse("No content"), JsonNode.class)))
.onErrorResume(BusinessException.class, err -> {
log.error(Logger.EVENT_FAILURE, "Failed to retrieve report");
JsonNode errJson = null;
CustomResponse apiResponse = new CustomResponse();
apiResponse.setStatus("Failed");
apiResponse.setMessage("Error message: " + err.getMessage());
apiResponse.setType(reportFilePrefix);
errJson = objectMapper.convertValue(apiResponse, JsonNode.class);
return Mono.just(errJson);
});
return writeToBlob(reportMono.flux(), reportFilePrefix).flux();
}
Any help would be appreciated!
Not sure what fetchReport returns but the code could be simplified by applying flatMap. Also, not sure why are you using flux() everywhere when only one signal is passed - you can use Mono instead.
public Mono<CustomResponse> getAndSaveReport(Mono<JsonNode> fetchReport, String reportFilePrefix) {
return fetchReport
.flatMap(result -> {
if (result.response.contains("Failed")) {
// error handling
return Mono.just(errorResponse);
} else {
return writeToBlob(result.report, reportFilePrefix)
}
});
}
I have a Spring Boot project that is leveraging Spring Integration. My goal is to to poll a POP3 mail server regularly, and download any attachments associated with those messages. My relevant Spring Config looks like this:
#Configuration
public class MailIntegrationConfig {
#Value("${path.output.temp}")
private String outPath;
#Bean
public MessageChannel mailChannel() {
return new DirectChannel();
}
#Bean
#InboundChannelAdapter(value = "mailChannel", poller = #Poller(fixedDelay = "16000"))
public MessageSource<Object> fileReadingMessageSource() {
var receiver = new Pop3MailReceiver("pop3s://user:passwordexample.com/INBOX");
var mailProperties = new Properties();
mailProperties.setProperty("mail.pop3.port", "995");
mailProperties.put("mail.pop3.ssl.enable", true);
receiver.setShouldDeleteMessages(false);
receiver.setMaxFetchSize(10);
receiver.setJavaMailProperties(mailProperties);
// receiver.setHeaderMapper(new DefaultMailHeaderMapper());
var source = new MailReceivingMessageSource(receiver);
return source;
}
#Bean
#ServiceActivator(inputChannel = "mailChannel")
public MessageHandler popMessageHandler() {
return new MailReceivingMessageHandler(outPath);
}
}
My MailReceivingMessageHandler class (partial)
public class MailReceivingMessageHandler extends AbstractMessageHandler {
private String outDir;
public MailReceivingMessageHandler(String outDir) {
var outPath = new File(outDir);
if (!outPath.exists()) {
throw new IllegalArgumentException(String.format("%s does not exist.", outDir));
}
this.outDir = outDir;
}
#Override
protected void handleMessageInternal(org.springframework.messaging.Message<?> message) {
Object payload = message.getPayload();
if (!(payload instanceof Message)) {
throw new IllegalArgumentException(
"Unable to create MailMessage from payload type [" + message.getPayload().getClass().getName()
+ "], " + "expected MimeMessage, MailMessage, byte array or String.");
}
try {
var msg = (Message) payload;
System.out.println(String.format("Headers [%s] Subject [%s]. Content-Type [%s].", msg.getAllHeaders(),
msg.getSubject(), msg.getContentType()));
this.handleMessage(msg);
} catch (IOException | MessagingException e) {
e.printStackTrace();
}
}
private void handleMessage(Message msg) throws MessagingException, IOException {
var cType = msg.getContentType();
if (cType.contains(MediaType.TEXT_PLAIN_VALUE)) {
handleText((String) msg.getContent());
} else if (cType.contains(MediaType.MULTIPART_MIXED_VALUE)) {
handleMultipart((Multipart) msg.getContent());
}
}
// See
// https://stackoverflow.com/questions/1748183/download-attachments-using-java-mail
private void handleMultipart(Multipart msgContent) throws MessagingException, IOException {
var mCount = msgContent.getCount();
for (var i = 0; i < mCount; i++) {
this.processAttachments(msgContent.getBodyPart(i));
}
}
private void processAttachments(BodyPart part) throws IOException, MessagingException {
var content = part.getContent();
if (content instanceof InputStream || content instanceof String) {
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) || !part.getFileName().isBlank()) {
var fName = String.format("%s.%s", UUID.randomUUID().toString(),
FilenameUtils.getExtension(part.getFileName()));
FileUtils.copyInputStreamToFile(part.getInputStream(), new File(outDir + File.separator + fName));
}
if (content instanceof Multipart) {
Multipart multipart = (Multipart) content;
for (int i = 0; i < multipart.getCount(); i++) {
var bodyPart = multipart.getBodyPart(i);
processAttachments(bodyPart);
}
}
}
}
}
Whenever I run my code using the config above, I receive the following error:
javax.mail.MessagingException: No inputstream from datasource;
nested exception is:
java.lang.IllegalStateException: Folder is not Open
at javax.mail.internet.MimeMultipart.parse(MimeMultipart.java:576)
at javax.mail.internet.MimeMultipart.getCount(MimeMultipart.java:312)
at com.midamcorp.data.mail.MailReceivingMessageHandler.handleMultipart(MailReceivingMessageHandler.java:70)
at com.midamcorp.data.mail.MailReceivingMessageHandler.handleMessage(MailReceivingMessageHandler.java:58)
at com.midamcorp.data.mail.MailReceivingMessageHandler.handleMessageInternal(MailReceivingMessageHandler.java:44)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:62)
at org.springframework.integration.handler.ReplyProducingMessageHandlerWrapper.handleRequestMessage(ReplyProducingMessageHandlerWrapper.java:58)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:134)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:62)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:72)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:570)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:520)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
at org.springframework.integration.endpoint.SourcePollingChannelAdapter.handleMessage(SourcePollingChannelAdapter.java:196)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.messageReceived(AbstractPollingEndpoint.java:444)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:428)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.pollForMessage(AbstractPollingEndpoint.java:376)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.lambda$null$3(AbstractPollingEndpoint.java:323)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.lambda$execute$0(ErrorHandlingTaskExecutor.java:57)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:55)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.lambda$createPoller$4(AbstractPollingEndpoint.java:320)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalStateException: Folder is not Open
at com.sun.mail.pop3.POP3Folder.checkOpen(POP3Folder.java:562)
at com.sun.mail.pop3.POP3Folder.getProtocol(POP3Folder.java:592)
at com.sun.mail.pop3.POP3Message.getRawStream(POP3Message.java:154)
at com.sun.mail.pop3.POP3Message.getContentStream(POP3Message.java:251)
at javax.mail.internet.MimePartDataSource.getInputStream(MimePartDataSource.java:78)
at javax.mail.internet.MimeMultipart.parse(MimeMultipart.java:570)
... 35 more
Obviously, the root cause is clear - the POP3 folder is closed. I have seen solutions that would likely be able to handle when just the Java mail classes are used, but none with Spring Integration. My question is how does one properly control when a folder is open or closed using Spring Integration Mail? I realize the Pop3MailReceiver class has a .setAutoCloseFolder() method. Based on the Spring Docs, I assume I need to set that, along something like the following to my handler:
Closeable closeableResource = StaticMessageHeaderAccessor.getCloseableResource(message);
if (closeableResource != null) {
closeableResource.close();
}
However, if I set autoCloseFolder to false, it does not appear as if the message even ever "hits" my handler, so unfortunately being able to close the resource does not even matter at this point. That is, when autoClose is set to false, the 'handleMessageInternal()' method in my handler class is never reached even though there are indeed message on the POP3 server. Instead I just get a bunch of logs like this:
2020-06-26 15:26:54.523 INFO 15348 --- [ scheduling-1] o.s.integration.mail.Pop3MailReceiver : attempting to receive mail from folder [INBOX]
What am I missing?
Thanks.
We are building a Graylog output plugin to send data to Google PubSub. This is the code we have written, inspired from the boilerplate code provided by google pubsub (this and this)
try (InputStream credential = new FileInputStream(Objects.requireNonNull(config.getString(CK_CREDENTIAL_FILE)))) {
CredentialsProvider credentialsProvider = FixedCredentialsProvider
.create(ServiceAccountCredentials.fromStream(credential));
// endpoint can be set here
publisher = Publisher.newBuilder(topicName).setCredentialsProvider(credentialsProvider).build();
ByteString finalData = ByteString.copyFromUtf8(String.valueOf(obj));
PubsubMessage pubsubMessage = PubsubMessage.newBuilder()
.setData(finalData)
.build();
ApiFuture<String> future = publisher.publish(pubsubMessage);
messageIdFutures.add(future);
ApiFutures.addCallback(
future,
new ApiFutureCallback<String>() {
#Override
public void onFailure(Throwable throwable) {
if (throwable instanceof ApiException) {
ApiException apiException = ((ApiException) throwable);
// details on the API exception
System.out.println(apiException.getStatusCode().getCode());
System.out.println(apiException.isRetryable());
}
System.out.println("Error publishing message : " + String.valueOf(obj));
}
#Override
public void onSuccess(String messageId) {
// Once published, returns server-assigned message ids (unique within the topic)
System.out.println(messageId);
}
},
MoreExecutors.directExecutor());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (publisher != null) {
try {
try {
publisher.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
publisher.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
On running, we get the following error stack:-
java.util.concurrent.ExecutionException: java.lang.IllegalAccessError: tried to access field io.opencensus.trace.unsafe.
ContextUtils.CONTEXT_SPAN_KEY from class io.grpc.internal.CensusTracingModule$TracingClientInterceptor
at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:526)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:423)
at com.google.common.util.concurrent.AbstractFuture$TrustedFuture.get(AbstractFuture.java:90)
at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:68)
at org.plugin.PubSubOutput.writeBuffer(PubSubOutput.java:159)
at org.plugin.PubSubOutput.write(PubSubOutput.java:85)
at org.graylog2.buffers.processors.OutputBufferProcessor$1.run(OutputBufferProcessor.java:191)
at com.codahale.metrics.InstrumentedExecutorService$InstrumentedRunnable.run(InstrumentedExecutorService.java:18
1)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
ERROR [AggregateFuture] - Input Future failed with Error - {}
java.lang.IllegalAccessError: tried to access field io.opencensus.trace.unsafe.ContextUtils.CONTEXT_SPAN_KEY from class
io.grpc.internal.CensusTracingModule$TracingClientInterceptor
at io.grpc.internal.CensusTracingModule$TracingClientInterceptor.interceptCall(CensusTracingModule.java:384) ~[g
raylog-plugin-pubsub-output-1.0.0-SNAPSHOT.jar:?]
at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:156) ~[graylog-plugin-pubsub-ou
tput-1.0.0-SNAPSHOT.jar:?]
at io.grpc.internal.CensusStatsModule$StatsClientInterceptor.interceptCall(CensusStatsModule.java:685) ~[graylog
-plugin-pubsub-output-1.0.0-SNAPSHOT.jar:?]
at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:156) ~[graylog-plugin-pubsub-ou
tput-1.0.0-SNAPSHOT.jar:?]
at com.google.api.gax.grpc.GrpcHeaderInterceptor.interceptCall(GrpcHeaderInterceptor.java:81) ~[graylog-plugin-p
ubsub-output-1.0.0-SNAPSHOT.jar:?]
at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:156) ~[graylog-plugin-pubsub-ou
tput-1.0.0-SNAPSHOT.jar:?]
at com.google.api.gax.grpc.GrpcMetadataHandlerInterceptor.interceptCall(GrpcMetadataHandlerInterceptor.java:55)
~[graylog-plugin-pubsub-output-1.0.0-SNAPSHOT.jar:?]
at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:156) ~[graylog-plugin-pubsub-ou
tput-1.0.0-SNAPSHOT.jar:?]
at io.grpc.internal.ManagedChannelImpl.newCall(ManagedChannelImpl.java:766) ~[graylog-plugin-pubsub-output-1.0.0
-SNAPSHOT.jar:?]
at io.grpc.internal.ForwardingManagedChannel.newCall(ForwardingManagedChannel.java:63) ~[graylog-plugin-pubsub-o
utput-1.0.0-SNAPSHOT.jar:?]
at com.google.api.gax.grpc.ChannelPool.newCall(ChannelPool.java:77) ~[graylog-plugin-pubsub-output-1.0.0-SNAPSHO
T.jar:?]
at com.google.api.gax.grpc.GrpcClientCalls.newCall(GrpcClientCalls.java:88) ~[graylog-plugin-pubsub-output-1.0.0
-SNAPSHOT.jar:?]
at com.google.api.gax.grpc.GrpcDirectCallable.futureCall(GrpcDirectCallable.java:58) ~[graylog-plugin-pubsub-out
put-1.0.0-SNAPSHOT.jar:?]
at com.google.api.gax.grpc.GrpcExceptionCallable.futureCall(GrpcExceptionCallable.java:64) ~[graylog-plugin-pubs
ub-output-1.0.0-SNAPSHOT.jar:?]
at com.google.api.gax.rpc.AttemptCallable.call(AttemptCallable.java:81) ~[graylog-plugin-pubsub-output-1.0.0-SNA
PSHOT.jar:?]
at com.google.api.gax.rpc.RetryingCallable.futureCall(RetryingCallable.java:63) ~[graylog-plugin-pubsub-output-1
.0.0-SNAPSHOT.jar:?]
at com.google.api.gax.rpc.RetryingCallable.futureCall(RetryingCallable.java:41) ~[graylog-plugin-pubsub-output-1
.0.0-SNAPSHOT.jar:?]
at com.google.api.gax.rpc.BatchingCallable.futureCall(BatchingCallable.java:79) ~[graylog-plugin-pubsub-output-1
.0.0-SNAPSHOT.jar:?]
at com.google.api.gax.rpc.UnaryCallable$1.futureCall(UnaryCallable.java:126) ~[graylog-plugin-pubsub-output-1.0.
0-SNAPSHOT.jar:?]
at com.google.api.gax.rpc.UnaryCallable.futureCall(UnaryCallable.java:87) ~[graylog-plugin-pubsub-output-1.0.0-S
NAPSHOT.jar:?]
at com.google.cloud.pubsub.v1.Publisher.publishOutstandingBatch(Publisher.java:317) [graylog-plugin-pubsub-outpu
t-1.0.0-SNAPSHOT.jar:?]
at com.google.cloud.pubsub.v1.Publisher.publishAllOutstanding(Publisher.java:306) [graylog-plugin-pubsub-output-
1.0.0-SNAPSHOT.jar:?]
at com.google.cloud.pubsub.v1.Publisher$3.run(Publisher.java:280) [graylog-plugin-pubsub-output-1.0.0-SNAPSHOT.j
ar:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_222]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_222]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.j
ava:180) [?:1.8.0_222]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293
) [?:1.8.0_222]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_222]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_222]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_222]
Caused by: java.lang.IllegalAccessError: tried to access field io.opencensus.trace.unsafe.ContextUtils.CONTEXT_SPAN_KEY
from class io.grpc.internal.CensusTracingModule$TracingClientInterceptor
at io.grpc.internal.CensusTracingModule$TracingClientInterceptor.interceptCall(CensusTracingModule.java:384)
at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:156)
at io.grpc.internal.CensusStatsModule$StatsClientInterceptor.interceptCall(CensusStatsModule.java:685)
at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:156)
at com.google.api.gax.grpc.GrpcHeaderInterceptor.interceptCall(GrpcHeaderInterceptor.java:81)
at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:156)
at com.google.api.gax.grpc.GrpcMetadataHandlerInterceptor.interceptCall(GrpcMetadataHandlerInterceptor.java:55)
at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:156)
at io.grpc.internal.ManagedChannelImpl.newCall(ManagedChannelImpl.java:766)
at io.grpc.internal.ForwardingManagedChannel.newCall(ForwardingManagedChannel.java:63)
at com.google.api.gax.grpc.ChannelPool.newCall(ChannelPool.java:77)
at com.google.api.gax.grpc.GrpcClientCalls.newCall(GrpcClientCalls.java:88)
at com.google.api.gax.grpc.GrpcDirectCallable.futureCall(GrpcDirectCallable.java:58)
at com.google.api.gax.grpc.GrpcExceptionCallable.futureCall(GrpcExceptionCallable.java:64)
at com.google.api.gax.rpc.AttemptCallable.call(AttemptCallable.java:81)
at com.google.api.gax.rpc.RetryingCallable.futureCall(RetryingCallable.java:63)
at com.google.api.gax.rpc.RetryingCallable.futureCall(RetryingCallable.java:41)
at com.google.api.gax.rpc.BatchingCallable.futureCall(BatchingCallable.java:79)
at com.google.api.gax.rpc.UnaryCallable$1.futureCall(UnaryCallable.java:126)
at com.google.api.gax.rpc.UnaryCallable.futureCall(UnaryCallable.java:87)
at com.google.cloud.pubsub.v1.Publisher.publishOutstandingBatch(Publisher.java:317)
at com.google.cloud.pubsub.v1.Publisher.publishAllOutstanding(Publisher.java:306)
at com.google.cloud.pubsub.v1.Publisher$3.run(Publisher.java:280)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.j
ava:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293
)
We have even looked at the grpc-java github repo but can't seem to figure out the problem. We are not using grpc in our communication but we think that it is being used by the google pubsub java module internally.
Any help would be highly appreciated. Thanks in advance.
I had the same issue,
My app is developped with scala (with sbt), but it's the same with maven.
To solve the issue I change my dependencies with :
libraryDependencies += "com.google.cloud" % "google-cloud-pubsub" % "1.75.0"
libraryDependencies += "com.google.api-client" % "google-api-client" % "1.30.5"
libraryDependencies += "com.google.cloud" % "google-cloud-core-grpc" % "1.91.3"
For the code, just keep default way to create google credential object :
def publishMessages(projectId : String, topic : String, event : String): Unit = {
val topicName = ProjectTopicName.of(projectId, topic)
var publisher : Publisher = null
val messageIdFutures = new util.ArrayList[ApiFuture[String]]
try {
val credentials = GoogleCredentials.fromStream(new FileInputStream(creds)).createScoped(
java.util.Arrays.asList("https://www.googleapis.com/auth/cloud-platform")
)
publisher = Publisher.newBuilder(topicName)
.setCredentialsProvider(FixedCredentialsProvider.create(credentials)).build
val payload = ByteString.copyFromUtf8(event)
val pubsubMessage = PubsubMessage.newBuilder.setData(payload).build
val messageIdFuture = publisher.publish(pubsubMessage)
messageIdFutures.add(messageIdFuture)
}
I have the following code:
typealias MessagePredicate = (Message) -> Boolean
object EmailHelper {
private val session: Session by lazy {
val props = System.getProperties()
props["mail.imaps.usesocketchannels"] = "true"
props["mail.imap.usesocketchannels"] = "true"
Session.getInstance(props, null)
}
private val store = session.getStore("gimap") as GmailStore
private val idleManager = IdleManager(session, Executors.newSingleThreadExecutor())
private val folder: GmailFolder by lazy { store.getFolder("INBOX") as GmailFolder }
init {
store.connect("imap.gmail.com", "***#gmail.com", "***")
folder.open(Folder.READ_ONLY)
idleManager.watch(folder)
}
fun watchForMessage(condition: MessagePredicate): CompletableFuture<Message> {
val promise = CompletableFuture<Message>()
folder.addMessageCountListener(object : MessageCountAdapter() {
override fun messagesAdded(e: MessageCountEvent) {
super.messagesAdded(e)
e.messages.firstOrNull(condition)?.let {
folder.removeMessageCountListener(this)
promise.complete(it)
}
}
})
return promise
}
}
However when I run this code I'm getting the following exception:
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.muliyul.MainKt.main(Main.kt:28)
Caused by: javax.mail.MessagingException: Folder is not using SocketChannels
at com.sun.mail.imap.IdleManager.watch(IdleManager.java:205)
at com.muliyul.EmailHelper.<clinit>(EmailHelper.kt:40)
... 1 more
I am setting the property "mail.imaps.usesocketchannels" beforehand and I've also read this question yet I can't wrap my head around what's wrong with my code.
Can someone point me in the right direction?
Side note: the email provider is Gmail (obviously).
An hour after I posted this question (and 3 hours of researching) I finally found an answer.
You have to set the property mail.gimap.usesocketchannels to "true" (and not mail.imap.usesocketchannels or mail.imaps.usesocketchannels)
This is due to the fact that gimap is a different protocol than imap.
There goes 3 hours down the drain.
I am brand new to Vertx and trying to create my first HTTP Rest Server. However, I have been running into this issue. Here is the error I'm getting when I try to send a response.
Jan 07, 2017 3:54:36 AM io.vertx.ext.web.impl.RoutingContextImplBase
SEVERE: Unexpected exception in route
java.lang.IllegalStateException: Response has already been written
at io.vertx.core.http.impl.HttpServerResponseImpl.checkWritten(HttpServerResponseImpl.java:559)
at io.vertx.core.http.impl.HttpServerResponseImpl.putHeader(HttpServerResponseImpl.java:156)
at io.vertx.core.http.impl.HttpServerResponseImpl.putHeader(HttpServerResponseImpl.java:54)
at com.themolecule.utils.Response.sendResponse(Response.kt:25)
at com.themolecule.api.UserAPI.addUser(UserAPI.kt:52)
at TheMoleculeAPI$main$3.handle(TheMoleculeAPI.kt:50)
at TheMoleculeAPI$main$3.handle(TheMoleculeAPI.kt:19)
at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:215)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:78)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:94)
at io.vertx.ext.web.handler.impl.AuthHandlerImpl.authorise(AuthHandlerImpl.java:86)
at
And this is how I have set up my routes.
// setup verx
val vertx = Vertx.vertx()
val router = Router.router(vertx)
val allowHeaders = HashSet<String>()
allowHeaders.add("x-requested-with")
allowHeaders.add("Access-Control-Allow-Origin")
allowHeaders.add("origin")
allowHeaders.add("Content-Type")
allowHeaders.add("accept")
val allowMethods = HashSet<HttpMethod>()
allowMethods.add(HttpMethod.GET)
allowMethods.add(HttpMethod.POST)
allowMethods.add(HttpMethod.DELETE)
allowMethods.add(HttpMethod.PATCH)
router.route().handler(CorsHandler.create("*")
.allowedHeaders(allowHeaders)
.allowedMethods(allowMethods))
router.route().handler(BodyHandler.create())
val config = JsonObject().put("keyStore", JsonObject()
.put("path", "keystore.jceks")
.put("type", "jceks")
.put("password", "password"))
// protect the API, login outside of JWT
router.route("/them/*").handler(JWTAuthHandler.create(jwt, "/them/login"))
//login routes
router.post("/them/login").handler { it -> loginAPI.login(it, jwt) }
//user routes
router.get("/them/user/getusers").handler { it -> userAPI.getUsers(it) }
router.post("/them/user/addUser").handler { it -> userAPI.addUser(it) }
This is the code that it seems to have the problem with.
fun sendResponse(responseCode: Int, responseMsg: String, context: RoutingContext) {
val userResponse = JsonObject().put("response", responseMsg)
context
.response()
.putHeader("content-type", "application/json")
.setStatusCode(responseCode)
.end(userResponse.encodePrettily())
}
Am I doing something wrong with the handlers? I tried to change the method for the response up a bunch of times, but nothing seems to work. This is written in Kotlin. If I need to add more context, just say the word!
edit: addUser method added
fun addUser(context: RoutingContext) {
val request = context.bodyAsJson
val newUser = NewUserRequestDTO(request.getString("userID").trim(), request.getString("password").trim())
newUser.userID.trim()
if (!newUser.userID.isNullOrEmpty() && !newUser.password.isNullOrEmpty()) {
//check user ID
if (userDAO.userIdInUse(newUser.userID)) {
Response.sendResponse(400, Response.ResponseMessage.ID_IN_USE.message, context)
return
}
//check password valid
val isValid: Boolean = SecurityUtils.checkPasswordCompliance(newUser.password)
if (!isValid) {
Response.sendResponse(400, Response.ResponseMessage.PASSWORD_IS_NOT_VALID.message, context)
return
}
val saltedPass = SecurityUtils.genSaltedPasswordAndSalt(newUser.password)
userDAO.addUser(newUser.userID, saltedPass.salt.toString(), saltedPass.pwdDigest.toString())
} else {
Response.sendResponse(401, Response.ResponseMessage.NO_USERNAME_OR_PASSWORD.message, context)
return
}
Response.sendResponse(200, Response.ResponseMessage.USER_CREATED_SUCCESSFULLY.message, context)
}