Neo4j SDN UUID Transaction Handler - neo4j

I'm using Neo4j 2.1.7 with SDN 3.3.0.RELEASE in embedded mode.
How can i automatically assign UUIDs to new nodes? What is the best practice when trying to achieve this?
Current Solution:
I added a TransactionEventHandler which automatically add a uuid property to every node. Additionally this handler also blocks the commit when someone tries to remove the uuid.
Problems:
With SDN i always have to reload the entity outside of my transaction in order to use the generated uuid. This limits the usefulness of #Transactional. Is there maybe a way to workaround this?

You have several posibilities
Assign the uuid in entity constructor, the advantage of this is that you can then use the uuid safely in equals and hashCode.
MyNodeEntity() {
uuid = UUID.randomUUID.toString()
....
}
Use lifecycle events, very useful for cases similar to "add uuid
if it is not set"
#Bean
ApplicationListener<BeforeSaveEvent> beforeSaveEventApplicationListener() {
return new ApplicationListener<BeforeSaveEvent>() {
#Override
public void onApplicationEvent(BeforeSaveEvent event) {
MyNodeEntity entity = (MyNodeEntity) event.getEntity();
if (!entity.hasUuid()) {
entity.setUuid(UUID.randomUUID.toString());
}
}
};
}
Subclass GraphRepository and override save() method - too complicated for something that can be achieved using the lifecycle events

I just enhanced my save method in my entity service implementation which will set the uuid upfront when it determined that the given entity is new.
Entity:
public boolean isNew() {
return null == getId();
}
EntityServiceImpl:
#Override
public T save(T node) {
if (node.isNew() && node.getUuid() == null) {
node.setUuid(UUIDTransactionEventHandler.getUUID());
}
return nodeRepository.save(node);
}

Related

Server side Validations and security in breeze.js

I’m trying save some entities using breeze.js. Breeze is working fine and it saves all the changes as required. However, I have trouble validating and ensuring authorization is the server side. From what I’ve gather so far I guess the only way to do this is via examining the JObject passed into save bundles and constructing corresponding objects on the server side. I have to do this (instead of relying Breeze.SaveChanges as I have some logic on the server side). How do I do this? And how do I construct the Breeze.WebApi. SaveResult?
Idea of any other way of solving this problem is also very welcome 
This should be done by implementing a custom EFContextProvider.
The code below implements a custom EFContextProvider for the Northwind database and was taken directly from the documentation on the breeze.com website .
public class NorthwindContextProvider: EFContextProvider<NorthwindIBContext> {
public NorthwindContextProvider() : base() { }
protected override bool BeforeSaveEntity(EntityInfo entityInfo) {
// return false if we don’t want the entity saved.
// prohibit any additions of entities of type 'Role'
if (entityInfo.Entity.GetType() == typeof(Role)
&& entityInfo.EntityState == EntityState.Added) {
return false;
} else {
return true;
}
}
protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap) {
// return a map of those entities we want saved.
return saveMap;
}
}
#jaq316 is correct: a custom EFContextProvider is the place to intercept changes coming from the client. It is the place to both authorize and validate them . The documentation has more details. The essence of it is that you scrutinize the proposed changes within your overrides of the BeforeSaveEntity and BeforeSaveEntities virtual methods; alternatively you can attach handlers to the BeforeSaveEntityDelegate and BeforeSaveEntitiesDelegate.
So here is my thought on this one, since I am not using a ContextProvider at all. I am utilizing a SQL back-end and Ninject to inject a repository dependency into each controller I have. I have more items than the demo for "Todos" and want separate controllers out there and repositories as well. If I created the ContextProvider as shown by the breeze docs I would have one ContextProvider file with all the entities in it. This would be huge. If I separated them into separate contexts I would duplicating code in all the overrides.
Here is my Save Changes method in ContactFormController.cs :
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
var sr = new SaveResult() { KeyMappings = new List<KeyMapping>(), Entities = new List<object>()};
dynamic entity = saveBundle["entities"][0];
ContactForm form = entity.ToObject<ContactForm>();
EntityState state = entity.entityAspect.entityState;
switch (state)
{
case EntityState.Added:
KeyMapping mapping = new KeyMapping(){EntityTypeName = typeof(ContactForm).ToString(), TempValue = form.Id };
var validationErrors = _contactFormService.ProcessContactForm(ref form).Cast<object>().ToList();
//if we succeed then update the mappings
if (validationErrors.Count == 0)
{
//setup the new mappings
mapping.RealValue = form.Id;
sr.KeyMappings.Add(mapping);
//link the entity
sr.Entities.Add(form);
}
else
{
sr.Errors = validationErrors;
}
break;
}
return sr;
}
I dynamically change the endpoints before saves on the client side so that each controller in my webapi has a SaveChanges() method. I then call into the appropriate repository to process the backend functions as needed. This way I can run mock code or actual SQL changes depending on the repo injected.
If their are errors on the Processing of the form then we cast our custom List list to a List and assign it to the Errors property of the SaveResult. If there are no errors we send back the new key mappings to be updated on the client.
Ideally I want to reduce all the code in this controller and perhaps abstract it out to a utility method so there is less repeat in every controller. I like this method because then I can create normal repositories and not have them depend on a ContextProvider. Breeze independent at that point.

