Client Not Getting CDI Event From Server
chaluwa Dec 28, 2013 10:35 AMI am building a code structure that I think will simplify my app, but now some things stopped working. My client no longer seems to get CDI events from the server and I cannot tell if the problem is with the client or server setup.
Server Setup ::
public interface RESTService<T>{ // in shared package
@POST
@Path("/add")
@Consumes("application/json")
@Produces("application/json")
public T add(T entity);
@GET
@Path("/delete/{id:[0-9][0-9]*}")
@Produces("application/json")
public Response delete(@PathParam("id") Long id);
....
}
@Dependent
public class CRUD<T>{ // in server package
@Inject
private Logger log;
@Inject
protected EntityManager em;
@Inject
private UserTransaction tnx;
protected Class<T> clz;
protected String clzName;
public CRUD() {
super();
}
public CRUD(Class<T> clz) {
this.clz = clz;
this.clzName = this.clz.getSimpleName();
}
protected T createEntity(T entity){
log.severe("call to create " + this.clzName);
try {
tnx.begin();
entity = em.merge(entity);
tnx.commit();
} catch (Exception ex) {
ex.printStackTrace();
}
log.severe("created - " + this.clzName + ", returning call ...");
return entity;
}
protected boolean deleteEntity(Long id){
log.severe("call to delete " + this.clzName + " @ " + id);
boolean status = false;
try {
tnx.begin();
T entity = em.find(this.clz, id);
if(entity != null){
log.severe("found " + this.clzName + ", deleting it ... ");
em.remove(entity);
}
tnx.commit();
status = true;
} catch (Exception ex) {
ex.printStackTrace();
}
String str = (status == true ? "deleted - " : "cold not delete - ");
log.severe( str + this.clzName + " @ " + id + ", returning call ...");
return status;
}
...
}
// the next @Dependent class abstracts the base / common code from all
// classes that will implement the jax-rs interface to provide
// server-side functionality. M is the entity type and D is a CDI event type, fired when entity of type M is deleted.
// Watch the CDI events fired in add() and delete() methods, they are somehow missed by the client ???
@Dependent
public class BaseEndpoint<M, D extends DeleteEvent> extends CRUD<M> implements RESTService<M> { // in server package
@Inject
protected Logger log;
@Inject @New
protected Event<M> entityAdded; // fired when entity M is created and persisted
@Inject
protected Event<D> entityDeleted; // fired when entity M is deleted;
public BaseEndpoint() {
super();
}
public BaseEndpoint(Class<M> clz) {
super(clz);
}
protected D getDeleteEventObject(){
return null; // subclass to return instance of delete event type. need a better way.
}
@Override
public M add(M entity) { // defined in RESTService<M>
log.severe("lets add " + clzName + " - " + entity);
entity = createEntity(entity);
entityAdded.fire(entity); // not seen by client ???
log.severe("added " + entity + " and fired CDI event, returning call");
return entity;
}
@Override
public Response delete(Long id) { // defined in RESTService<M>
log.severe("lets delete " + clzName + " @ " + id);
boolean status = deleteEntity(id);
log.severe("deleted " + clzName + " @ " + id);
if(status){
D d = getDeleteEventObject();
if(d != null){
d.setEntityId(id);
entityDeleted.fire(d); // not seen by client ???
log.severe("fired delete CDI event for " + clzName + " @ " + id);
}
return Response.ok().build();
}
return Response.serverError().build();
}
}
// jax-rs sub-interface for "domain" specific actions if any
@Path("/putme/bundles")
public interface PutmeSubjectBundlesService extends RESTService<PutmeSubjectBundle> { // in shared package
}
// And now, the "server" implementation, similar in role to UserComplaintEndpointImpl from errai-tutorial demo
// PutmeSubjectBundle is the entity type and BundleDelete is the @Portable CDI event object type that gets
// fired when a PutmeSubjectBundle object is deleted. PutmeSubjectBundle is a simple default-constructable @Portable @Bindable @Entity
// and BundleDelete is a default-constructable @Portable pojo. All very simple and clear ...
@RequestScoped
public class PutmeSubjectBundlesEndpoint extends BaseEndpoint<PutmeSubjectBundle, BundleDelete> implements PutmeSubjectBundlesService {
public PutmeSubjectBundlesEndpoint() {
super(PutmeSubjectBundle.class);
}
@Override
protected BundleDelete getDeleteEventObject() { // give BaseEndpoint BundleDelete instance to fire
return new BundleDelete();
}
}
On the server, PutmeSubjectBundlesEndpoint can now effortless add and delete entities by extending BaseEndpoint. Only problem is that CDI events fired by the super-class BaseEndpoint, are "not getting" to the clients ?? Lets look at the client side code now.
@ApplicationScoped
@SuppressWarnings({"unused", "deprecation"})
public class PutmeBundlesPresenter{
public interface PutmeBundlesDisplay{
....
}
@Inject
private Caller<PutmeSubjectBundlesService> endpoint; // recall PutmeSubjectBundlesService above ??
@Inject
private PutmeBundlesView display; // the @Template @Page UI
public PutmeBundlesPresenter() {
super();
}
...
private void onAdd(@Observes @New PutmeSubjectBundle added){
LogUtil.log("added bundle"); // never gets called ???
}
private void onDelete(@Observes BundleDelete evt){
LogUtil.log("deleted bundle"); // never gets called ???
}
}
