How to decide dynamic work flow for a set of model? - django

Let consider we have 3 roles, Manager, Admin, Superadmin.
Sequence of transactions should happen like t1->t2->t3->t4.
If any employee belongs to Manager role , his transaction should happen t1->t3->t2
If any employee belongs to Admin role , his transaction should happen t1->t2->t4
If any employee belongs to Supreadmin role , his transaction should happen
t1->t2
In django how to define this dynamic workflow? So on request of employee this process should follow based on there Role.
Thank you in advance.

Generally, that sample is about non-dynamic workflow. All nodes instances counts are known at the moment of workflow definitions.
If you think about the flow from the process modeling side, visual representation and explanation to a non-technical user, the flow would be modeled as following BPMN diagram that not a far away from the textual specification:
So this directly could be translated into the viewflow class definition, where django views for the same tasks could be reused over different flow nodes, ex:
class MyFlow(Flow):
start = flow.Start(ViewT1).Next(check_role)
check_role = (
flow.Switch()
.Case(this.user_t2, cond=lambda act: act.process.created_by.role=='USER')
.Case(this.admin_t2, cond=lambda act: act.process.created_by.role=='ADMIN')
...
)
user_t2 = flow.View(ViewT2).Next(this.user_t3)
admin_t2 = flow.View(ViewT2).Next(this.admin_t4)
...
Ability to have the code that looks pretty same as the textual and visual specification the main value of the viewflow library. To do that for some cases you will need to create your own flow nodes. In the viewflow samples, you can find a dynamic split node that show how to be, if the nodes instance counts are unknown at the design time.

Related

DynamoDB Single Table Design guidance

