is-registry/src/org/gcube/informationsystem/registry/impl/contexts/ServiceContext.java

235 lines
8.2 KiB
Java

package org.gcube.informationsystem.registry.impl.contexts;
import java.io.StringWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.gcube.common.core.contexts.GCUBEServiceContext;
import org.gcube.common.core.contexts.GHNContext;
import static org.gcube.common.core.contexts.GHNContext.Mode;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.queries.GCUBERIQuery;
import org.gcube.common.core.informationsystem.publisher.ISLocalPublisher;
import org.gcube.common.core.informationsystem.publisher.ISLocalPublisher.LocalProfileConsumer;
import org.gcube.common.core.resources.GCUBEResource;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.events.GCUBEProducer;
import org.gcube.common.core.utils.events.GCUBETopic;
import org.gcube.common.core.utils.handlers.GCUBEHandler;
import org.gcube.common.core.utils.handlers.GCUBEScheduledHandler;
import org.gcube.informationsystem.registry.impl.porttypes.RegistryFactory;
import org.gcube.informationsystem.registry.impl.resourcemanagement.EliminatePoolingThread;
import org.gcube.informationsystem.registry.impl.state.RegistryFactoryResource;
import org.gcube.informationsystem.registry.stubs.CreateResourceMessage;
import org.gcube.informationsystem.registry.stubs.RemoveResourceMessage;
import org.gcube.informationsystem.registry.stubs.UpdateResourceMessage;
/**
* IS-Registry service context
*
* @author Andrea Manzi, Manuele Simi , Lucio lelii (CNR)
*
*/
public class ServiceContext extends GCUBEServiceContext {
public static final String JNDI_NAME = "gcube/informationsystem/registry";
public static Map<String, EliminatePoolingThread> threadTable = Collections.synchronizedMap(new HashMap<String, EliminatePoolingThread>());
protected static final ServiceContext cache = new ServiceContext();
protected ISClient client = null;
protected GCUBERIQuery queryRI = null;
public static enum RegistryTopic implements GCUBETopic{CREATE,UPDATE, REMOVE};
//protected GCUBEResourceXPathQuery queryGHN = null;
protected boolean isNotifierCodeployed = false;
protected boolean isICCodeployed = false;
protected GCUBEProducer<RegistryTopic, GCUBEResource> topicProducer;
protected class NotificationResourceScheduler extends GCUBEScheduledHandler {
public NotificationResourceScheduler(long interval, Mode mode) {
super(interval, mode);
}
@Override
protected boolean repeat(Exception exception, int exceptionCount) {
if (exception!=null) {
logger.warn("Failed to create the notification resource (attempt "+exceptionCount+" out of 20)",exception);
if (exceptionCount >= 20) {
logger.error("Max attempts reached, no more chance to register the notification resource");
return false;
} else
return true;
} else
return false;
}
}
private ServiceContext() {}
/**
*
* @return ServiceContext
*/
public static ServiceContext getContext() {
return cache;
}
/**
* @return the JNDI name
*/
@Override
public String getJNDIName() {
return JNDI_NAME;
}
/**
*
* @return GCUBEProducer
*/
public GCUBEProducer<RegistryTopic, GCUBEResource> getTopicProducer(){
return topicProducer;
}
@SuppressWarnings("unchecked")
@Override
protected void onReady() throws Exception {
//switch to the production mode if needed
if (GHNContext.getContext().getMode() == Mode.ROOT)
GHNContext.getContext().setMode(Mode.CONNECTED);
//creates the single RegistryResource used to raise notifications about profiles' changes
logger.info("Scheduling IS-Registry notification resource...");
for (GCUBEScope scope: ServiceContext.getContext().getInstance().getScopes().values()){
EliminatePoolingThread ept= new EliminatePoolingThread();
ServiceContext.getContext().setScope(ept, scope);
ept.start();
threadTable.put(scope.getName(), ept);
}
NotificationResourceScheduler scheduler = new NotificationResourceScheduler(20, GCUBEScheduledHandler.Mode.LAZY);
scheduler.setHandled(new GCUBEHandler(){
@Override
public void run() throws Exception {
try {
for (GCUBEScope scope: ServiceContext.getContext().getInstance().getScopes().values())
{
ServiceContext.getContext().setScope(scope);
RegistryFactoryResource resource = (RegistryFactoryResource) FactoryContext.getContext().getWSHome().create(FactoryContext.getContext().makeKey(RegistryFactory.NOTIFICATOR_RESOURCE_KEY));
resource.store();
}
} catch (Exception e) {
logger.error("Failed to create the resource", e);
}
}
});
scheduler.run();
this.subscribeToLocalRegistrationEvents();
}
@Override
protected void onInitialisation() throws Exception {
this.client = GHNContext.getImplementation(ISClient.class);
topicProducer= new GCUBEProducer<RegistryTopic, GCUBEResource>();
//topicProducer.registerTopics(RegistryTopic.CREATE, RegistryTopic.UPDATE, RegistryTopic.REMOVE);
}
private void subscribeToLocalRegistrationEvents() throws Exception{
ISLocalPublisher pub = GHNContext.getImplementation(ISLocalPublisher.class);
LocalProfileConsumer cons = new LocalProfileConsumer() {
/* (non-Javadoc)
* @see org.gcube.common.core.informationsystem.publisher.ISLocalPublisher.LocalProfileConsumer#onProfileRegistered(org.gcube.common.core.resources.GCUBEResource)
*/
@Override
protected void onProfileRegistered(GCUBEResource resource, GCUBEScope scope) {
logger.debug("onProfileRegistered event received" );
RegistryFactory factory= new RegistryFactory();
try {
ServiceContext.getContext().setScope(scope);
CreateResourceMessage crm = new CreateResourceMessage();
StringWriter writer = new StringWriter();
resource.store(writer);
crm.setProfile(writer.toString());
crm.setType(resource.getType());
factory.createResource(crm);
logger.trace("create Event handled");
} catch (Exception e) {
logger.error("cannot handle the create resource event"+e);
}
}
/* (non-Javadoc)
* @see org.gcube.common.core.informationsystem.publisher.ISLocalPublisher.LocalProfileConsumer#onProfileRemoved(java.lang.String, java.lang.String)
*/
@Override
protected void onProfileRemoved(String resourceID, String type, GCUBEScope scope) {
ServiceContext.getContext().setScope(scope);
RegistryFactory factory= new RegistryFactory();
RemoveResourceMessage rrm= new RemoveResourceMessage();
rrm.setType(type);
rrm.setUniqueID(resourceID);
logger.trace("remove Event handled");
try {
factory.removeResource(rrm);
} catch (Exception e) {
logger.error("cannot handle the remove resource event"+e);
}
}
/* (non-Javadoc)
* @see org.gcube.common.core.informationsystem.publisher.ISLocalPublisher.LocalProfileConsumer#onProfileUpdated(org.gcube.common.core.resources.GCUBEResource)
*/
@Override
protected void onProfileUpdated(GCUBEResource resource, GCUBEScope scope) {
logger.debug("onProfileUpdated event received" );
ServiceContext.getContext().setScope(scope);
RegistryFactory factory= new RegistryFactory();
try {
UpdateResourceMessage urm= new UpdateResourceMessage();
StringWriter writer = new StringWriter();
resource.store(writer);
urm.setXmlProfile(writer.toString());
urm.setType(resource.getType());
urm.setUniqueID(resource.getID());
factory.updateResource(urm);
logger.trace("Update Event handled");
} catch (Exception e) {
logger.error("cannot handle the update resource event"+e);
}
}
};
pub.subscribeLocalProfileEvents(cons);
}
}