I'm looking for the right way of communicating the current version of my Aggregate to the Read Model. Currently the only possibility I see is to do the following:
public class Child : AggregateBase
{
...
public void ChangeName(string firstName, string lastName)
{
RaiseEvent(new ChildNameChanged(Id, Version + 1, firstName, lastName));
}
...
}
I don't like it because I think the Aggregate should dispatch the AR version automatically to all the read side event handlers.
Are there other ways I could do this?
Have a look at this gist from JOliver himself: https://gist.github.com/1311195
Basically what he does is that he attach the version as a header in the dispatched message instead. You don't want to add stuff like that to your events. The events should be kept focusing on the business.
Related
I am trying to implement a pure event sourced service to see where I will get problems. Now I found a problem that I can not solve so far, so I would like to open a discussion about it.
Given the following aggregate:
class User
{
public Guid Id { get; private set; }
public string Name { get; private set; }
public void Apply(UserNameChangedEvent domainEvent)
{
Name = domainEvent.NewName;
}
public void Apply(UserCreatedEvent domainEvent)
{
Name = domainEvent.Name;
Id = domainEvent.Id;
}
}
and those Domain Events
class UserCreatedEvent
{
public string NewName { get; }
public Guid Id { get; }
public UserCreatedEvent(string newName, Guid id)
{
NewName = newName;
Id = id;
}
}
class UserNameChangedEvent
{
public string NewName { get; }
public UserNameChangedEvent(string newName)
{
NewName = newName;
}
}
Lets say I create a user and change its name to "Peter" afterwards, then I have a UserCretedEvent and a UserChangedNameEvent persisted in my EventStore. Now the business says that changing a name is no longer possible and therefore I would remove the class UserChangedNameEvent and the function that handles it. But now I have the problem that I can not recreate the aggregate in its correct state, which would be with the name "Peter".
Of course I could start hacking around and mark the function and class as deprecated, so I could keep using it, but I might end up with a lot of event classes afterwards and this will be a nightmare to keep track of. I also heard you might create a new event that persists the change in the domain, but that also seems very hacky to me and not a very good style, as this is no domain event in my point of view.
So the question is, how do I deal the best with changes like this?
edit: just to clarify: I do not want to delete any event, just the class and the function where I use it, as the requirement is different now.
THE resource for questions related to changes in event schemas is Versioning in an Event Sourced System, by Greg Young.
So the question is, how do I deal the best with changes like this?
It depends on the real problem that you are trying to solve.
If the requirement is that users aren't allowed to change their names in the future, then you take away the logic in the domain model that creates new UserNameChangedEvents, but leave behind the correct processing where the events do appear.
If the requirement is that changes to user names should be ignored, then you also take the Apply(UserNameChanged) handler and turn it into a NoOp, just as you would for any other unrecognized event.
If the requirement is that information about name changes should be destroyed, then you migrate your event store to a new schema, that no longer includes the UserNameChanged event.
It may help to think through how you would solve the problem if you were storing your state in an RDBMS: is it enough to ignore the User Name column? do you need to delete the column? Do you need to (somehow) restore value in a column to a previously written value?
Knowing the problem in a traditional database that is analogous to the problem you want to solve in the event store should help identify the appropriate solution.
Also: pay attention to whether or not your domain model is the system of record for the data that needs changed, or if instead you are caching a representation of information published by a different authority.
Events captured facts about the system. If User name was changed at some point, it is a fact. Future business rule changes cannot affect past facts.
So you should not remove UserNameChanged events, and all associated handlers, events are there, and you should not rewrite past history.
In CQRS app, events are generated by command handlers. So this is a place where you specify business requirements. "Now the business says that changing a name is no longer possible" means that ChangeName command is no longer available: you can simply remove it, or just throw an error saying that you cannot change names anymore.
I'm new at Apache Isis and I'm stuck.
I want to create my own submit form with editable parameters for search some entities and a grid with search results below.
Firstly, I created #DomainObject(nature=Nature.VIEW_MODEL) with search results collection, parameters for search and #Action for search.
After deeper research, I found out strict implementations for actions (For exapmle ActionParametersFormPanel). Can I use #Action and edit #DomainObject properties(my search parameters for action) without prompts?
Can I implement it by layout.xml?
Then I tried to change a component as described here: 6.2 Replacing page elements, but I was confused which ComponentType and IModel should I use, maybe ComponentType.PARAMETERS and ActionModel or implement my own IModel for my case.
Should I implement my own Wicket page for search and register it by PageClassList interface, as described here: 6.3 Custom pages
As I understood I need to replace page class for one of PageType, but which one should I change?
So, the question is how to implement such issues properly? Which way should I choose?
Thank you!
===================== UPDATE ===================
I've implemented HomePageViewModel in this way:
#DomainObject(
nature = Nature.VIEW_MODEL,
objectType = "homepage.HomePageViewModel"
)
#Setter #Getter
public class HomePageViewModel {
private String id;
private String type;
public TranslatableString title() {
return TranslatableString.tr("My custom search");
}
public List<SimpleObject> getObjects() {
return simpleObjectRepository.listAll();
}
#Action
public HomePageViewModel search(
#ParameterLayout(named = "Id")
String id,
#ParameterLayout(named = "Type")
String type
){
setId(id);
setType(type);
// finding objects by entered parameters is not implemented yet
return this;
}
#javax.inject.Inject
SimpleObjectRepository simpleObjectRepository;
}
And it works in this way:
I want to implement a built-in-ViewModel action with parameters without any dialog windows, smth like this:
1) Is it possible to create smth like ActionParametersFormPanel based on ComponentType.PARAMETERS and ActionModel and use this component as #Action in my ViewModel?
2) Or I should use, as you said, ComponentType.COLLECTION_CONTENTS? As I inderstand my search result grid and my search input panel will be like ONE my stub component?
Thank you.
We have a JIRA ticket in our JIRA to implement a filterable/searchable component, but it hasn't yet made it to the top of the list for implementation.
As an alternative, you could have a view model that provides the parameters you want to filter on as properties, with a table underneath. (I see you asked another question here on SO re properties on view models, so perhaps you are moving in that direction also... I've answered that question).
If you do want to have a stab at implementing that ticket, then the ComponentTYpe to use is COLLECTION_CONTENTS. If you take a look at the isisaddons, eg for excel or gmap3 then it might help get you started.
======= UPDATE TO ANSWER (based on update made to query) ==========
I have some good news for you. v1.15.0-SNAPSHOT, which should be released in the couple of weeks, has support for "inline prompts". You should find these give a user experience very similar to what you are after, with no further work needed on your part.
To try it out, check out the current trunk, and then load the simpleapp (in examples/application/simpleapp). You should see that editing properties and invoking actions uses the new inline prompt style.
HTH
Dan
I have a web api project that I'm building on an N-Tier system. Without causing too many changes to the overall system, I will not be touching the data server that has access to the database. Instead, I'm using .NET remoting to create a tcp channel that will allow me to send requests to the data server, which will then query the database and send back a response object.
On my application, I would like to use entity framework to create my datacontexts (unit of work), then create a repository pattern that interfaces with those contexts, which will be called by the web api project that I created.
However, I'm having problems with entity framework as it requires me to have a connection with the database. Is there anyway I can create a full entity framework project without any sqlconnections to the database? I just need dbcontexts, which I will be mapping my response objects and I figure that EF would do what I needed (ie help with design, and team collabs, and provide a nice graphical designer); but it throws an error insisting that I need a connection string.
I've been searching high and low for tutorials where a database is not needed, nor any sql connection string (this means no localdb either).
Okay as promised, I have 3 solutions for this. I personally went with #3.
Note: Whenever there is a repository pattern present, and "datacontext" is used, this is interpreted as your UnitOfWork.
Solution 1: Create singletons to represent your datacontext.
http://www.breezejs.com/samples/nodb
I found this idea after going to BreezeJS.com's website and checked out their samples. They have a sample called NoDb, which allows them to create a singleton, which can create an item and a list of items, and a method to populate the datacontext. You create singletons that would lock a space in memory to prevent any kind of thread conflicts. Here is a tid bit of the code:
//generates singleton
public class TodoContext
{
static TodoContext{ }
private TodoContext() { }
public static TodoContext Instance
{
get
{
if (!__instance._initialized)
{
__instance.PopulateWithSampleData();
__instance._initialized = true;
}
return __instance;
}
}
public void PopulateWithSampleData()
{
var newList = new TodoItem { Title = "Before work"};
AddTodoList(newList);
var listId = newList.TodoListId;
var newItem = new TodoItem {
TodoListId = listId, Title = "Make coffee", IsDone = false };
AddTodoItem(newItem);
newItem = new TodoItem {
TodoListId = listId, Title = "Turn heater off", IsDone = false };
AddTodoItem(newItem);
}
//SaveChanges(), SaveTodoList(), AddTodoItem, etc.
{ ... }
private static readonly Object __lock = new Object();
private static readonly TodoContext __instance = new TodoContext();
private bool _initialized;
private readonly List<TodoItem> _todoLists = new List<TodoItem>();
private readonly List<KeyMapping> _keyMappings = new List<KeyMapping>();
}
There's a repository included which directs how to save the context and what needs to be done before the context is saved. It also allows the list of items to be queryable.
Problem I had with this:
I felt like there was higher maintenance when creating new datacontexts. If I have StateContext, CityContext, CountryContext, the overhead of creating them would be too great. I'd have problems trying to wrap my head around relating them to each other as well. Plus I'm not too sure how many people out there who agree with using singletons. I've read articles that we should avoid singletons at all costs. I'm more concerns about anyone who'd be reading this much code.
Solution 2: Override the Seed() for DropCreateDatabaseAlways
http://www.itorian.com/2012/10/entity-frameworks-database-seed-method.html
For this trick, you have to create a class called SampleDatastoreInitializer that inherits from System.Data.Entity.DropCreateDatabaseAlways where T is the datacontext, which has a reference to a collection of your POCO model.
public class State
{
[Key()]
public string Abbr{ get; set; }
public string Name{ get; set; }
}
public class StateContext : DbContext
{
public virtual IDbSet<State> States { get; set; }
}
public class SampleDatastoreInitializer : DropCreateDatabaseAlways<StateContext>
{
protected override void Seed (StateContext context)
{
var states = new List<State>
{
new State { Abbr = "NY", Name = "New York" },
new State { Abbr = "CA", Name = "California" },
new State { Abbr = "AL", Name = "Alabama" },
new State { Abbr = "Tx", Name = "Texas" },
};
states.ForEach(s => context.States.Add(s));
context.SaveChanges();
}
}
This will actually embed the data in a cache, the DropCreateDatabaseAlways means that it will drop the cache and recreate it no matter what. If you use some other means of IDatabaseInitializer, and your model has a unique key, you might get an exception error, where you run it the first time, it works, but run it again and again, it will fail because you're violating the constraints of primary key (since you're adding duplicate rows).
Problem I had with this:
This seems like it should only be used to provide sample data when you're testing the application, not for production level. Plus I'd have to continously create a new initializer for each context, which plays a similar problem noted in solution 1 of maintainability. There is nothing automatic happening here. But if you want a way to inject sample code without hooking up to a database, this is a great solution.
Solution 3: Entity framework with Repository (In-memory persistence)
I got this solution from this website:
http://www.roelvanlisdonk.nl/?p=2827
He first sets up an edmx file, using EF5 and the code generator templates for EF5 dbcontexts you can get from VS extension libraries.
He first uses the edmx to create the contexts and changes the tt templates to bind to the repository class he made, so that the repository will keep track of the datacontext, and provide the options of querying and accessing the data through the repository; in his website though he calls the repository as MemoryPersistenceDbSet.
The templates he modified will be used to create datacontexts that will bind to an interface (IEntity) shared by all. Doing it this way is nice because you are establishing a Dependency Injection, so that you can add any entity you want through the T4 templates, and there'd be no complaints.
Advantage of this solution:
Wrapping up the edmx in repository pattern allows you to leverage the n-tier architecture, so that any changes done to the backend won't affect the front end, and allows you to separate the interface between the front end and backend so there are no coupled dependencies. So maybe later on, I can replace my edmx with petapoco, or massive, or some other ORM, or switch from in-memory persistence to fetching data from a database.
I followed everything exactly as explained. I made one modification though:
In the t4 template for .Context.tt, where DbSetInConstructor is added, I had the code written like this:
public string DbSetInConstructor(EntitySet entitySet)
{
return string.Format(
CultureInfo.InvariantCulture,
“this.{1} = new BaseRepository();”,
_typeMapper.GetTypeName(entitySet.ElementType), entitySet);
}
Because in my case I had the entityset = Persons and entityname = Person. So there’d be discrepancy. But this should cover all bases.
Final step:
So whether you picked solution 1, 2, or 3. You have a method to automatically populate your application. In these cases, the stubs are embedded in the code. In my case, what I've done is have my web server (containing my front end app), contact my data server, have the data server query the database. The data server will receive a dataset, serialize it, and pass it back to the web server. The web server will take that dataset, deserialize it, and auto-map to an object collection (list, or enumberable, or objectcollection, etc).
I would post the solutions more fully but there's way too much detail between all 3 of these solutions. Hopefully these solutions would point anyone in the right direction.
Dependency Injection
If anyone wants some information about how to allow DI to api controllers, Peter Provost provides a very useful blog that explains how to do it. He does a very very good job.
http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/
few more helpful links of repository wrapping up edmx:
http://blogs.msdn.com/b/wriju/archive/2013/08/23/using-repository-pattern-in-entity-framework.aspx
http://www.codeproject.com/Articles/688929/Repository-Pattern-and-Unit-of
I'd like to send the report generated by testNG ( java+eclipse+testNG) within the #AfterSuite section.
It's not a problem to send it, but the point is that the report is generated after the #AfterSuite section, so , basically, i send the previous one instead of the last one !
Any idea about how can I solve it ?
As you are seeing, #AfterSuite runs before the report is generated.
Have you though about implementing a TestNG IReporter listener ?
public class MyReporter implements IReporter {
#Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> iSuites, String s) {
//Create your bespoke results
//Email results
}
}
Obviously you can see a flaw in that you have to generate your own results from the raw results data (which may be advantageous if you just want to email a subset of data).
The ideal solution would to be able to extend the default report generator, but I am not sure this can be done. However there is an existing listener provided by http://reportng.uncommons.org/, which actually provides a much nicer report output.
If you extend this this class, and call their code, and then add email generator code afterwards, it may work
public class MyReporter extends HTMLReporter {
#Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> iSuites, String s) {
super.generateReport(xmlSuites, iSuites, s);
//Email results
}
}
You can attach a listener to a test suite in several ways, as explained on the TEstNG website (http://testng.org/doc/documentation-main.html#listeners-testng-xml)
An alternative to all of this woudl be to use a build tool like Maven to run your tests, then have a post test event to email the results.
I copied the answer from Krishnan.
It works for me.
By the way, in my test environment, I need to extends the org.testng.reporters.EmailableReporter2 instead of EmailableReporter to make sure the correct count.
See below for your reference:
Krishnan Mahadevan Krishnan Mahadevan at Jul 31, 2012 at 8:58 am I am guessing that you are referring to the TestNG generated
"emailable-report.html" which you would want to mail.
With that assumption here's how you should be able to do it.
Extend org.testng.reporters.EmailableReporter
Override org.testng.reporters.EmailableReporter.generateReport(List,
List, String) and have it do something as below :
#Override
public void generateReport(List xml, List suites, String
outdir) {
super.generateReport(xml, suites, outdir);
SendFileEmail e= new SendFileEmail();
e.sendEmail();
}
Now add up this listener of yours into your suite file using
tag.
I spent many hours to search this info "How to make SuggestBox to reliably RPC-call to Server DB in GWTP (Gwt platform) Framework" but couldn't find any answer about it.
In fact, there were some answers but they were for people who do not use GWTP. For example, i found a website (http://jagadesh4java.blogspot.com.au/2009/03/hi-every-one-this-is-my-first-blog.html) that guide to code SuggestBox & RPC & it suggests these classes:
-Client Side:
+ interface SuggestService extends RemoteService
+ interface SuggestServiceAsync
+ class Suggestions implements IsSerializable, Suggestion
+ class SuggestionOracle extends SuggestOracle
-Server Side:
+ class SuggestServiceImpl extends RemoteServiceServlet implements
SuggestService
I tried to follow up that website but i got error:
[WARN] failed SelectChannelConnector#127.0.0.1:8888
java.net.BindException: Address already in use: bind..........
The above guide clearly was not for people who use GWTP.
My task is I have a dictionary that contains 200k of English words & I want to have a suggest box that when user types any char or word it will look up into DB & suggest accordingly. Ex, when user types "c" it will suggest "cat, car, cut, etc", when typing "car" it will suggest "car service", "carbon", etc.
So I come up with my own solution, even it works but I am feeling I am not doing right thing. My solution is quite simple that I just bring the data from DB down & add them into MultiWordSuggestOracle. Whenever it found a list of word in DB, it won't clear the old data but just keep adding the new list into MultiWordSuggestOracle. However, my program will not constantly call to DB everytime user types a char, but it will call to DB only if the wordInTheMultiWordSuggestOracleList.indexOf(suggestBox.getText(),0)>0. However, there is no way to loop each string in the MultiWordSuggestOracle, so I used List<String> accumulatedSuggestedWordsList=new ArrayList<String>() to store data. Pls see ex:
private final MultiWordSuggestOracle mySuggestions = new MultiWordSuggestOracle();
private List<String> accumulatedSuggestedWordsList=new ArrayList<String>();
private void updateSuggestions(List<String> suggestedWordsList) {
// call some service to load the suggestions
for(int i=0;i<suggestedWordsList.size(); i++){
mySuggestions.add(suggestedWordsList.get(i));
accumulatedSuggestedWordsList.add(suggestedWordsList.get(i));
}
}
#Override
protected void onBind() {
super.onBind();
final SuggestBox suggestBox = new SuggestBox(mySuggestions);
getView().getShowingTriplePanel().add(suggestBox);
suggestBox.addKeyDownHandler(new KeyDownHandler(){
#Override
public void onKeyDown(KeyDownEvent event) {
// TODO Auto-generated method stub
String word=suggestBox.getText();
int index=-1;
for(int i=0; i<accumulatedSuggestedWordsList.size();i++){
String w=accumulatedSuggestedWordsList.get(i);
index=w.indexOf(word,0);
if(index>0)
break;
}
if(index==0 || index==-1){
GetWordFromDictionary action=new tWordFromDictionary(suggestBox.getText());
action.setActionType("getSuggestedWords");
dispatchAsync.execute(action, getWordFromDictionaryCallback);
}
}
});
}
private AsyncCallback<GetWordFromDictionaryResult> getWordFromDictionaryCallback=new AsyncCallback<GetWordFromDictionaryResult>(){
#Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
#Override
public void onSuccess(GetWordFromDictionaryResult result) {
// TODO Auto-generated method stub
List<String> suggestedWordsFromDictionaryList=result.getSuggestedWordsFromDictionaryList();
updateSuggestions(suggestedWordsFromDictionaryList);
}
};
The Result: it works but the suggest only show up if i type the "Backspace" button. For ex, when i type the word "car" then no suggested list popup, it only popup "car service, car sale, etc" when i hit the backspace button.
So, can u evaluate my solution? I am feeling i am not doing right. If i am not doing right thing, can u provide a SuggestBox PRC for GWTPframework?
Very Important Note:
How to build a Reliable SuggestBox PRC that prevents the a denial of service attack on our own servers?
What if there are too many calls generated by many people rapidly typing in a suggest box?
Actually I just found an error:
SQL Exception: Data source rejected establishment of connection, message from server: "Too many connections" --> so there must be something wrong with my solution
I knew why i got "Too many connections" error. For example, when i type "ambassador" into the suggest box, & i saw my server call the Db 9 times continuously.
-1st call, it will search any word like 'a%'
-2nd call, it will search any word like 'am%'
-3nd call, it will search any word like 'amb%'
The first problem is that it create too many calls at 1 time, second it is not effective cos the first time call like 'a%' may already contains word that will be called at 2nd time like 'am%', so it duplicate the data. Question is how to code to avoid this ineffectiveness.
Someone suggests to use RPCSuggestOracle.java (https://code.google.com/p/google-web-toolkit-incubator/source/browse/trunk/src/com/google/gwt/widgetideas/client/RPCSuggestOracle.java?spec=svn1310&r=1310)
If you can provide an example of using RPCSuggestOracle.java, that will be great.
I hope your answer will help a lot of other people.
There were an old inspiring blog post, from the Lombardi Development, that I remember addresses almost all questions you are looking for. It took me a while to find that out but, fortunately, it has simply been moved! And the sources are available. Have a look.
Although being old, things in that post still applies. In particular:
use a single connection to avoid explosion of requests, and left free the other ones for other tasks (i.e. avoid to use all the 2-to-8 max parallel browser http connections);
reuse data from a previous requests (i.e., if your request is a substring of the previous one, you may already have the suggestions, hence just filter them client-side).
Other things that come to my mind are:
use a Timer to simulate a little delay in case of fast writers, so you call the server only after a bit (probably an over optimization, but still an idea);
allow to fetch suggestions only on a minimum input length (say, min 3 characters). If you have a lot of possible suggestions, the data returned might be expensive even to parse, specially if - for the search - you decide to adopt a contains instead of startswith strategy;
in case you still have tons of suggestions, you could try to implement a lazy load SuggestionDisplay that simply show you the first, say, 50 suggestions and then, on scroll, all the others in an incremental way using the same input string.
Can't say anything from the GWTP part, I've never used it. But AFAICS seems just like GWT-RPC + dispatch mechanism (command pattern) like the old gwt-dispatch. Should't be hard to use instead of vanilla GWT-RPC.
Also have a look at the other 2 previous articles linked in the one above. Might contain some other useful tips.
Use key Up handler instead of key down handler may be it will solve your problem.
this is because keyDown event is fired before rendering the character.