Hi Jielin,
Thanks for the review.
But I need a one more round: Hong changed her mind :(, and asked me to
be able to support PRE_DEPLOY event even in the case of the 1st deploy
(if they ever need to add such an event).
The changes are minor, and the new version of the DeploymentEventListenerImpl
is attached (look for isDeploy).
thanks,
-marina
jielin wrote:
> Hi, Marina,
>
> Your changes are good.
>
> Thanks.
>
> Jielin
>
> Marina Vatkina wrote:
>
>> Hi Jielin,
>>
>> Please review the changes to the java2db processing required by issue
>> https://glassfish.dev.java.net/issues/show_bug.cgi?id=1038.
>>
>> The problem: files left sometimes locked by a "normal" redeploy
>> processing
>> on Windows. Ludo found out that Windows allow to override those files
>> even
>> though they do not allow to remove them (usually those are 3rd party
>> lib jars
>> and redeploy doesn't actually cause any changes to them).
>>
>> The solution: split redeploy event processing for java2db into PRE_DEPLOY
>> and POST_DEPLOY, where tables are dropped in PRE_DEPLOY and created in
>> POST_DEPLOY. No changes to the event processing in the 1st deploy or
>> undeploy
>> are expected.
>>
>> Note, that PRE_DEPLOY event can be only fired on redeploy.
>>
>> Also note, that for quite some time already our app server completely
>> wipes
>> out previously deployed application in case of a failed redeploy, so
>> it seems
>> logical to drop the tables also (what's good to have tables for an
>> undeployed
>> application?).
>>
>> And one more note - the corresponding code has changed its location
>> and had
>> been split into a base class and 2 subclasses since you've last
>> touched it to
>> add JPA processing.
>>
>> These changes actually simplify our processing logic a bit as there is no
>> need to calculate drop vs. create step. It can be simplified even
>> further,
>> but that would require to have too many 'if (create)' blocks.
>>
>> I've tested so far with RosterAppJ2DB (ear and jar), and persistence
>> example.
>> I'll test deploydir tomorrow as it was broken until today's fix by Jane.
>>
>> Please let me know if you have any questions.
>>
>> thanks,
>> -marina
>
>
/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
*
https://glassfish.dev.java.net/public/CDDLv1.0.html or
* glassfish/bootstrap/legal/CDDLv1.0.txt.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at glassfish/bootstrap/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* you own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
*/
/*
* DeploymentEventListenerImpl.java
*
* Created on April 8, 2003.
*/
package com.sun.jdo.spi.persistence.support.ejb.ejbc;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.Properties;
import java.util.Collection;
import com.sun.enterprise.util.io.FileUtils;
import com.sun.enterprise.deployment.Application;
import com.sun.enterprise.deployment.EjbBundleDescriptor;
import com.sun.enterprise.deployment.IASEjbCMPEntityDescriptor;
import com.sun.enterprise.deployment.PersistenceUnitsDescriptor;
import com.sun.enterprise.deployment.PersistenceUnitDescriptor;
import com.sun.enterprise.deployment.ResourceReferenceDescriptor;
import com.sun.enterprise.deployment.backend.DeploymentEvent;
import com.sun.enterprise.deployment.backend.DeploymentEventInfo;
import com.sun.enterprise.deployment.backend.DeploymentEventListener;
import com.sun.enterprise.deployment.backend.DeploymentEventManager;
import com.sun.enterprise.deployment.backend.DeploymentRequest;
import com.sun.enterprise.deployment.backend.DeploymentStatus;
import com.sun.enterprise.deployment.backend.IASDeploymentException;
import com.sun.enterprise.server.Constants;
import com.sun.jdo.api.persistence.support.JDOFatalUserException;
import com.sun.jdo.spi.persistence.support.sqlstore.LogHelperSQLStore;
import com.sun.jdo.spi.persistence.utility.logging.Logger;
import com.sun.jdo.spi.persistence.utility.I18NHelper;
import com.sun.jdo.spi.persistence.utility.database.DatabaseConstants;
//import com.sun.jdo.spi.persistence.support.sqlstore.ejb.*;
/** Implementation of the DeploymentEventListener interface for
* creating and dropping database schema definitions at the appropriate
* deployment/undeployment events.
*
*/
public class DeploymentEventListenerImpl
implements DeploymentEventListener, DatabaseConstants {
/** I18N message handler */
private final static ResourceBundle messages = I18NHelper.loadBundle(
"com.sun.jdo.spi.persistence.support.ejb.ejbc.Bundle", // NOI18N
DeploymentEventListenerImpl.class.getClassLoader());
/** The logger */
private static Logger logger = LogHelperSQLStore.getLogger();
/** Garantees singleton.
* Registers itself during initial load
*/
static {
DeploymentEventManager.addListener (new DeploymentEventListenerImpl());
}
/** Default constructor should not be public */
DeploymentEventListenerImpl() { }
/**
* This method is called when a <code>DeploymentEventManager</code>
* needs to deliver a code>DeploymentEvent</code> event.
* @param event the DeploymentEvent to be delivered.
*/
public void notifyDeploymentEvent(DeploymentEvent event) {
int type = event.getEventType();
switch (type) {
case DeploymentEvent.POST_DEPLOY:
processEvent(event.getEventInfo(), true);
break;
case DeploymentEvent.PRE_UNDEPLOY:
case DeploymentEvent.PRE_DEPLOY:
processEvent(event.getEventInfo(), false);
break;
default:
break;
}
}
/** Event handling.
* @param source the event source.
* @param create true if we need to create tables as part of this event.
*/
private void processEvent(DeploymentEventInfo info, boolean create) {
// Get the CLI overrides.
String cliCreateTables = null;
String cliDropTables = null;
DeploymentRequest request = info.getDeploymentRequest();
// Do nothing for drop tables on the deploy
if (isDeploy(request) && !create) {
return;
}
Properties cliOverrides = request.getOptionalArguments();
String cliDropAndCreateTables = cliOverrides.getProperty(
Constants.CMP_DROP_AND_CREATE_TABLES, Constants.UNDEFINED);
if (create) {
cliCreateTables = cliOverrides.getProperty(
Constants.CMP_CREATE_TABLES, Constants.UNDEFINED);
if (cliCreateTables.equals(Constants.UNDEFINED)) {
// It might have been specified as CMP_DROP_AND_CREATE_TABLES.
cliCreateTables = cliDropAndCreateTables;
}
} else {
cliDropTables = cliOverrides.getProperty(
Constants.CMP_DROP_TABLES, Constants.UNDEFINED);
}
Application application = info.getApplicationDescriptor();
if ( application == null) {
return;
}
processApplication(request, info, create, cliCreateTables,
cliDropAndCreateTables, cliDropTables);
} //processEvent
/**
* This is the method that does the actual processing of the deployment event.
* For each application process the cmp 2.x beans if any followed by processing
* the ejb 3.0 beans.
* @param request the deployment request object
* @param info the event source
* @param create true if we need to create tables as part of this event.
* @param cliCreateTables the cli option for creating tables
* @param cliDropAndCreateTables the cli option for dropping old tables and creating new tables
* @param cliDropTables the cli option to drop tables at undeploy time
*/
private void processApplication(DeploymentRequest request,
DeploymentEventInfo info, boolean create,
String cliCreateTables, String cliDropAndCreateTables,
String cliDropTables) {
if (logger.isLoggable(logger.FINE)) {
logger.fine("ejb.DeploymentEventListenerImpl.processingevent", //NOI18N
(isRedeploy(request)? "redeploy" : ((create)? "deploy" : "undeploy")), //NOI18N
info.getApplicationDescriptor().getRegistrationName());
}
// Get status value for our use and initialize it.
DeploymentStatus status = request.getCurrentDeploymentStatus();
status.setStageStatus(DeploymentStatus.SUCCESS);
status.setStageStatusMessage("");
BaseProcessor processor =
new CMPProcessor(info, create, cliCreateTables,
cliDropAndCreateTables, cliDropTables);
processor.processApplication();
processor =
new PersistenceProcessor(info, create, cliCreateTables,
cliDropAndCreateTables, cliDropTables);
processor.processApplication();
}
/**
* This method returns a boolean value that determines if we are
* trying to do a redeployment of an existing application but doesn't
* throw an exception.
* @param request the deployment request object
* @return true if we are trying to redeploy an existing application
*/
private boolean isRedeploy(DeploymentRequest request) {
boolean redeploy = false;
try {
if (request != null) {
redeploy = request.isReDeploy();
}
} catch (IASDeploymentException e) {
// Ignore? This is a strange exception.
}
return redeploy;
}
/**
* This method returns a boolean value that determines if we are
* trying to do a deployment of an existing application but doesn't
* throw an exception.
* @param request the deployment request object
* @return true if we are trying to redeploy an existing application
*/
private boolean isDeploy(DeploymentRequest request) {
boolean deploy = false;
try {
if (request != null) {
deploy = request.isDeploy();
}
} catch (IASDeploymentException e) {
// Ignore? This is a strange exception.
}
return deploy;
}
} //DeploymentEventListenerImpl