Google Cloud Function - Cloud storage object overwritten event - google-cloud-storage

I have a cloud function which is set to be triggered by a cloud storage bucket.
Is there anyway to tell if an event is set off by a newly uploaded object or rather an overwritten object?
I tried to console.log out the event object but nothing seems to be indicative of whether or not the object has been overwritten.
I do notice that there exists an "overwroteGeneration" attribute in Cloud Pub/Sub Notifications which the trigger event here is based on, but it's not available here.

As staged by #Doug Stevenson, it looks like there is no easy way to achieve this. Moreover, I have been playing around with metageneration and, according to this example in the documentation (under "You upload a new version of the image
"), when an object is overwritten (even when versioning is enabled), it will get its own new generation and metageneration numbers, reason why, as you commented in the comment to the other answer, metageneration = 1 in such a scenario.
The only workaround I see, and which may not satisfy your specific requirements, is using two Cloud Functions (let's call them funcA and funcB), one (funcA) that identifies object creation with google.storage.object.finalize and another one (funcB) that detects object overwriting with google.storage.object.archive or google.storage.object.delete (depending if you are using versioning or not, respectively). In this case, funcA would be triggered twice, because for object overwritting it will be triggered too, but depending on your use case, you can identify the proximity in time of the create and delete events and detect that these detect to a single event:
funcA logs:
funcB logs:
I know this does not exactly solve the question you posted, but I do not think there is any way to identify, using a single Cloud Function, that an object has been either created or overwritten, it looks like you will need one Cloud Function for each of those procedures.

In order to determine the nature of the file upload (new file upload rather than existing file upload), you need to use the event and delivered to the function to figure it out.
You'll need to use an Object Finalize event type. As you can see from the documentation there:
This event is sent when a new object is created (or an existing object
is overwritten, and a new generation of that object is created) in the
bucket.
What's not so clear from that doc is that the metageneration combined with the resourceState property of the event is the indicator.
The documentation here should be clear about how to use metageneration along with resourceState to determine if a change to a bucket is a new file or a replaced file:
The resourceState attribute should be paired with the 'metageneration'
attribute if you want to know if an object was just created. The
metageneration attribute is incremented whenever there's a change to
the object's metadata. For new objects, the metageneration value is 1.

Related

Logic App Blob Trigger for a group of blobs

I'm creating a Logic App that has to process all blobs that in a certain container. I would like to periodically check whether there are any new blobs and, if yes, start a run. I tried using the "When a blob is added or modified". However, if at the time of checking there are several new blobs, several new runs are initiated. Is there a way to only initiate one run if one or more blobs are added/modified?
I experimented with the "Number of blobs to return from the trigger" and also with the split-on setting, but I haven't found a way yet.
If you want to trigger with multiple blob files, yes you have to use When a blob is added or modified. From the connector description you could know
This operation triggers a flow when one or more blobs are added or modified in a container.
And you must set the maxFileCount also you already find the result is split into separate parts. This is because the default setting the splitOn is on, if you want the result be a whole you need to set it OFF.
The the result should be what you want.

Is a SharedIndexInformer's Indexer's ThreadSafeStore ever emptied?

I'm carefully making my way through the Go code in the tools/cache package for what seems like the hundredth time.
From close-reading the code, when you create a new SharedIndexInformer, the following things happen:
SharedIndexInformer creates a new Indexer.
The Indexer so created creates a new ThreadSafeStore internally for holding representations of Kubernetes resources.
SharedIndexInformer.Run() creates a new DeltaFIFO with the new Indexer as its second parameter.
The Indexer supplied to the new DeltaFIFO therefore functions as its KeyLister
and its KeyGetter. (This is used to track "prior state" for deletions; i.e. if there's an object in it but the latest sync up with Kubernetes does not contain that object, then we know it has been deleted from the cluster.)
The HandleDeltas function is the one that the underlying controller will call when Kubernetes resources are added, updated or deleted.
The HandleDeltas function will call the Add, Update and Delete methods on the Indexer (and, by extension, on its underlying ThreadSafeStore).
Let's say I write a new controller using a SharedIndexInformer. Let's further say that it is watching for Pods. Let's finally say that there are 10 Pods in the cluster.
Does this mean that after the SharedIndexInformer's Run method has been called and some requisite amount of time has passed that there will be 10 JSON representations of Pods in the ThreadSafeStore, and, further, that none will be removed from this store until an actual deletion of one of the corresponding Pods occurs in Kubernetes?
Correct, except for the JSON part.
The Store contains native Object structs, deserialized from protobuf messages.

how to create a elastic watch which can identify the changes of data in a given index of elasticsearch

In the offical site of Elastic Watcher, they said
Watcher is a plugin for Elasticsearch that provides alerting and notification based on changes in your data
The relevant data or changes in data can be identified with a periodic Elasticsearch query
What I want is a function like Trigger of MySQL, that is when a record is updated, a action is triggered.
But I didn't find a example or document to address this use case, can anybody tell me how to do this?
You define an input of type search and using body, indices (mainly) you define which indices to look at (indices) and what is the actual query (body). If you need other settings, there are many more things to configure. After this, you define a condition and an action to complete the flow.
Make an attempt and create a watch. If you have difficulties, provide details of what you tried in a different SO post (you realize your current post is not appropriate for SO since you ask for complete code without you trying anything).

Determining whether mongodb save method really update a record or not

My question is clear as in the title. When a request come to my service for updating related record in mongoDb, we use "save" method.
However, I would like to understand whether the save method really updates the record or not.
In other words, I would like to know if the content going to save is the same with the existing content in mongoDb. Accordingly, even if save method is executed without any errors, is it possible to understand whether it is really updated or not?
Thanks in advance
There are several ways to checks this.
The first is after calling Save, is to call the getLastError method. Within the console this is just db.getLastError().
This will tell you if an error occurred during the last operation. More details can be found at te following address http://docs.mongodb.org/manual/core/write-operations/#write-concern.
Another way would be to call findAndModify, this will allow you to update the document and either get the updated document back.
http://docs.mongodb.org/manual/reference/command/findAndModify/
Both of these are available in all of the official drivers.
Save method always writes the record.
There is no situation in Mongo where the write would not happen because the record that is being saved is identical to the record that's already there. The write would simply happen and "overwrite" existing data with new data (which happens to be identical).
The only way you can tell is by comparing the old and new documents - and that's a lot of extra work.

Detect when a record is being cloned in trigger

Is there a way to detect that a record being inserted is the result of a clone operation in a trigger?
As part of a managed package, I'd like to clear out some of the custom fields when Opportunity and OpportunityLineItem records are cloned.
Or is a trigger not the correct place to prevent certain fields being cloned?
I had considered creating dedicated code to invoke sObject.Clone() and excluding the fields that aren't required. This doesn't seem like an ideal solution for a managed package as it would also exclude any other custom fields on Opportunity.
In the Winter '16 release, Apex has two new methods that let you detect if a record is being cloned and from what source record id. You can use this in your triggers.
isClone() - Returns true if an entity is cloned from something, even if the entity hasn’t been saved.
getCloneSourceId() - Returns the ID of the entity from which an object was cloned.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_sobject.htm#apex_System_SObject_getCloneSourceId
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_sobject.htm#apex_System_SObject_getCloneSourceId
One approach, albeit kind of kludgy, would be to create a new field, say original_id__c, which gets populated by a workflow (or trigger, depending on your preference for the order of execution) when blank with the salesforce id of the record. For new records this field will match the standard salesforce id, for cloned records they won't. There are a number of variations on when and how and what to populate the field with, but the key is to give yourself your own hook to differentiate new and cloned records.
If you're only looking to control the experience for the end user (as opposed to a developer extending your managed package) you can override the standard clone button with a custom page that clears the values for a subset of fields using url hacking. There are some caveats, namely that the field is editable and visible on the page layout for the user who clicked the clone button. As of this writing I don't believe you can package standard button overrides, but the list of what's possible changes with ever release.
You cannot detect clone operation inside the trigger. It is treated as "Insert" operation.
You can still use dedicated code to invoke sObject.Clone() and exclude the fields that aren't required. You can ensure that you include all fields by using the sObject describe information to get hold of all fields for that object, and then exclude the fields that are not required.
Hope this makes sense!
Anup