Creating a DataContext with LinqToSql - Could Storing Collection in Class Result in Memory Issues?

I've ran into some problems in an application where the .net process is running out of memory. One change I made in the application has been adding a lot of Linq to Sql classes. I'm wondering if there is an issue on how I'm creating my DataContext.
I could create my datacontext by creating the datacontext when I need it. Obviously if I was changing data, I would create a variable and hold the datacontext, because I would need the same data context in multiple statements.
Technique 1
public class SchoolRepository
{
DataBaseDataContext GetCtx()
{
return new DataBaseDataContext();
}
public List<School> GetSchools()
{
return GetCtx().Schools.ToList();
}
}
Here is another way I could create the DataContext. In this case I have a class field which holds a reference to a DataContext.
Technique 2:
public class SchoolRepository
{
private DataBaseDataContext _ctx = null;
DataBaseDataContext ctx
{
get { return _ctx = (_ctx ?? new DataBaseDataContext()); }
}
public List<School> GetSchools()
{
return ctx.Schools.ToList();
}
}
I have been using the second way (with a class variable), and I'm wondering if that could be causing the context to stick around longer than the first way--- because it would stick around as long as an instance of my class stuck around.
Perhaps I'm grasping at straws here-- but I'm wondering if one way is "safer" than the other way.

Mocking DbContext.Set<T>()?

We're using EF Code first, and have a data context for our sales database. Additionally, we have a class that sits on top of our data context and does some basic CRUD operations.
For example, we have the following function:
public static T Create<T>(int userId, T entity) where T : class, IAllowCreate
{
if (entity == null)
throw new ArgumentNullException("entity");
using (SalesContext dc = new SalesContext())
{
dc.Set<T>().Add(entity);
dc.SaveChanges();
return entity;
}
}
I found an example of how to create fake contexts and IDBset properties. I started implementing that, but I ran in to an issue.
We use dc.Set() quite liberally (as seen above) in our code, as we attempt to create generic CRUD methods. Instead of having a ReadCustomer, ReadContact etc, we would just do Read(). However, dc.Set returns a DbSet, not an IDbSet, so I'm not able to mock that.
Has anyone been able to mock or fake DbContext and still use the Set functionality?
interface ISalesContext
{
IDbSet<T> GetIDbSet<T>();
}
class SalesContext : DbContext, ISalesContext
{
public IDbSet<T> GetIDbSet<T>()
{
return Set<T>();
}
}
I used a different name, but you can use the new operator if you prefer to hide the regular implementation.

Using WCF DataContract in MVC SessionState using AppFabric cache