First time building a single table design and was just wondering if anyone had any advice/feedback/better ways on the following plan?
Going to be building a basic 'meetup' clone. so e.g. Users can create events, and then users can attend those events essentially.
How the entities in the app relate to eachother:
Entities: (Also added an 'ItemType' to each entity) so e.g. ItemType=Event
Key Structure:
Access Patterns:
Get All Attendees for an event
Get All events for a specific user
Get all events
Get a single event
Global Secondary Indexes:
Inverted Index: SK-PK-index
ItemType-SK-Index
Queries:
1. Get all attendees for an event:
PK=EVENT#E1
SK=ATTENDEE# (begins with)
2. Get All Events for a specific User
Index: SK-PK-index
SK=ATTENDEE#User1
PK=EVENT# (Begins With)
3. Get All Events (I feel like there's a much better way to do this, if there is please let me know)
Index: ItemType-SK-Index
ItemType=Event
SK=EVENT# (Begins With)
4. Get a single event
PK=EVENT#E1
SK=EVENT#E1
A couple of questions I had:
When returning a list of attendees, I'd want to be able to get extra data for that attendee, e.g. First/Lastname etc.
Based on this example: https://aws.amazon.com/getting-started/hands-on/design-a-database-for-a-mobile-app-with-dynamodb/module-5/
To avoid having to duplicate data and handle when data changes, (e.g. user changes name) use Partial Normalization and the BatchGetItem API to retrieve details?
For fuzzy searches etc, is the best approach to stream this data into e.g. elastic/opensearch?
If so, when building API's - would you still use dynamoDB for some queries, or just use elasticsearch for everything?
e.g. for Get All Events - would using an ItemType of 'Events' end up creating a hot partition if there's a huge number of events?
Sorry for the long post, Would appreciate any feedback/advice/better ways to do things, thank you!!

Query at JPA repo from list object

Need to ask query in JPA repository.
I have entity mapped like this
private String name;
private Set<String> roles;
There are two different string roles "users" and "managers"
Need to list all users and all managers respectively
tried
findAllByRolesContains(String role);
Than tried:
return userRepository.findAllByRolesContains("users");
Received response
Parameter value [%users%] did not match expected type
How should I ask it right?
tried
findAllByInRolesContains(String role);
it did not work at all
So first off, I see you didn't add the tags for "spring" and "spring data jpa" to your question. I want to remind you, that you are showing code snippets for Spring Data JPA - so a part of the Spring framework that builds upon the Java Persistence API (JPA). Make sure you understand the basics (JPA) first! Spring Data builds JPA queries under the hood and automates a lot of stuff, but it won't save you from knowing how to use JPA!
Next, if you have specific roles, i.e., not arbitrary strings ("role1324"), you might want to map an Enum instead.
But let's look at your case:
#Entity
public class User {
#Id
private String name;
#ElementCollection
private Set<String> roles;
}
So you are trying to create a query method for your repository - Spring Data generates queries based on the name of the method. The rules can be found in the reference documentation.
So what does findAllByRolesContains generate? Anything between 'find' and 'By' is just descriptive, i.e., ignored. 'Roles' is the property and 'Contains' may mean "contained in a collection" or "contained in a string".
But we are missing a level here - you want to check if a string in a collection contains something. And I have not found a way to tell Spring Data to create the correct query.
findAllByRolesLike is the closest one, but then you have to manually wrap the search string with '%'s.
Getting Spring Data to create the correct query can be fickle and if it's not straight forward, a waste of time IMHO. You can always write the query yourself:
#Query("select user from User user join user.roles role where role like %:role%")
List<User> findAllByRolesContaining(#Param("role") String role);
But if you test this with a User with roles ["admin", "administrator"], you get the same user twice?! What gives?! Well, that's just how the underlying SQL works - it filters rows and there are two rows with "username - admin" and "username - administrator".
You want the distrinct keyword to filter them out:
#Query("select distinct user from User user join user.roles role where role like %:role%")
List<User> findAllByRolesContaining(#Param("role") String role);
One more optimization: If roles is an #ElementCollection, they are fetched lazily by default. If you know that you will need to access it, you can add a join fetch user.roles before the join. This will load it eagerly. You can create 2 different methods if you like. You want to avoid fetching them if you don't need them, but if you know you'll need them, lazy loading may issue multiple queries.
The wikibook on JPA is a great resource and the book and blog of Vlad Mihalcea are the best resources on high performance JPA you can find.
Also - don't rely too much on the auto-magic of Spring Data JPA, IMHO it does more harm than good for anything but the most trivial of queries...

How to get history of a state in corda?

In My corda project state may evolve over time. I have made the state of type LinearState. Now I want to retrieve the history of a corda state that means, How it evolved over time. How can I see the evolution history of a particular state in Corda?
Particularly, I want to access the complete transaction chain of a state.
Of course without access to your code this answer will vary, but there's two pieces of documentation to be aware of here.
What you want to perform is essentially a vault query (depending on what information you're looking to get).
From the docs on LinearState:
Whenever a node records a new transaction, it also decides whether it should store each of the transaction’s output states in its vault. The default vault implementation makes the decision based on the following rules.
source: https://docs.corda.net/docs/corda-os/4.6/api-states.html#the-vault
That being said, to perform your vault query you would do it just like you would other states. Here's the docs on the vault query API : https://docs.corda.net/docs/corda-os/4.6/api-vault-query.html
If you have the linear Id you can do it from the node shell or using H2 and looking in places like the VAULT_LINEAR_STATES table.
If you want an example of querying in code take a look at the obligation cordapp that takes the linearID as a parameter to the flow.
// 1. Retrieve the IOU State from the vault using LinearStateQueryCriteria
List<UUID> listOfLinearIds = Arrays.asList(stateLinearId.getId());
QueryCriteria queryCriteria = new QueryCriteria.LinearStateQueryCriteria(null, listOfLinearIds);
Vault.Page results = getServiceHub().getVaultService().queryBy(IOUState.class, queryCriteria);
StateAndRef inputStateAndRefToSettle = (StateAndRef) results.getStates().get(0);
IOUState inputStateToSettle = (IOUState) ((StateAndRef) results.getStates().get(0)).getState().getData();
Source Code example here: https://github.com/corda/samples-java/blob/master/Advanced/obligation-cordapp/workflows/src/main/java/net/corda/samples/flows/IOUSettleFlow.java#L56-L61

Django custom creation manager logic for temporal database

I am trying to develop a Django application that has built-in logic around temporal states for objects. The desire is to be able to have a singular object representing a resource, while having attributes of that resource be able to change over time. For example, a desired use case is to query the owner of a resource at any given time (last year, yesterday, tomorrow, next year, ...).
Here is what I am working with...
class Resource(models.Model):
id = models.AutoField(primary_key=True)
class ResourceState(models.Model):
id = models.AutoField(primary_key=True)
# Link the resource this state is applied to
resource = models.ForeignKey(Resource, related_name='states', on_delete=models.CASCADE)
# Track when this state is ACTIVE on a resource
start_dt = models.DateTimeField()
end_dt = models.DateTimeField()
# Temporal fields, can change between ResourceStates
owner = models.CharField(max_length=100)
description = models.TextField(max_length=500)
I feel like I am going to have to create a custom interface to interact with this state. Some example use cases (interface is completely up in the air)...
# Get all of the states that were ever active on resource 1 (this is already possible)
Resource.objects.get(id=1).states.objects.all()
# Get the owner of resource 1 from the state that was active yesterday, this is non-standard behavior
Resource.objects.get(id=1).states.at(YESTERDAY).owner
# Create a new state for resource 1, active between tomorrow and infinity (None == infinity)
# This is obviously non standard if I want to enforce one-state-per-timepoint
Resource.objects.get(id=1).states.create(
start_dt=TOMORROW,
end_dt=None,
owner="New Owner",
description="New Description"
)
I feel the largest amount of custom logic will be required to do creates. I want to enforce that only one ResourceState can be active on a Resource for any given timepoint. This means that to create some ResourceState objects, I will need to adjust/remove others.
>> resource = Resource.objects.get(id=1)
>> resource.states.objects.all()
[ResourceState(start_dt=None, end_dt=None, owner='owner1')]
>> resource.states.create(start_dt=YESTERDAY, end_dt=TOMORROW, owner='owner2')
>> resource.states.objects.all()
[
ResourceState(start_dt=None, end_dt=YESTERDAY, owner='owner1'),
ResourceState(start_dt=YESTERDAY, end_dt=TOMORROW, owner='owner2'),
ResourceState(start_dt=TOMORROW, end_dt=None, owner='owner1')
]
I know I will have to do most of the legwork around defining the logic, but is there any intuitive place where I should put it? Does Django provide an easy place for me to create these methods? If so, where is the best place to apply them? Against the Resource object? Using a custom Manager to deal with interacting with related 'ResourceState' objects?
Re-reading the above it is a bit confusing, but this isnt a simple topic either!! Please let me know if anyone has any ideas for how to do something like the above!
Thanks a ton!
too long for a comment, and purely some thoughts, not a full answer, but having dealt with many date effective records in financial systems (not in Django) some things come to mind:
My gut would be to start by putting it on the save method of the resource model. You are probably right in needing a custom manager as well.
I'd probably also flirt with the idea of a is_current boolean field in the state model but certain care would need to be considered with future date effective state records. If there is only one active state at a time, I'd also examine the need for an enddate. Having both start and end definitely makes the raw sql queries (if ever needed) easier: date() between state.start and state.end <- this would give current record, sub in any date to get that date's effective record. Also, give some consideration to the open ended end date where you don't know the end date date. Your queries will have to handle the nulls properly. YOu probably also may need to consider the open ended start date (say for a load of historical data where the original start date is unknown). I'd suggest staying away from using some super early date as a fill in (same for date far in the future for unknown end dates) - If you end up with lots of transactions, your query optimizer may thank you, however, I may be old and this doesn't matter anymore.
If you like to read about this stuff, I'd recommend a look at 1.8 in https://www.amazon.ca/Art-SQL-Stephane-Faroult/dp/0596008945/ and chapter 6:
"But before settling for one solution, we must acknowledge that
valuation tables come in all shapes and sizes. For instance, those of
telecom companies, which handle tremendous amounts of data, have a
relatively short price list that doesn't change very often. By
contrast, an investment bank stores new prices for all the securities,
derivatives, and any type of financial product it may be dealing with
almost continuously. A good solution in one case will not necessarily
be a good solution in another.
Handling data that both accumulates and changes requires very careful
design and tactics that vary according to the rate of change."

Doctrine 2 How to set an entity table name at run time (Zend 2)

I'm building a product with Zend 2 and Doctrine 2 and it requires that I have a separate table for each user to contain data unique to them. I've made an entity that defines what that table looks like but how do I change the name of the table to persist the data to, or in fact retrieve the data from, at run time?
Alternatively am I going to be better off giving each user their own database, and just changing which DB I am connecting to?
I'd question the design-choice at first. What happens if you create a new user after runtime. The table has to be created first? Furthermore, what kind of data are you storing, to me this sounds like a pretty common multi-client capabilities. Like:
tbl_clients
- id
- name
tbl_clientdata
- client_id
- data_1_value
- data_2_value
- data_n_value
If you really want to silo users data, you'd have to go the separate databases route. But that only works if each "user" is really independent of each other. Think very hard about that.
If you're building some kind of software-as-a-service, and user A and user B are just two different customers of yours, with no relationship to each other, then an N+1 database might be appropriate (one db for each of your N users, plus one "meta" database which just holds user accounts (and maybe billing-related stuff).
I've implemented something like this in ZF2/Doctrine2, and it's not terribly bad. You just create a factory for EntityManager that looks up the database information for whatever user is active, and configures the EM to connect to it. The only place it gets a bit tricky is when you find yourself writing some kind of shared job queue, where long-running workers need to switch database connections with some regularity -- but that's doable too.