I'm having a problem I don't seem to find a solution for, and it looks really odd given i've tried everything I could with the official Spring Data Couchbase documentation.
Basically all i'm trying to do is a simple count() method.
My Repository :
public interface ICourrierRepository extends CrudRepository<Courrier, String> {
List<Courrier> findByCategorie(String categorie);
Long countByCategorie(String categorie);
#View(designDocument = "_design/courrier", viewName = "courrierBase")
long count();
}
The view is setup like this : http://img15.hostingpics.net/pics/169793Capture.png
And the view map is like this :
function (doc, meta) {
if (doc._class == "com.model.Courrier") {
emit(meta.id, null);
}
}
Worst thing is it actually works when i set a "reduce" to "_count" in the CouchBase GUI, but when I launch it from my client, I always get the same message, and the return is 0 :
[cb-computations-2] INFO c.c.c.java.view.ViewRetryHandler - Received a View HTTP response code (400) I did not expect, not retrying.
Thanks for any help...
I actually found the problem... it comes from this line :
#View(designDocument = "_design/courrier", viewName = "courrierBase")
which should be
#View(designDocument = "courrier", viewName = "courrierBase")
Also, the view should be set to reduce : _count.
Hope this helps future users !
Related
private fun shareOperation(file: File) {
val uri = Uri.fromFile(file)
val storage = FirebaseStorage.getInstance()
val pdfRef = storage.reference.child("pdf/${uri.lastPathSegment}")
pdfRef.putFile(uri).addOnFailureListener { e ->
Log.e(TAG, "Couldn't share " + e.message)
}.addOnCompleteListener{
it.addOnCompleteListener {
pdfRef.downloadUrl.addOnSuccessListener { e ->
run {
link = e.toString()
Log.i(TAG,link!!) // Here i get the link to file in firebase storage
}
}
}
}
// Here link gets null
}
i was expecting somehow i can get the link to the file and can use it for sharing intent
You are performing an asynchronous call to upload the file, that is correct since any UI blocking action must be performed in background. The variable link will be null until the run code is executed in the background thread.
You need to code inside the run block whatever you want to happen when the link is available.
BTW looks weird what you are doing with the nested addOnCompleteListener, there should be an easier way to code that. You should probably spend time learning how to code with listeners and background threads.
I have declared a mail listener with Spring Integration like this:
#Bean
public IntegrationFlow mailListener() {
return IntegrationFlows.from(
Mail.imapIdleAdapter(getUrl())
.searchTermStrategy((s, f) -> new FlagTerm(new Flags(Flags.Flag.SEEN), false))
.shouldMarkMessagesAsRead(true)
.shouldDeleteMessages(false)
.get())
.<Message>handle((payload, header) -> handle(payload)).get();
}
In my test mail account I have a few 'unread' and a few 'read' messages. Starting the application I see in the logs that the listener fetches all of the 'unread' messages over and over again without ever marking them as 'read'.
Given that I specified shouldMarkMessagesAsRead(true) I would expect the Adapter to mark a message as read after fetching it.
Am I understanding and/or doing something wrong?
Thanks to Artem Bilan's hint on activating debug output I found out that the mailbox was opened in read-only mode.
And thanks to Gary Russell's answer to another question I tried removing the .get() call on the ImapIdleChannelAdapterSpec:
#Bean
public IntegrationFlow mailListener() {
return IntegrationFlows.from(
Mail.imapIdleAdapter(getUrl())
.shouldMarkMessagesAsRead(true)
.shouldDeleteMessages(false))
.<Message>handle((payload, header) -> handle(payload)).get();
}
Now the mailbox gets opened in read-write mode and marking the messages with the SEEN flag works fine.
I also don't actually need the custom SearchTermStrategy now as Artem Bilan already suggested.
In this type of situations we recommend to set:
.javaMailProperties(p -> p.put("mail.debug", "true"))
on that Mail.imapIdleAdapter().
Probably your e-mail server really does not support that \seen flag, so the message is marked as read via some other flag.
So, with that mail debugging option you should see some interesting info in your logs.
The logic in our default DefaultSearchTermStrategy is like this around that Flags.Flag.SEEN :
if (supportedFlags.contains(Flags.Flag.SEEN)) {
NotTerm notSeen = new NotTerm(new FlagTerm(new Flags(Flags.Flag.SEEN), true));
if (searchTerm == null) {
searchTerm = notSeen;
}
else {
searchTerm = new AndTerm(searchTerm, notSeen);
}
}
See if you really need a custom strategy and why a default one is not enough for you: https://docs.spring.io/spring-integration/docs/current/reference/html/mail.html#search-term
I am working on a solution where I am using vertx 3.8.4 and vertx-mysql-client 3.9.0 for asynchronous database calls.
Here is the scenario that I have been trying to resolve, in a proper reactive manner.
I have some mastertable records which are in inactive state.
I run a query and get the list of records from the database.
This I did like this :
Future<List<Master>> locationMasters = getInactiveMasterTableRecords ();
locationMasters.onSuccess (locationMasterList -> {
if (locationMasterList.size () > 0) {
uploadTargetingDataForAllInactiveLocations(vertx, amazonS3Utility,
locationMasterList);
}
});
Now in uploadTargetingDataForAllInactiveLocations method, i have a list of items.
What I have to do is, I need to iterate over this list, for each item, I need to download a file from aws, parse the file and insert those data to db.
I understand the way to do it using CompositeFuture.
Can someone from vertx dev community help me with this or with some documentation available ?
I did not find good contents on this by googling.
I'm answering this as I was searching for something similar and I ended up spending some time before finding an answer and hopefully this might be useful to someone else in future.
I believe you want to use CompositeFuture in vertx only if you want to synchronize multiple actions. That means that you either want an action to execute in the case that either all your other actions on which your composite future is built upon succeed or at least one of the action on which your composite future is built upon succeed.
In the first case I would use CompositeFuture.all(List<Future> futures) and in the second case I would use CompositeFuture.any(List<Future> futures).
As per your question, below is a sample code where a list of item, for each item we run an asynchronous operation (namely downloadAnProcessFile()) which returns a Future and we want to execute an action doAction() in the case that all the async actions succeeded:
List<Future> futures = new ArrayList<>();
locationMasterList.forEach(elem -> {
Promise<Void> promise = Promise.promise();
futures.add(promise.future());
Future<Boolean> processStatus = downloadAndProcessFile(); // doesn't need to be boolean
processStatus.onComplete(asyncProcessStatus -> {
if (asyncProcessStatus.succeeded()){
// eventually do stuff with the result
promise.complete();
} else {
promise.fail("Error while processing file whatever");
}
});
});
CompositeFuture.all(futures).onComplete(compositeAsync -> {
if (compositeAsync.succeeded()){
doAction(); // <-- here do what you want to do when all future complete
} else {
// at least 1 future failed
}
});
This solution is probably not perfect and I suppose can be improved but this is what I found works for me. Hopefully will work for someone else.
I'm finding this incredibly frustrating. I'm trying to use the InventoryFacadeClient to call either the Change or Sync web services to update product availability. The issue I'm facing is that I can't seem to instantiate all of the required DataTypes to populate the request.
It's quite confusing, I wanted to call ChangeInventory but can't compose the request, and started down SyncProductAvailability but again, can't compose the request.
The problem below is that the ProductIdentifierType is null, and there's no corresponding "createProductIdentifierType" on the Factory....I'm not sure what I"m missing here, the factory seems to be half baked...
If someone can help me complete this code, it would be great?
public void setUp() throws Exception {
String METHOD_NAME = "setUp";
logger.info("{} entering", METHOD_NAME);
super.setUp();
InventoryFacadeClient iClient = super.initializeInventoryClient(false);
InventoryFactory f = com.ibm.commerce.inventory.datatypes.InventoryFactory.eINSTANCE;
com.ibm.commerce.inventory.facade.datatypes.InventoryFactory cf = iClient.getInventoryFactory();
CommerceFoundationFactory fd = iClient.getCommerceFoundationFactory();
// we must have customised the SyncProductAvailability web service to
// handle ATP inventory model.
SyncProductAvailabilityDataAreaType dataArea = f.createSyncProductAvailabilityDataAreaType();
SyncProductAvailabilityType sat = f.createSyncProductAvailabilityType();
sat.setDataArea(dataArea);
DocumentRoot root = cf.createDocumentRoot();
sat.setVersionID(root.getInventoryAvailabilityBODVersion());
ProductAvailabilityType pat = f.createProductAvailabilityType();
ProductIdentifierType pid = pat.getProductIdentifier();
I found the answer to this on another forum. I was missing the right CommerceFoundationFactory - the class the ProductIdentifierType is created from is:
com.ibm.commerce.foundation.datatypes.CommerceFoundationFactory fd2 = com.ibm.commerce.foundation.datatypes.CommerceFoundationFactory.eINSTANCE;
fd2.createProductIdentifierType
Say I have this code:
private void CreateSnapshots(IEnumerable<StreamHead> streams)
{
foreach (StreamHead head in streams)
{
IAggregate aggregate = ???;
IMemento memento = aggregate.GetSnapshot();
var snapshot = new Snapshot(head.StreamId, head.SnapshotRevision + 1, memento);
eventStore.AddSnapshot(snapshot);
observer.Notify(new SnapshotTaken(head.StreamId, head.HeadRevision));
}
}
how do I know what aggregate to load for the current stream? I'm also using CommonDomain. Is there something in there?
Thanks
The snapshotting aspect of the EventStore needs a bit of love. I have tried to make the IStoreEvents interface geared toward working with an individual aggregate. I have also tried to ensure that snapshotting does not interfere or get in the way of normal use.
Since the release of v2.0, I have now turned my attention toward v2.1 and I will be able to make a few small API changes related to this. In the meantime, your best option is probably to bypass IStoreEvents altogether when doing snapshotting.
Another alternative is to have the snapshotting code run in-process with your regular code. When an aggregate is loaded the needs a snapshot, you could easily push a reference to that aggregate asynchronously to your snapshotting code. In this way, you don't actually have to do a load because you already have the aggregate.
I found a solution for me (this is most definitely a hack). It is still out-of-band snapshotting. Here's a sample of it in action.
private void CreateSnapshots(IEnumerable<StreamHead> streams)
{
foreach (StreamHead head in streams)
{
//NOTE: This uses a patched version of EventStore that loads commit headers in OptimisticEventStream.PopulateStream()
// <code>
// this.identifiers.Add(commit.CommitId);
// this.headers = this.headers.Union(commit.Headers).ToDictionary(k => k.Key, k => k.Value);
// </code>
var stream = eventStore.OpenStream(head.StreamId, int.MinValue, int.MaxValue);
//NOTE: Nasty hack but it works.
var aggregateType = stream.UncommittedHeaders.Where(p=>p.Key=="AggregateType").First();
var type = aggregateTypeResolver(aggregateType.Value.ToString());
MethodInfo methodInfo = typeof(IRepository).GetMethod("GetById");
MethodInfo method = methodInfo.MakeGenericMethod(type);
object o = method.Invoke(repository, new object[]{head.StreamId, head.HeadRevision});
var aggregate = (IAggregate) o;
IMemento memento = aggregate.GetSnapshot();
var snapshot = new Snapshot(head.StreamId, head.HeadRevision, memento);
eventStore.AddSnapshot(snapshot);
observer.Notify(new SnapshotTaken(head.StreamId, head.HeadRevision));
}
}