I have a Data Access Layer, a Service Layer, and a Presentation Layer. The Presentation Layer is ASP.NET MVC2 RTM (web), and the Service Layer is WCF (services). It's all .NET 3.5 SP1.
The problem is that in the services, the objects being returned are marked with the [DataContract] attribute. The web is using the AppFabric Cache (a.k.a Velocity) SessionStateProvider to store session state. Due to this, anything I store in the session must be serializable.
Here comes the problem: the DataContracts aren't marked with [Serializable] and as far as I can remember, by introducing it onto a class already marked with [DataContract] some issues arise, and so I don't believe this is a solution.
I was initially planning on using the DataContracts right in the web layer, using them as models to views related to rendering the DataContracts (probably nested inside a higher level ViewModel class). But due to the session state provider requiring all objects stored inside it to be serializable, I'm starting to rethink this strategy. It would be nice to have though, since they contain validation logic using the IDataErrorInfo interface, and the same validation logic could be re-used in MVC as part of model binding.
What do you believe is the best way to allow me to reduce the work needed?
I've currently thought of the following different ways:
A. Create a 'ServiceIntegration' part in the web project.
This would be a middle man between my controllers and my WCF service layer. The ServiceIntegration part would speak to the service layer using DataContracts, and to the Web layer using ViewModels, but would have to transform between the DataContracts and ViewModels using a two-way Transformer.
Also, since the IDataErrorInfo Validation wouldn't be re-usable, it would be necessary to create a Validator per DataContract too, that uses the Transformer to convert from ViewModel to DataContract, perform validation using IDataErrorInfo and return its results. This would then be used inside action methods of Controllers (e.g. if (!MyValidator.IsValid(viewModel)) return View();)
Different classes required: xDataContract, xViewModel, xTransformer, xValidator
B. Create a 'SessionIntegration' part in the web project
This would be a middle-man between the controllers (or anything accessing the session) and the session itself. Anything requiring access to the session would go through this class. DataContracts would be used in the entire application, unless they are being stored into the session. The SessionIntegration part would take the responsibility of transforming the DataContract to some ISerializable form, and back. No additional Validator is needed because of the use of of IDataErrorInfo interface on the DataContract.
Different classes required: xDataContract, xTransformer, xSerializableForm
Note: there would still be ViewModels around in both scenarios, however with (B) I'd be able to compose ViewModels from DataContracts.
(B) has the benefit of not needing an extra validator.
Before I go off and implement (A)/(B) fully, I'd like some feedback. At the moment, I'm starting to lean towards (B), however, (A) might be more flexible. Either way, it seems like way too much work for what it's worth. Has anyone else come across this problem, do you agree/disagree with me, and/or do you have any other way of solving the problem?
Thanks,
James
Without going the full blown route of A or B, could you just make a generic ISerializable wrapper object and put those in your SessionState?
[Serializable]
public class Wrapper : ISerializable
{
public object Value { get; set; }
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (Value != null)
{
info.AddValue("IsNull", false);
if (Value.GetType().GetCustomAttributes(typeof(DataContractAttribute), false).Length == 1)
{
using (var ms = new MemoryStream())
{
var serializer = new DataContractSerializer(Value.GetType());
serializer.WriteObject(ms, Value);
info.AddValue("Bytes", ms.ToArray());
info.AddValue("IsDataContract", true);
}
}
else if (Value.GetType().IsSerializable)
{
info.AddValue("Value", Value);
info.AddValue("IsDataContract", false);
}
info.AddValue("Type", Value.GetType());
}
else
{
info.AddValue("IsNull", true);
}
}
public Wrapper(SerializationInfo info, StreamingContext context)
{
if (!info.GetBoolean("IsNull"))
{
var type = info.GetValue("Type", typeof(Type)) as Type;
if (info.GetBoolean("IsDataContract"))
{
using (var ms = new MemoryStream(info.GetValue("Bytes", typeof(byte[])) as byte[]))
{
var serializer = new DataContractSerializer(type);
Value = serializer.ReadObject(ms);
}
}
else
{
Value = info.GetValue("Value", type);
}
}
}
}
As an extension to the provided answer, I added these two methods to ease storing/retrieving the data.
public static void Set<T>(HttpSessionStateBase session, string key, T value)
{
session[key] = new Wrapper(value);
}
public static T Get<T>(HttpSessionStateBase session, string key)
{
object value = session[key];
if (value != null && typeof(T) == value.GetType())
{
return (T) value;
}
Wrapper wrapper = value as Wrapper;
return (T) ((wrapper == null) ? null : wrapper.Value);
}
This makes it a little easier to set/get values from the session:
MyDataContract c = ...;
Wrapper.Set(Session, "mykey", c);
c = Wrapper.Get<MyDataContract>(Session, "mykey");
To make it even easier, add extension methods:
public static class SessionWrapperEx
{
public static void SetWrapped<T>(this HttpSessionStateBase session, string key, T value)
{
Wrapper.Set<T>(session, key, value);
}
public static T GetWrapped<T>(this HttpSessionStateBase session, string key)
{
return Wrapper.Get<T>(session, key);
}
}
And use as below:
MyDataContract c = ...;
Session.SetWrapped("mykey", c);
c = Session.GetWrapped<MyDataContract>("mykey");

Access the website settings of an asp.net mvc app stored in a database table using NHibernate

