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 ??? } }