I am building a cache of objects and trying to persist them as I receive them in my DB (Stripe Webhooks if your familiar). But for some reason I cannot get any of them to persist, though there are no errors thrown....
NOTE: don't let the GET confuse you I changed it to GET so I could test it easier.... it will be a POST if it ever works (yeah I'm a little frustrated been trying different variations all weekend. not sure if its just me but this stuff seems really poorly defined, you can find a half dozen articles all giving me different approaches)
#Path("/events/{realm}/add")
#GET
#ReactiveTransactional
public Uni<Response> add(#PathParam("realm") String realm, #QueryParam("id") String id) {
return Panache.withTransaction(() -> StripeAccount.findRealm(realm)
.onItem().transform(a -> new StripeCustomer(realm,id)).onItem().invoke(e -> e.persist())
).onItem().ifNotNull().transform(e -> Response.ok(e).build())
.onItem().ifNull().continueWith(Response.ok().status(NOT_FOUND)::build);
}
I have tried the above endpoint with and without the ReactiveTransactional and with and without the "withTransaction()" but it never persists in mysql DB though the new object is returned in the response and no errors are thrown.
#Entity
#Table(name="Customers")
public class StripeCustomer extends PanacheEntityBase {
#Id
#Column(name = "cust_id")
public String id;
#Column(name = "cust_realm")
public String realm;
public StripeCustomer(String realm, String id) {
this.realm = realm;
this.id = id;
}
}
The ID is a natural key I receive from Stripe and I do not know if this is part of the problem. I have tried designating the #Id differently as well but nothing seems to help. I also tried extending from PanacheEntity and allowing JPA to create a redundant key but that too did not help.
Related
I am having problem retrieving records from azure storage table when the record is inserted from the portal itself. The table structure is fairly simple:
package com.nielsen.batchJobsManager.storage.entities;
import com.microsoft.azure.storage.table.TableServiceEntity;
public class BatchJobConfigEntity extends TableServiceEntity {
public BatchJobConfigEntity(String jobPrefix, String configName) {
this.partitionKey = jobPrefix;
this.rowKey = configName;
}
public BatchJobConfigEntity() {
}
public String configValue;
public void setConfigValue(String configValue) {
this.configValue = configValue;
}
public String getConfigValue() {
return this.configValue;
}
}
I am just trying to fetch the configValue stored in the table but I am having no luck, as you can see from the screen shot. However I have noticed that if I add the record using java application "TableOperation.insertOrMerge" then it works but I just do not understand why it should matter!
Ok found the solution just trying random stuff! I hope this will come handy for folks who are facing the same issue. So turns out the propertyName must follow camel case but with first character capitalized. So :
had to be changed to :
Only after inserting like that I was able to get the configValue from table entity object correctly.
I am using JsfCaptcha in an attempt to process offline captcha validation. While there is a method to validate "what the user entered matches what the captcha image has shown", I am having a hard time actually printing out what the server states is the right solution. I anticipated this being fairly easy to complete, but for the life of me, cannot figure it out. Here is how I am using the library:
import botdetect.web.jsf.JsfCaptcha;
[...]
#ManagedBean
#RequestScoped
public class MySampleBean implements Serializable {
private JsfCaptcha captcha;
private String captchaCode;
getters for above two fields
[...]
setters for above two fields
[...]
public boolean checkInputMatches() {
if (!this.captcha.validate(captchaCode)) {
return true;
}
return false;
}
}
The method checkInputMatches() demonstrates how the library validates that the user has entered in the right captcha solution. What I'd want to do now is, for debugging purposes, is to log out what the solution was ( In the event that the user entered in the wrong value ). Potentially, something like this:
final String solution = captcha.getCorrectSolutionToCaptcha();
At first, I've taken a look through all of the public getters, but none of them are blatant in providing me the data I need. After trying all of them, I went down the jdgui route, where I decompiled the libraries and tried to hunt my way around to a solution / method that would give me this data.
Sadly, the JsfCaptcha class goes under 5-6 levels of base class extending, with a multitude of protected / private methods. Obviously, a very tedious and unnecessary hunt for something very simple.
Is it possible to print out the actual JsfCaptcha value that is being validated against?
I finally managed to solve the problem with javassist, by modifying the generated bytecode of the Botdetect library. I did this because I was unable to find any getter method for accessing the actual captcha solution. Obviously, this is not a clean solution, but it is a solution given that you just want to debug your code to determine why the code you entered does not match the code that the backend server has. For now, I'll consider this as a solution until there is a cleaner alternative requiring no bytecode manipulation. Here are the details on the version that I played with and got this to work:
botdetect-4.0.beta3.5jar
botdetect-jsf20-4.0.beta3.5.jar
botdetect-servlet-4.0.beta3.5.jar
When the checkInputMatches() method executes to validate the captcha, this structure is executed on the backend with respect to the mentioned jars:
Step 1: ( botdetect-jsf20-4.0.beta3.5.jar )
com.captcha.botdetect.web.jsf.JsfCaptcha ->
public boolean validate(String paramString)
Step 2: ( botdetect-servlet-4.0.beta3.5.jar )
com.captcha.botdetect.web.servlet.Captcha ->
public boolean validate(String paramString)
Step 3: ( botdetect-jsf20-4.0.beta3.5.jar )
com.captcha.botdetect.internal.core.CaptchaBase ->
public boolean validate(String paramString1, String paramString2, ValidationAttemptOrigin paramValidationAttemptOrigin, boolean paramBoolean)
Step 4: ( botdetect-jsf20-4.0.beta3.5.jar )
com.captcha.botdetect.internal.core.captchacode.CodeCollection ->
public final boolean a(String paramString1, String paramString2, Integer paramInteger, boolean paramBoolean, ValidationAttemptOrigin paramValidationAttemptOrigin)
Step 5: Observe $3 ( third argument from Step 4 ) to show the actual code.
Here is a photo using jdgui, through which I came to this conclusion:
With that in mind, here is how you can go about printing that value out when that code is executed using javassits ( I am using javassist-3.18.1-GA.jar , on Tomcat ) :
#ManagedBean(eager = true)
#ApplicationScoped
public class CustomBean implements Serializable {
private static final long serialVersionUID = 3121378662264771535L;
private static Logger LOG = LogManager.getLogger(CustomBean.class.getName());
#PostConstruct
public void initialize() {
try {
final ClassPool classPool = new ClassPool(ClassPool.getDefault());
classPool.insertClassPath(new ClassClassPath(this.getClass()));
classPool.insertClassPath(new LoaderClassPath(Thread.currentThread().getContextClassLoader()));
final CtClass codeCollectionClass = classPool
.get("com.captcha.botdetect.internal.core.captchacode.CodeCollection");
if (!codeCollectionClass.isFrozen()) {
final CtMethod aMethod = codeCollectionClass.getDeclaredMethod("a",
new CtClass[] { classPool.get("java.lang.String"), classPool.get("java.lang.String"),
classPool.get("java.lang.Integer"), classPool.get("boolean"),
classPool.get("com.captcha.botdetect.internal.core."
+ "captchacode.validation.ValidationAttemptOrigin") });
aMethod.insertAfter("System.out.println(\"Botdetect-DEBUG: entered-captcha: \" + "
+ "$1 + \"; expected-captcha: \" + $3 + \";\" );");
codeCollectionClass.toClass();
} else {
LOG.error("Frozen class : Unable to re-compile BotDetect for debugging.");
}
} catch (final Exception e) {
LOG.error("unable to modify the bot detect java code", e);
}
}
}
Given this input and challenge:
You get a message like this in your logs:
Botdetect-DEBUG: entered-captcha: U33aZ; expected-captcha: U49a6;
I am sorry this isn't a 'coding' question, but after some considerable time on the learning path with XPages and Java I still struggle with finding definitive information on the correct way to carry out the basics.
When developing an XPages application using Java which is the best or most efficient method for accessing data?
1) Setting up and maintaining a View, with a column for every field in the document and retrieving data by ViewEntry.getColumnValues().get(int); i.e. not accessing the document and retrieving the data from the view. Which is what I have been doing but my View Columns are continuing to increase along with the hassle of maintaining column sequences. My understanding is this a faster method.
or
2) Just drop everything into a document using a View only when necessary, but in the main using Database.getDocumentByUNID().getItemValueAsString("field") and not worrying about adding lots of columns, far easier to maintain, but is accessing the document slowing things down?
Neither 1) or 2).
Go this way to manage document's data in a Java class:
Read document's items all at once in your Java class into class fields
remember UNID in a class field too
recycle document after reading items
get document again with the help of UNID for every read/write and recycle afterwards
Database.getDocumentByUNID() is quite fast but call it only once for a document and not for every item.
Update
As you mentioned in a comment, you have a database with 50.000 documents of various types.
I'd try to read only those documents you really need. If you want to read e.g. all support ticket documents of a customer you would use a view containing support tickets sorted by customer (without additional columns). You would get the documents with getAllDocumentsByKey(customer, true) and put the Java objects (each based on a document) into a Map.
You can maintain a cache in addition. Create a Map of models (model = Java object for a document type) and use UNID as key. This way you can avoid to read/store documents twice.
This is a really great question. I would first say that I agree 100% with Knut and that's how I code my objects that represent documents.
Below I've pasted a code example of what I typically do. Note this code is using the OpenNTF Domino API which among other things takes care of recycling for me. So you won't see any recycle calls.
But as Knut says - grab the document. Get what you need for it then it can be discarded again. When you want to save something just get the document again. At this stage you could even check lastModified or something to see of another save took place since the time you loaded it.
Sometimes for convenience I overload the load() method and add a NotesViewEntry :
public boolean load(ViewEntry entry) {}
Then in there I could just get the document, in if it's a specific situation use view columns.
Now this works great when dealing with a single document at a time. It works really well if I want to loop through many documents for a collection. But if you get too many you might see some of the overheard start to slow things down. One app I have if I "injest" 30,000 docs like this into a collection it can get a little slow.
I don't have a great answer for this yet. I've tried the big view with many columns thing like it sounds like you did. I've tried creating a lower level basic version of the object with just needed fields and that was more designed to work on viewEntry and their columns. I don't have a great answer for that yet. Making sure you lazy load what you can is pretty important I think.
Anyway here's a code example that shows how I build most of my document driven objects.
package com.notesIn9.video;
import java.io.Serializable;
import java.util.Date;
import org.openntf.domino.Database;
import org.openntf.domino.Document;
import org.openntf.domino.Session;
import org.openntf.domino.View;
import org.openntf.domino.utils.Factory;
public class Episode implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String title;
private Double number;
private String authorId;
private String contributorId;
private String summary;
private String subTitle;
private String youTube;
private String libsyn;
private Date publishedDate;
private Double minutes;
private Double seconds;
private String blogLink;
private boolean valid;
private String unid;
private String unique;
private String creator;
public Episode() {
this.unid = "";
}
public void create() {
Session session = Factory.getSession(); // this will be slightly
// different if not using the
// OpenNTF Domino API
this.setUnique(session.getUnique());
this.setCreator(session.getEffectiveUserName());
this.valid = true;
}
public Episode load(Document doc) {
this.loadValues(doc);
return this;
}
public boolean load(String key) {
// this key is the unique key of the document. UNID would be
// faster/easier.. I just kinda hate using them and seeing them in URLS
Session session = Factory.getSession();
Database currentDb = session.getCurrentDatabase();
Database db = session.getDatabase(currentDb.getServer(), "episodes.nsf");
View view = db.getView("lkup_episodes");
Document doc = view.getDocumentByKey(key); // This is deprecated because
// the API prefers to use
// getFirstDocumentByKey
if (null == doc) {
// document not found. DANGER
this.valid = false;
} else {
this.loadValues(doc);
}
return this.valid;
}
private void loadValues(Document doc) {
this.title = doc.getItemValueString("title");
this.number = doc.getItemValueDouble("number");
this.authorId = doc.getItemValueString("authorId");
this.contributorId = doc.getItemValueString("contributorId");
this.summary = doc.getItemValueString("summary");
this.subTitle = doc.getItemValueString("subtitle");
this.youTube = doc.getItemValueString("youTube");
this.libsyn = doc.getItemValueString("libsyn");
this.publishedDate = doc.getItemValue("publishedDate", Date.class);
this.minutes = doc.getItemValueDouble("minutes");
this.seconds = doc.getItemValueDouble("seconds");
this.blogLink = doc.getItemValueString("blogLink");
this.unique = doc.getItemValueString("unique");
this.creator = doc.getItemValueString("creator");
this.unid = doc.getUniversalID();
this.valid = true;
}
public boolean save() {
Session session = Factory.getSession();
Database currentDb = session.getCurrentDatabase();
Database db = session.getDatabase(currentDb.getServer(), "episodes.nsf");
Document doc = null;
if (this.unid.isEmpty()) {
doc = db.createDocument();
doc.replaceItemValue("form", "episode");
this.unid = doc.getUniversalID();
} else {
doc = db.getDocumentByUNID(this.unid);
}
this.saveValues(doc);
return doc.save();
}
private void saveValues(Document doc) {
doc.replaceItemValue("title", this.title);
doc.replaceItemValue("number", this.number);
doc.replaceItemValue("authorId", this.authorId);
doc.replaceItemValue("contributorId", this.contributorId);
doc.replaceItemValue("summary", this.summary);
doc.replaceItemValue("subtitle", this.subTitle);
doc.replaceItemValue("youTube", this.youTube);
doc.replaceItemValue("libsyn", this.libsyn);
doc.replaceItemValue("publishedData", this.publishedDate);
doc.replaceItemValue("minutes", this.minutes);
doc.replaceItemValue("seconds", this.seconds);
doc.replaceItemValue("blogLink", this.blogLink);
doc.replaceItemValue("unique", this.unique);
doc.replaceItemValue("creator", this.creator);
}
// getters and setters removed to condense code.
public boolean remove() {
Session session = Factory.getSession();
Database currentDb = session.getCurrentDatabase();
Database db = session.getDatabase(currentDb.getServer(), "episodes.nsf");
if (this.unid.isEmpty()) {
// this is a new Doc
return false;
} else {
Document doc = db.getDocumentByUNID(this.getUnid());
return doc.remove(true);
}
}
}
It's all about balance. everything has its price. Big views (case 1) slow down indexing. Opening documents every time (case 2) slows down your code.
Find something in between.
I am looking for advice on where to add validation rules for domain entities, and best practices for implementation. I did search and did not find what i was looking for, or i missed it.
I would like to know what the recommended way is for validating that properties are not null, in a certain range, or length, etc... I have seen several ways using an IsValid() and other discussions about enforcing in the constructor so the entity is never in an invalid state, or using preprocessing and postprocessing, and others using FluentValidation api, how invariants impact DRY and SRP.
Can someone give me a good example of where to put these sorts of checks, when using a App Service, Bounded Context, Domain Service, Aggregate Root, Entity layering. Where does this go, and what is the best approach?
Thanks.
When modeling your domain entity, it is best to consider real-world implications. Let's say you are dealing with a Employee entity.
Employees need a name
We know that in the real-world an employee must always have a name. It is impossible for an employee not to have a name. In other words, one cannot 'construct' an employee without specifying its name. So, use parameterised constructors! We also know that an employees name cannot change - so we prevent this from even happening by creating a private setter. Using the .NET type system to verify your employee is a very strong form of validation.
public string Name { get; private set; }
public Employee(string name)
{
Name = name;
}
Valid names have some rules
Now it starts to get interesting. A name has certain rules. Let's just take the simplistic route and assume that a valid name is one which is not null or empty. In the code example above, the following business rule is not validated against. At this point, we can still currently create invalid employees! Let's prevent this from EVER occurring by amending our setter:
public string Name
{
get
{
return name;
}
private set
{
if (String.IsNullOrWhiteSpace(value))
{
throw new ArgumentOutOfRangeException("value", "Employee name cannot be an empty value");
}
name = value;
}
}
Personally I prefer to have this logic in the private setter than in the constructor. The setter is not completely invisible. The entity itself can still change it, and we need to ensure validity. Also, always throw exceptions!
What about exposing some form of IsValid() method?
Take the above Employee entity. Where and how would an IsValid() method work?
Would you allow an invalid Employee to be created and then expect the developer to check it's validity with an IsValid() check? This is a weak design - before you know it, nameless Employees are going to be cruising around your system causing havoc.
But perhaps you would like to expose the name validation logic?
We don't want to catch exceptions for control flow. Exceptions are for catastrophic system failure. We also don't want to duplicate these validation rules in our codebase. So, perhaps exposing this validation logic isn't such a bad idea (but still not the greatest!).
What you could do is provide a static IsValidName(string) method:
public static bool IsValidName(string name)
{
return (String.IsNullOrWhiteSpace(value))
}
Our property would now change somewhat:
public string Name
{
get
{
return name;
}
private set
{
if (!Employee.IsValidName(value))
{
throw new ArgumentOutOfRangeException("value", "Employee name cannot be an empty value");
}
name = value;
}
}
But there is something fishy about this design...
We now are starting to spawn validation methods for individual properties of our entity. If a property has all kinds of rules and behavior attached to it, perhaps this is a sign that we can create an value object for it!
public PersonName : IEquatable<PersonName>
{
public string Name
{
get
{
return name;
}
private set
{
if (!PersonName.IsValid(value))
{
throw new ArgumentOutOfRangeException("value", "Person name cannot be an empty value");
}
name = value;
}
}
private PersonName(string name)
{
Name = name;
}
public static PersonName From(string name)
{
return new PersonName(name);
}
public static bool IsValid(string name)
{
return !String.IsNullOrWhiteSpace(value);
}
// Don't forget to override .Equals
}
Now our Employee entity can be simplified (I have excluded a null reference check):
public Employee
{
public PersonName Name { get; private set; }
public Employee(PersonName name)
{
Name = name;
}
}
Our client code can now look something like this:
if(PersonName.IsValid(name))
{
employee = new Employee(PersonName.From(name));
}
else
{
// Send a validation message to the user or something
}
So what have we done here?
We have ensured that our domain model is always consistent. Extremely important. An invalid entity cannot be created. In addition, we have used value objects to provide further 'richness'. PersonName has given the client code more control and more power and has also simplified Employee.
I built a library that can help you.
https://github.com/mersocarlin/ddd-validation
I'm creating a SharePoint application, and am trying some new things to create what amounts to an API for Data Access to maintain consistency and conventions.
I haven't seen this before, and that makes me think it might be bad :)
I've overloaded the constructor for class Post to only take an SPListItem as a parameter. I then have an embedded Generic List of Post that takes an SPListItemCollection in the method signature.
I loop through the items in a more efficient for statement, and this means if I ever need to add or modify how the Post object is cast, I can do it in the Class definition for a single source.
class Post
{
public int ID { get; set; }
public string Title { get; set; }
public Post(SPListItem item)
{
ID = item.ID;
Title = (string)item["Title"];
}
public static List<Post> Posts(SPListItemCollection _items)
{
var returnlist = new List<Post>();
for (int i = 0; i < _items.Count; i++) {returnlist.Add(new Post(_items[i]));}
return returnlist;
}
}
This enables me to do the following:
static public List<Post> GetPostsByCommunity(string communityName)
{
var targetList = CoreLists.SystemAccount.Posts(); //CAML emitted for brevity
return Post.Posts(targetList.GetItems(query)); //Call the constructor
}
Is this a bad idea?
This approach might be suitable, but that FOR loop causes some concern. _items.Count will force the SPListItemCollection to retrieve ALL those items in the list from the database. With large lists, this could either a) cause a throttling exception, or b) use up a lot of resources. Why not use a FOREACH loop? With that, I think the SPListItems are retrieved and disposed one at a time.
If I were writing this I would have a 'Posts' class as well 'Post', and give it the constructor accepting the SPListItemCollection.
To be honest, though, the few times I've seen people try and wrap SharePoint SPListItems, it's always ended up seeming more effort than it's worth.
Also, if you're using SharePoint 2010, have you considered using SPMetal?