I have an ASP.NET MVC app which depends on a lot of settings (name-value pairs), I am planning to store this information in a database table called SiteSettings. Is there an easy way in which I can get these settings using NHibernate. And what are the best practices when saving settings for a web application. And by settings I mean the settings which control the flow of processes in the web application and which are governed by business rules. These are not the typical connection string kind of settings. I was unable to get much information on the web on this topic. Maybe I am not searching on the right keywords, Any help will be greatly appreciated.
I can't answer in the context of nhibernate (which I'm not using) or best practices (I came up with this on my own recently). However, it works well for me, and will probably work for you.
I have a table (Biz_Config) in the database to store business preferences. (I've created a web.config section for what I call IT preferences.)
I have a class that is in charge of managing the biz preferences. The constructor grabs the entire table (one row per setting) and copies these into a dictionary, and it has methods to access (such as bizconfig.get("key")) and update this dictionary, also updating the table at the same time. It also has a few shortcut properties for specific dictionary values, especially where the value has to be cast (I have a few important numbers). It works quite well.
In order to be more efficient and not instantiate it every time I need a setting, and also to access it easily from my controllers and views, I created a static class, Globals, that is in charge of getting things out of the session or application variables. For the biz config object, it checks the application variable and, if null, creates a new one. Otherwise it just returns it. Globals is part of my helpers namespace, which is included in my web.config to be available to my views. So I can easily call:
<% Globals.Biz_Config.Get("key") %>
I hope this helps. If you'd like code, I can dig that up for you.
James
If you have a set of key/value pairs, you probably want to use a <map>. See the official NHibernate documentation or Ayende's post about 'NHibernate Mapping - <map/>'.
I have come up with a solution which is quite similar to the one suggested by James. I have an SiteSettingsService class which manages the settings for the whole site, it has a simple dependency on an interface called ISiteServiceRepository. This might not be the most elegant solution, But it is working perfectly for me. I have also configured the SiteSettingsService class as a Singleton using StructureMap. So, it saves me unnecessary instantiantion every time I need any settings.
//ISiteServiceRepository, an implementation of this uses NHibernate to do just two things
//i)Get all the settings, ii)Persist all the settings
using System.Collections.Generic;
using Cosmicvent.Mcwa.Core.Domain.Model;
namespace Cosmicvent.Mcwa.Core.Domain {
public interface ISiteServiceRepository {
IList<Setting> GetSettings();
void PersistSettings(IDictionary<string, string> settings);
}
}
//The main SiteSettingsService class depends on the ISiteServiceRepository
using System;
using System.Collections.Generic;
using Cosmicvent.Mcwa.Core.Domain;
using Cosmicvent.Mcwa.Core.Domain.Model;
namespace Cosmicvent.Mcwa.Core.Services {
public class SiteSettingsService : ISiteSettingsService {
private readonly ISiteServiceRepository _siteServiceRepository;
private IDictionary<string, string> _settings;
public SiteSettingsService(ISiteServiceRepository siteServiceRepository) {
_siteServiceRepository = siteServiceRepository;
//Fill up the settings
HydrateSettings();
}
public int ActiveDegreeId {
get {
return int.Parse(GetValue("Active_Degree_Id"));
}
}
public string SiteTitle {
get { return GetValue("Site_Title"); }
}
public decimal CounsellingFee {
get { return decimal.Parse(GetValue("Counselling_Fee")); }
}
public decimal TuitionFee {
get { return decimal.Parse(GetValue("Tuition_Fee")); }
}
public decimal RegistrationFee {
get { return decimal.Parse(GetValue("Registration_Fee")); }
}
public void UpdateSetting(string setting, string value) {
if (!string.IsNullOrEmpty(setting) && !string.IsNullOrEmpty(value)) {
SetValue(setting, value);
PersistSettings();
}
}
//Helper methods
private void HydrateSettings() {
_settings = new Dictionary<string, string>();
IList<Setting> siteRepoSettings = _siteServiceRepository.GetSettings();
if (siteRepoSettings == null) {
throw new ArgumentException("Site Settings Repository returned a null dictionary");
}
foreach (Setting setting in siteRepoSettings) {
_settings.Add(setting.Name.ToUpper(), setting.Value);
}
}
private string GetValue(string key) {
key = key.ToUpper();
if (_settings == null) {
throw new NullReferenceException("The Site Settings object is Null");
}
if (!_settings.ContainsKey(key)) {
throw new KeyNotFoundException(string.Format("The site setting {0} was not found", key));
}
return _settings[key];
}
private void SetValue(string key, string value) {
key = key.ToUpper();
if (_settings == null) {
throw new NullReferenceException("The Site Settings object is Null");
}
if (!_settings.ContainsKey(key)) {
throw new KeyNotFoundException(string.Format("The site setting {0} was not found", key));
}
_settings[key] = value;
}
private void PersistSettings() {
_siteServiceRepository.PersistSettings(_settings);
}
}
}
Hope this helps future developers facing similar problems. Any suggestions for improving this are more than welcome.

Resources