Skip to content

Commit

Permalink
TEIID-4024 fixing hang with rest war shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Mar 8, 2016
1 parent dba34ae commit 1d14928
Show file tree
Hide file tree
Showing 20 changed files with 101 additions and 177 deletions.
Expand Up @@ -123,11 +123,11 @@ public void removed(String name, int version, CompositeVDB vdb) {
}

@Override
public void added(String name, int version, CompositeVDB vdb, boolean reloading) {
public void added(String name, int version, CompositeVDB vdb) {
}

@Override
public void finishedDeployment(String name, int version, CompositeVDB cvdb, boolean reloading) {
public void finishedDeployment(String name, int version, CompositeVDB cvdb) {
}

@Override
Expand Down
Expand Up @@ -21,55 +21,20 @@
*/
package org.teiid.jboss;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.jboss.as.controller.ControlledProcessState;
import org.jboss.as.controller.ControlledProcessStateService;
import org.jboss.msc.service.AbstractServiceListener;
import org.jboss.msc.service.ServiceContainer.TerminateListener;
import org.jboss.msc.service.ServiceController;
import org.jboss.as.controller.ControlledProcessState.State;
import org.jboss.as.controller.access.Environment;
import org.teiid.deployers.ContainerLifeCycleListener;

class JBossLifeCycleListener extends AbstractServiceListener<Object> implements TerminateListener, ContainerLifeCycleListener {
private boolean shutdownInProgress = false;
private List<ContainerLifeCycleListener.LifeCycleEventListener> listeners = Collections.synchronizedList(new ArrayList<ContainerLifeCycleListener.LifeCycleEventListener>());
private ControlledProcessStateService state;
class JBossLifeCycleListener implements ContainerLifeCycleListener {
private Environment environment;

@Override
public boolean isShutdownInProgress() {
return shutdownInProgress;
public JBossLifeCycleListener(Environment environment) {
this.environment = environment;
}

@Override
public boolean isBootInProgress() {
return state.getCurrentState().equals(ControlledProcessState.State.STARTING);
}

@Override
public void handleTermination(Info info) {
if (info.getShutdownInitiated() > 0) {
this.shutdownInProgress = true;
}
}

@Override
public void addListener(LifeCycleEventListener listener) {
listeners.add(listener);
public boolean isShutdownInProgress() {
return environment.getProcessState() == State.STOPPING;
}

@Override
public void transition(final ServiceController controller, final ServiceController.Transition transition) {
if (transition.equals(ServiceController.Transition.UP_to_STOP_REQUESTED)) {
this.shutdownInProgress = true;
}
else if (transition.equals(ServiceController.Transition.STOP_REQUESTED_to_UP)) {
this.shutdownInProgress = false;
}
}

void setControlledProcessStateService(ControlledProcessStateService state) {
this.state = state;
}
}
24 changes: 14 additions & 10 deletions jboss-integration/src/main/java/org/teiid/jboss/TeiidAdd.java
Expand Up @@ -44,7 +44,16 @@

import org.infinispan.manager.EmbeddedCacheManager;
import org.jboss.as.clustering.jgroups.ChannelFactory;
import org.jboss.as.controller.*;
import org.jboss.as.controller.AbstractAddStepHandler;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.ProcessType;
import org.jboss.as.controller.ServiceVerificationHandler;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.access.Environment;
import org.jboss.as.controller.registry.ImmutableManagementResourceRegistration;
import org.jboss.as.controller.registry.Resource;
import org.jboss.as.controller.services.path.RelativePathService;
Expand All @@ -54,15 +63,13 @@
import org.jboss.as.naming.service.BinderService;
import org.jboss.as.server.AbstractDeploymentChainStep;
import org.jboss.as.server.DeploymentProcessorTarget;
import org.jboss.as.server.Services;
import org.jboss.as.server.deployment.Phase;
import org.jboss.dmr.ModelNode;
import org.jboss.modules.Module;
import org.jboss.modules.ModuleIdentifier;
import org.jboss.modules.ModuleLoadException;
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceBuilder.DependencyType;
import org.jboss.msc.service.ServiceContainer;
import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceTarget;
Expand Down Expand Up @@ -188,8 +195,6 @@ private void initilaizeTeiidEngine(final OperationContext context, final ModelNo
throws OperationFailedException {
ServiceTarget target = context.getServiceTarget();

final JBossLifeCycleListener shutdownListener = new JBossLifeCycleListener();

final String asyncThreadPoolName = asString(ASYNC_THREAD_POOL_ELEMENT, operation, context);

// translator repository
Expand Down Expand Up @@ -413,11 +418,10 @@ public PreParser getValue() throws IllegalStateException, IllegalArgumentExcepti
engineBuilder.setInitialMode(ServiceController.Mode.ACTIVE);
ServiceController<DQPCore> controller = engineBuilder.install();
newControllers.add(controller);
ServiceContainer container = controller.getServiceContainer();
container.addTerminateListener(shutdownListener);
container.getService(Services.JBOSS_SERVER_CONTROLLER).addListener(shutdownListener);
shutdownListener.setControlledProcessStateService((ControlledProcessStateService)container.getService(ControlledProcessStateService.SERVICE_NAME).getValue());

Environment environement = context.getCallEnvironment();

final JBossLifeCycleListener shutdownListener = new JBossLifeCycleListener(environement);

// add JNDI for event distributor
final ReferenceFactoryService<EventDistributorFactory> referenceFactoryService = new ReferenceFactoryService<EventDistributorFactory>();
final ServiceName referenceFactoryServiceName = TeiidServiceNames.EVENT_DISTRIBUTOR_FACTORY.append("reference-factory"); //$NON-NLS-1$
Expand Down
12 changes: 6 additions & 6 deletions jboss-integration/src/main/java/org/teiid/jboss/VDBService.java
Expand Up @@ -130,7 +130,7 @@ public void start(final StartContext context) throws StartException {
final ServiceBuilder<Void> vdbService = addVDBFinishedService(context);
this.vdbListener = new VDBLifeCycleListener() {
@Override
public void added(String name, int version, CompositeVDB cvdb, boolean reloading) {
public void added(String name, int version, CompositeVDB cvdb) {
}
@Override
public void beforeRemove(String name, int version, CompositeVDB cvdb) {
Expand All @@ -140,7 +140,7 @@ public void removed(String name, int version, CompositeVDB cvdb) {
}

@Override
public void finishedDeployment(String name, int version, CompositeVDB cvdb, boolean reloading) {
public void finishedDeployment(String name, int version, CompositeVDB cvdb) {
if (!name.equals(VDBService.this.vdb.getName()) || version != VDBService.this.vdb.getVersion()) {
return;
}
Expand Down Expand Up @@ -176,15 +176,15 @@ public void finishedDeployment(String name, int version, CompositeVDB cvdb, bool
}
this.assignMetadataRepositories(vdb, defaultRepo);
// add transformation metadata to the repository.
getVDBRepository().addVDB(this.vdb, store, vdbResources.getEntriesPlusVisibilities(), udf, cmr, this.shutdownListener.isBootInProgress());
getVDBRepository().addVDB(this.vdb, store, vdbResources.getEntriesPlusVisibilities(), udf, cmr);
} catch (VirtualDatabaseException e) {
cleanup(context);
throw new StartException(e);
}

this.vdb.removeAttachment(UDFMetaData.class);
try {
loadMetadata(this.vdb, cmr, store, this.vdbResources, this.shutdownListener.isBootInProgress());
loadMetadata(this.vdb, cmr, store, this.vdbResources);
} catch (TranslatorException e) {
cleanup(context);
throw new StartException(e);
Expand Down Expand Up @@ -413,7 +413,7 @@ public void run() {
cacheMetadataStore(model, factory);
}

metadataLoaded(vdb, model, vdbMetadataStore, loadCount, factory, true, VDBService.this.shutdownListener.isBootInProgress());
metadataLoaded(vdb, model, vdbMetadataStore, loadCount, factory, true);
} else {
String errorMsg = ex.getMessage()==null?ex.getClass().getName():ex.getMessage();
if (te != null) {
Expand All @@ -423,7 +423,7 @@ public void run() {
model.setMetadataStatus(Model.MetadataStatus.FAILED);
LogManager.logWarning(LogConstants.CTX_RUNTIME, ex, IntegrationPlugin.Util.gs(IntegrationPlugin.Event.TEIID50036,vdb.getName(), vdb.getVersion(), model.getName(), errorMsg));
if (ex instanceof RuntimeException) {
metadataLoaded(vdb, model, vdbMetadataStore, loadCount, factory, false, VDBService.this.shutdownListener.isBootInProgress());
metadataLoaded(vdb, model, vdbMetadataStore, loadCount, factory, false);
} else {
if (marked != null) {
getExecutor().execute(this);
Expand Down
Expand Up @@ -25,13 +25,11 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;

import org.jboss.as.controller.ModelController;
import org.teiid.adminapi.*;
import org.teiid.adminapi.AdminException;
import org.teiid.adminapi.VDB.Status;
import org.teiid.adminapi.impl.ModelMetaData;
import org.teiid.adminapi.impl.VDBMetaData;
Expand All @@ -50,52 +48,30 @@

public class ResteasyEnabler implements VDBLifeCycleListener {
static final String REST_NAMESPACE = "{http://teiid.org/rest}"; //$NON-NLS-1$
private Admin admin;
private AdminImpl admin;
private Executor executor;
private String vdbName;
private int vdbVersion;
private AtomicBoolean deployed = new AtomicBoolean(false);
private ContainerLifeCycleListener shutdownListener;

public ResteasyEnabler(String vdbName, int version, ModelController deployer, Executor executor, ContainerLifeCycleListener shutdownListener) {
this.admin = AdminFactory.getInstance().createAdmin(deployer.createClient(executor));
this.admin = (AdminImpl)AdminFactory.getInstance().createAdmin(deployer.createClient(executor));
this.executor = executor;
this.vdbName = vdbName;
this.vdbVersion = version;
this.shutdownListener = shutdownListener;
}

@Override
public synchronized void added(String name, int version, CompositeVDB vdb, boolean reloading) {
public synchronized void added(String name, int version, CompositeVDB vdb) {
}

@Override
public void beforeRemove(String name, int version, CompositeVDB cvdb) {
if (this.vdbName.equals(name) && this.vdbVersion == version) {

// we only want un-deploy what is auto-generated previously
final String warName = buildName(name, version);

if (this.deployed.get()) {
this.deployed.set(false);
if (!this.shutdownListener.isShutdownInProgress()) {
this.executor.execute(new Runnable() {
@Override
public void run() {
try {
((AdminImpl)admin).undeploy(warName, true);
} catch (AdminException e) {
// during shutdown some times the logging and other subsystems are shutdown, so this operation may not succeed.
LogManager.logWarning(LogConstants.CTX_RUNTIME, IntegrationPlugin.Util.getString("failed_to_remove", warName)); //$NON-NLS-1$
}
}
});
}
}
}
this.deployed.set(false);
}

@Override
public synchronized void finishedDeployment(String name, int version, CompositeVDB cvdb, boolean reloading) {
public synchronized void finishedDeployment(String name, int version, CompositeVDB cvdb) {
if (this.vdbName.equals(name) && this.vdbVersion == version) {

final VDBMetaData vdb = cvdb.getVDB();
Expand All @@ -109,8 +85,7 @@ public synchronized void finishedDeployment(String name, int version, CompositeV
final String warName = buildName(name, version);
if (generate != null && Boolean.parseBoolean(generate)
&& hasRestMetadata(vdb)
&& !this.deployed.get()
&& !reloading) {
&& !this.deployed.get()) {

this.deployed.set(true);

Expand All @@ -120,7 +95,14 @@ public void run() {
try {
RestASMBasedWebArchiveBuilder builder = new RestASMBasedWebArchiveBuilder();
byte[] warContents = builder.createRestArchive(vdb);
((AdminImpl)admin).deploy(warName, new ByteArrayInputStream(warContents), true);
if (!vdb.getStatus().equals(Status.ACTIVE)) {
return;
}
if (admin.getDeployments().contains(warName)) {
admin.undeploy(warName);
}
//make it a non-persistent deployment
admin.deploy(warName, new ByteArrayInputStream(warContents), false);
} catch (FileNotFoundException e) {
LogManager.logWarning(LogConstants.CTX_RUNTIME, e, IntegrationPlugin.Util.getString("failed_to_add", warName)); //$NON-NLS-1$
} catch (IOException e) {
Expand All @@ -131,27 +113,7 @@ public void run() {
}
};

if (!((AdminImpl) admin).getDeployments().contains(warName)) {
executor.execute(job);
}
else {
// there is timing issue in terms of replacement/re-deploy where remove/add can not be
// synchronized correctly. it would have better if there was a way we could inject dependency
// on war file
final Timer timer = new Timer("teiid-war-deployer", true); //$NON-NLS-1$
TimerTask task = new TimerTask() {
@Override
public void run() {
if (!((AdminImpl) admin).getDeployments().contains(warName)) {
executor.execute(job);
}
else {
LogManager.logWarning(LogConstants.CTX_RUNTIME, IntegrationPlugin.Util.getString("failed_to_add", warName)); //$NON-NLS-1$
}
}
};
timer.schedule(task, 3000L);
}
executor.execute(job);
}
}
}
Expand Down
Expand Up @@ -50,7 +50,7 @@ public class TestResteasyEnabler {
model.setModelType(Type.OTHER);
vdb.getVDB().addModel(model);

resteasyEnabler.finishedDeployment("x", 1, vdb, false);
resteasyEnabler.finishedDeployment("x", 1, vdb);
}

}
Expand Up @@ -143,7 +143,7 @@ public void removed(String name, int version, CompositeVDB vdb) {
}

@Override
public void finishedDeployment(String name, int version, CompositeVDB vdb,boolean reloading) {
public void finishedDeployment(String name, int version, CompositeVDB vdb) {
this.clientMap.remove(new VDBKey(name, version));
}

Expand All @@ -152,6 +152,6 @@ public void beforeRemove(String name, int version, CompositeVDB vdb) {
}

@Override
public void added(String name, int version, CompositeVDB vdb,boolean reloading) {
public void added(String name, int version, CompositeVDB vdb) {
}
}
5 changes: 2 additions & 3 deletions olingo/src/main/java/org/teiid/olingo/web/ODataFilter.java
Expand Up @@ -237,8 +237,7 @@ public void removed(String name, int version, CompositeVDB vdb) {
}

@Override
public void finishedDeployment(String name, int version, CompositeVDB vdb,
boolean reloading) {
public void finishedDeployment(String name, int version, CompositeVDB vdb) {
this.contextMap.remove(new VDBKey(name, version));
}

Expand All @@ -247,6 +246,6 @@ public void beforeRemove(String name, int version, CompositeVDB vdb) {
}

@Override
public void added(String name, int version, CompositeVDB vdb, boolean reloading) {
public void added(String name, int version, CompositeVDB vdb) {
}
}
Expand Up @@ -23,8 +23,6 @@

public interface ContainerLifeCycleListener {
boolean isShutdownInProgress();
boolean isBootInProgress();
void addListener(LifeCycleEventListener listener);

public static interface LifeCycleEventListener{
void onStartupFinish();
Expand Down
Expand Up @@ -62,7 +62,7 @@ public void removed(String name, int version, CompositeVDB vdb) {
}
}
@Override
public void finishedDeployment(String name, int version, CompositeVDB vdb, boolean reloading) {
public void finishedDeployment(String name, int version, CompositeVDB vdb) {
for(EventListener el:EventDistributorImpl.this.listeners) {
if (vdb.getVDB().getStatus().equals(Status.ACTIVE)) {
el.vdbLoaded(vdb.getVDB());
Expand All @@ -73,7 +73,7 @@ public void finishedDeployment(String name, int version, CompositeVDB vdb, boole
}
}
@Override
public void added(String name, int version, CompositeVDB vdb, boolean reloading) {
public void added(String name, int version, CompositeVDB vdb) {
for(EventListener el:EventDistributorImpl.this.listeners) {
el.vdbDeployed(name, version);
}
Expand Down

0 comments on commit 1d14928

Please sign in to comment.