Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (C) 2003-2010 eXo Platform SAS.
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Affero General Public License
   * as published by the Free Software Foundation; either version 3
   * of the License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see<http://www.gnu.org/licenses/>.
  */
 package org.exoplatform.services.jcr.ext.repository.creation;
 
 import  org.picocontainer.Startable;
 
 import java.io.File;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
Created by The eXo Platform SAS.
Date:

Author(s):
Karpenko Sergiy
Version:
$Id: RepositoryCreationServiceImpl.java 111 2008-11-11 11:11:11Z serg $
 
 public class RepositoryCreationServiceImpl implements RepositoryCreationService, Startable
 {
   
The logger.
 
    private static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.RepositoryCreationService");

   
The parameter name in service's configuration.
 
    private final static String FACTORY_CLASSS_NAME_PARAM = "factory-class-name";

   
The default factory class name.
 
    private static final String DEFAULT_DATA_SOURCE_FACTORY = "org.apache.commons.dbcp.BasicDataSourceFactory";

   
The factory class name to create object.
The Repository service.
   private final RepositoryService repositoryService;

   
The RPC Service used to communicate with other nodes.
   private final RPCService rpcService;

   
BackupManager used to restore repository from backup.
   private final BackupManager backupManager;

   
Exo container context;
   private ExoContainerContext context;


   
InitalContextInitalizer used to bind new datasource.
Store of reserved repository names. {tokenname, repositoryname}
   private final Map<StringStringpendingRepositories = new ConcurrentHashMap<StringString>();
   
   private static final SecureRandom tokenGenerator = new SecureRandom();
   private RemoteCommand canRemoveRepository;

   
Constructor RepositoryCreationServiceImpl.
   public RepositoryCreationServiceImpl(InitParams initParamsRepositoryService repositoryService,
      BackupManager backupManagerExoContainerContext contextInitialContextInitializer initialContextInitializer)
   {
      this(initParamsrepositoryServicebackupManagercontextinitialContextInitializernull);
   }

   
Constructor RepositoryCreationServiceImpl.
   public RepositoryCreationServiceImpl(InitParams initParamsfinal RepositoryService repositoryService,
      BackupManager backupManagerExoContainerContext contextInitialContextInitializer initialContextInitializer,
      final RPCService rpcService)
   {
      if (initParams != null)
      {
         // set reference class name for datasource binding from initialization parameters
      }
      
      this. = repositoryService;
      this. = backupManager;
      this. = rpcService;
      this. = context;
      this. = initialContextInitializer;
      if (rpcService != null)
      {
         // register commands
          = rpcService.registerCommand(new RemoteCommand()
         {
            public String getId()
            {
               return "org.exoplatform.services.jcr.ext.repository.creation.RepositoryCreationServiceImpl-reserveRepositoryName";
            }
            public Serializable execute(Serializable[] argsthrows Throwable
            {
               String repositoryName = (String)args[0];
               return reserveRepositoryNameLocally(repositoryName);
            }
         });
          = rpcService.registerCommand(new RemoteCommand()
         {
            public String getId()
            {
               return "org.exoplatform.services.jcr.ext.repository.creation.RepositoryCreationServiceImpl-createRepository";
            }
            public Serializable execute(Serializable[] argsthrows Throwable
            {
               String backupId = (String)args[0];
               String stringRepositoryEntry = (String)args[1];
               String rToken = (String)args[2];
               DBCreationProperties creationProps = (DBCreationProperties)args[3];
               try
               {
                  RepositoryEntry rEntry =
                     (RepositoryEntry)(getObject(RepositoryEntry.class,
                        stringRepositoryEntry.getBytes(.)));
                  createRepositoryLocally(backupIdrEntryrTokencreationProps);
                  return null;
               }
               finally
               {
                  // release tokens
                  .remove(rToken);
               }
            }
         });
          = rpcService.registerCommand(new RemoteCommand()
         {
            public String getId()
            {
               return "org.exoplatform.services.jcr.ext.repository.creation.RepositoryCreationServiceImpl-startRepository";
            }
            public Serializable execute(Serializable[] argsthrows Throwable
            {
               // must not be executed on coordinator node, since coordinator node already created the repository
               if (!rpcService.isCoordinator())
               {
                  //RepositoryEntry (as String) rEntry
                  String stringRepositoryEntry = (String)args[0];
                  RepositoryEntry rEntry =
                     (RepositoryEntry)(getObject(RepositoryEntry.class,
                        stringRepositoryEntry.getBytes(.)));
                  DBCreationProperties creationProps = (DBCreationProperties)args[1];
                  startRepository(rEntrycreationProps);
               }
               return null;
            }
         });
          = rpcService.registerCommand(new RemoteCommand()
         {
            public String getId()
            {
               return "org.exoplatform.services.jcr.ext.repository.creation.RepositoryCreationServiceImpl-removeRepository";
            }
            public Serializable execute(Serializable[] argsthrows Throwable
            {
               String repositoryName = (String)args[0];
               removeRepositoryLocally(repositoryName);
               return null;
            }
         });
          = rpcService.registerCommand(new RemoteCommand()
         {
            public String getId()
            {
               return "org.exoplatform.services.jcr.ext.repository.creation.RepositoryCreationServiceImpl-checkRepositoryInUse";
            }
            public Serializable execute(Serializable[] argsthrows Throwable
            {
               String repositoryName = (String)args[0];
               
               return new Boolean(repositoryService.canRemoveRepository(repositoryName));
            }
         });
      }
      else
      {
         .warn("RepositoryCreationService initialized without RPCService, so other cluser nodes will"
            + " not be notified about new repositories.");
      }
   }

   
   public void createRepository(String backupIdRepositoryEntry rEntrythrows RepositoryConfigurationException,
   {
      String rToken = reserveRepositoryName(rEntry.getName());
      createRepositoryInternally(backupIdrEntryrTokennull);
   }

   
   public void createRepository(String backupIdRepositoryEntry rEntryStorageCreationProperties creationProps)
   {
      String rToken = reserveRepositoryName(rEntry.getName());
      if (creationProps instanceof DBCreationProperties)
      {
         createRepositoryInternally(backupIdrEntryrToken, (DBCreationProperties)creationProps);
      }
      else
      {
         throw new RepositoryCreationException("creationProps should be the instance of DBCreationProperties");
      }
   }

   
   public void createRepository(String backupIdRepositoryEntry rEntryString rToken)
   {
      createRepositoryInternally(backupIdrEntryrTokennull);
   }
   
   
   public void createRepository(String backupIdRepositoryEntry rEntryString rToken,
   {
      if (creationProps instanceof DBCreationProperties)
      {
         createRepositoryInternally(backupIdrEntryrToken, (DBCreationProperties)creationProps);
      }
      else
      {
         throw new RepositoryCreationException("creationProps should be the instance of DBCreationProperties");
      }
   }

   
Create repository internally. serverUrl and connProps contain specific properties for db creation.
   protected void createRepositoryInternally(String backupIdRepositoryEntry rEntryString rToken,
   {
      if ( != null)
      {
         String stringRepositoryEntry = null;
         try
         {
            JsonGeneratorImpl generatorImpl = new JsonGeneratorImpl();
            JsonValue json = generatorImpl.createJsonObject(rEntry);
            stringRepositoryEntry = json.toString();
         }
         catch (JsonException e)
         {
            throw new RepositoryCreationException("Can not serialize repository entry: " + e.getMessage(), e);
         }
         // notify coordinator node to create repository
         try
         {
            Object result =
               .executeCommandOnCoordinator(truebackupIdstringRepositoryEntryrToken,
                  creationProps);
            if (result != null)
            {
               if (result instanceof Throwable)
               {
                  throw new RepositoryCreationException("Can't create repository " + rEntry.getName(),
                     (Throwable)result);
               }
               else
               {
                  throw new RepositoryCreationException("createRepository command returned uknown result type.");
               }
            }
         }
         catch (RPCException e)
         {
            Throwable cause = (e).getCause();
            if (cause instanceof RepositoryCreationException)
            {
               throw (RepositoryCreationException)cause;
            }
            else if (cause instanceof RepositoryConfigurationException)
            {
               throw (RepositoryConfigurationException)cause;
            }
            else
            {
               throw new RepositoryCreationException(e.getMessage(), e);
            }
         }
         // execute startRepository at all cluster nodes (coordinator will ignore this command)
         try
         {
            List<Objectresults =
               .executeCommandOnAllNodes(truestringRepositoryEntrycreationProps);
            for (Object result : results)
            {
               if (result != null)
               {
                  if (result instanceof Throwable)
                  {
                     throw new RepositoryCreationException("Repository " + rEntry.getName()
                        + " created on coordinator, but can not be started at other cluster nodes", ((Throwable)result));
                  }
                  else
                  {
                     throw new RepositoryCreationException("startRepository command returns uknown result type");
                  }
               }
            }
         }
         catch (RPCException e)
         {
            throw new RepositoryCreationException("Repository " + rEntry.getName()
               + " created on coordinator, can not be started at other cluster node: " + e.getMessage(), e);
         }
      }
      else
      {
         try
         {
            createRepositoryLocally(backupIdrEntryrTokencreationProps);
         }
         finally
         {
            .remove(rToken);
         }
      }
   }

   
   public String reserveRepositoryName(String repositoryNamethrows RepositoryCreationException
   {
      if ( != null)
      {
         // reserve RepositoryName at coordinator-node
         try
         {
            Object result = .executeCommandOnCoordinator(truerepositoryName);
            if (result instanceof String)
            {
               return (String)result;
            }
            else if (result instanceof Throwable)
            {
               throw new RepositoryCreationException("Can't reserve repository " + repositoryName, (Throwable)result);
            }
            else
            {
               throw new RepositoryCreationException("ReserveRepositoryName command returns unknown type result.");
            }
         }
         catch (RPCException e)
         {
            Throwable cause = (e).getCause();
            if (cause instanceof RepositoryCreationException)
            {
               throw (RepositoryCreationException)cause;
            }
            else
            {
               throw new RepositoryCreationException("Can not reserve repository name " + repositoryName + " since: "
                  + e.getMessage(), e);
            }
         }
      }
      else
      {
         return reserveRepositoryNameLocally(repositoryName);
      }
   }
   protected String reserveRepositoryNameLocally(String repositoryNamethrows RepositoryCreationException
   {
      // check does repository already created
      try
      {
         if (.getRepository(repositoryName) != null)
         {
            throw new RepositoryCreationException("Repository " + repositoryName + " already exists.");
         }
      }
      catch (RepositoryConfigurationException e)
      {
         throw new RepositoryCreationException("Can not check does repository " + repositoryName + " exists: "
            + e.getMessage(), e);
      }
      catch (RepositoryException e)
      {
         if (.isTraceEnabled())
         {
            .trace("An exception occurred: " + e.getMessage());
         }
      }
      // check does this repository name already reserved, otherwise generate and return token
      if (!.containsValue(repositoryName))
      {
         String rToken = repositoryName + .nextLong();
         .put(rTokenrepositoryName);
         return rToken;
      }
      else
      {
         throw new RepositoryCreationException("Repository name " + repositoryName + " already reserved.");
      }
   }
   protected void createRepositoryLocally(String backupIdRepositoryEntry rEntryString rToken,
   {
      // check does token registered
      if (!this..containsKey(rToken))
      {
         throw new RepositoryCreationException("Token " + rToken + " does not registered.");
      }
      // Prepare list of data-source names that must be binded to newly created databases.
      Set<StringdataSourceNames = extractDataSourceNames(rEntrytrue);
      // create and bind related database to each data-source name
      for (String dataSource : dataSourceNames)
      {
         // create related DB
         Map<StringStringrefAddr = null;
         try
         {
            // db name will be the same as repository name if only one datasource exists
            String dbName = rEntry.getName() + (dataSourceNames.size() == 1 ? "" : "_" + dataSource);
            // get DBCreator
            DBCreator dbCreator = getDBCreator(creationProps);
            
            // create database
            DBConnectionInfo dbConnectionInfo = dbCreator.createDatabase(dbName);
            refAddr = dbConnectionInfo.getProperties();
         }
         catch (DBCreatorException e)
         {
            throw new RepositoryCreationException("Can not create new database for " + rEntry.getName()
               + " repository."e);
         }
         catch (ConfigurationException e)
         {
            throw new RepositoryCreationException("Can not get instance of DBCreator"e);
         }
         // bind data-source
         try
         {
            .getInitialContextBinder().bind(dataSource"javax.sql.DataSource",
               nullrefAddr);
         }
         catch (NamingException e)
         {
            throw new RepositoryCreationException(e.getMessage(), e);
         }
         catch (FileNotFoundException e)
         {
            throw new RepositoryCreationException(e.getMessage(), e);
         }
         catch (XMLStreamException e)
         {
            throw new RepositoryCreationException(e.getMessage(), e);
         }
      }
      // restore repository from backup
      RepositoryBackupChainLog backupChain = null;
      {
         if (chainLog.getBackupId().equals(backupId))
         {
            backupChain = chainLog;
            break;
         }
      }
      if (backupChain == null)
      {
         throw new RepositoryCreationException("BackupChain by id " + backupId + " does not exists.");
      }
      File backLog = new File(backupChain.getLogFilePath());
      if (backLog != null && PrivilegedFileHelper.exists(backLog))
      {
         try
         {
            .restore(backupChainrEntryfalsetrue);
         }
         catch (BackupOperationException e)
         {
            throw new RepositoryCreationException(e.getLocalizedMessage(), e);
         }
         catch (BackupConfigurationException e)
         {
            throw new RepositoryCreationException(e.getLocalizedMessage(), e);
         }
         catch (RepositoryException e)
         {
            throw new RepositoryCreationException(e.getLocalizedMessage(), e);
         }
      }
      else
      {
         throw new RepositoryCreationException("Backup log file by id " + backupId
            + (backLog != null ? (" and file path=" + PrivilegedFileHelper.getAbsolutePath(backLog)) : "")
            + " do not exists.");
      }
   }
   protected void startRepository(RepositoryEntry repositoryEntryDBCreationProperties creationProps)
      throws RepositoryCreationException
   {
      try
      {
         // Prepare list of data-source names that must be binded
         Set<StringdataSourceNames = extractDataSourceNames(repositoryEntryfalse);
         for (String dataSource : dataSourceNames)
         {
            // get data base info 
            Map<StringStringrefAddr = null;
            try
            {
               // db name will be the same as repository name if only one datasource exists
               String dbName = repositoryEntry.getName() + (dataSourceNames.size() == 1 ? "" : "_" + dataSource);
               // get DBCreator
               DBCreator dbCreator = getDBCreator(creationProps);
               // get connection info
               DBConnectionInfo dbConnectionInfo = dbCreator.getDBConnectionInfo(dbName);
               refAddr = dbConnectionInfo.getProperties();
            }
            catch (DBCreatorException e)
            {
               throw new RepositoryCreationException("Can not fetch database information associated with "
                  + repositoryEntry.getName() + " repository and " + dataSource + " datasource."e);
            }
            catch (ConfigurationException e)
            {
               throw new RepositoryCreationException("Can't get instance of DBCreator"e);
            }
            // bind data-source
            try
            {
               .getInitialContextBinder().bind(dataSource"javax.sql.DataSource",
                  nullrefAddr);
            }
            catch (NamingException e)
            {
               throw new RepositoryCreationException(e.getMessage(), e);
            }
            catch (FileNotFoundException e)
            {
               throw new RepositoryCreationException(e.getMessage(), e);
            }
            catch (XMLStreamException e)
            {
               throw new RepositoryCreationException(e.getMessage(), e);
            }
         }
         .createRepository(repositoryEntry);
      }
      catch (RepositoryConfigurationException e)
      {
         throw new RepositoryCreationException(e.getMessage(), e);
      }
      catch (RepositoryException e)
      {
         throw new RepositoryCreationException(e.getMessage(), e);
      }
   }
   private Set<StringextractDataSourceNames(RepositoryEntry repositoryEntryboolean checkDataSourceExistance)
   {
      Set<StringdataSourceNames = new HashSet<String>();
      for (WorkspaceEntry wsEntry : repositoryEntry.getWorkspaceEntries())
      {
         boolean isMultiDB =
         String dbSourceName = wsEntry.getContainer().getParameterValue(.);
         if (isMultiDB && dataSourceNames.contains(dbSourceName))
         {
            throw new RepositoryCreationException("RepositoryEntry for new " + repositoryEntry.getName()
               + " repository contains workspaces that marked as multiDB but have same datasource " + dbSourceName
               + ".");
         }
         if (checkDataSourceExistance)
         {
            try
            {
               DataSource ds = (DataSource).getInitialContext().lookup(dbSourceName);
               if (ds != null)
               {
                  throw new RepositoryConfigurationException("RepositoryEntry for new " + repositoryEntry.getName()
                     + " repository contains already binded datasource " + dbSourceName + ".");
               }
            }
            catch (NameNotFoundException e)
            {
               if (.isTraceEnabled())
               {
                  .trace("An exception occurred: " + e.getMessage());
               }
            }
            catch (NamingException e)
            {
               throw new RepositoryConfigurationException(e.getMessage(), e);
            }
         }
         dataSourceNames.add(dbSourceName);
      }
      return dataSourceNames;
   }

   
Will be created the Object from JSON binary data.

Parameters:
cl Class
data binary data (JSON)
Returns:
Object
Throws:
Exception will be generated Exception
   private Object getObject(Class clbyte[] datathrows Exception
   {
      JsonHandler jsonHandler = new JsonDefaultHandler();
      JsonParser jsonParser = new JsonParserImpl();
      InputStream inputStream = new ByteArrayInputStream(data);
      jsonParser.parse(inputStreamjsonHandler);
      JsonValue jsonValue = jsonHandler.getJsonObject();
      return new BeanBuilder().createObject(cljsonValue);
   }

   
   public void start()
   {
   }

   
   public void stop()
   {
      if (this. != null)
      {
      }
   }

   
   public void removeRepository(String repositoryNameboolean forceRemovethrows RepositoryCreationException
   {
      if ( != null)
      {
         try
         {
            if (!forceRemove)
            {
               List<Objectresults = .executeCommandOnAllNodes(truerepositoryName);
               for (Object result : results)
               {
                  if (result != null)
                  {
                     if (result instanceof Throwable)
                     {
                        throw new RepositoryCreationException("It is not possible to check is repository "
                           + repositoryName + " in usage or not", (Throwable)result);
                     }
                     else if (result instanceof Boolean)
                     {
                        if (!(Boolean)result)
                        {
                           throw new RepositoryCreationException("Can't remove repository " + repositoryName
                              + ". The repository in use.");
                        }
                     }
                     else
                     {
                        throw new RepositoryCreationException(
                           "checkRepositoryInUse command returned uknown result type");
                     }
                  }
               }
            }
            List<Objectresults = .executeCommandOnAllNodes(truerepositoryName);
            for (Object result : results)
            {
               if (result != null)
               {
                  if (result instanceof Throwable)
                  {
                     throw new RepositoryCreationException("Can't remove repository " + repositoryName,
                        (Throwable)result);
                  }
                  else
                  {
                     throw new RepositoryCreationException("removeRepository command returned uknown result type");
                  }
               }
            }
         }
         catch (RPCException e)
         {
            throw new RepositoryCreationException("Can't remove repository " + repositoryNamee);
         }
      }
      else
      {
         if (!forceRemove)
         {
            try
            {
               if (!.canRemoveRepository(repositoryName))
               {
                  throw new RepositoryCreationException("Can't remove repository " + repositoryName
                     + ". The repository in use.");
               }
            }
            catch (RepositoryException e)
            {
               throw new RepositoryCreationException("It is not possible to check is repository " + repositoryName
                  + " in usage or not"e);
            }
         }
         removeRepositoryLocally(repositoryName);
      }
   }

   
Remove repository locally.

Parameters:
repositoryName the repository name
Throws:
RepositoryCreationException
   protected void removeRepositoryLocally(String repositoryNamethrows RepositoryCreationException
   {
      try
      {
         // extract list of all datasources
         ManageableRepository repositorty = .getRepository(repositoryName);
         Set<Stringdatasources = extractDataSourceNames(repositorty.getConfiguration(), false);
         // close all opened sessions
         for (String workspaceName : repositorty.getWorkspaceNames())
         {
            WorkspaceContainerFacade wc = repositorty.getWorkspaceContainer(workspaceName);
            SessionRegistry sessionRegistry = (SessionRegistry)wc.getComponent(SessionRegistry.class);
            sessionRegistry.closeSessions(workspaceName);
         }
         // remove repository from configuration
         .removeRepository(repositoryName);
         .getConfig().retain();
         
         // unbind datasource and close connections
         for (String dsName : datasources)
         {
            try
            {
               // we suppose that lookup() method returns the same instance of datasource by the same name
               DataSource ds = (DataSource).getInitialContext().lookup(dsName);
               .getInitialContextBinder().unbind(dsName);
               // close datasource
               if (ds instanceof CloseableDataSource)
               {
                  ((CloseableDataSource)ds).close();
               }
            }
            catch (NamingException e)
            {
               .error("Can't unbind datasource " + dsNamee);
            }
            catch (FileNotFoundException e)
            {
               .error("Can't unbind datasource " + dsNamee);
            }
            catch (XMLStreamException e)
            {
               .error("Can't unbind datasource " + dsNamee);
            }
         }
      }
      catch (RepositoryException e)
      {
         throw new RepositoryCreationException("Can't remove repository"e);
      }
      catch (RepositoryConfigurationException e)
      {
         throw new RepositoryCreationException("Can't remove repository"e);
      }
   }
   private DBCreator getDBCreator(DBCreationProperties creationPropsthrows ConfigurationException
   {
      if (creationProps == null)
      {
      }
      ConfigurationManager cm =
      return new DBCreator(creationProps.getServerUrl(), creationProps.getConnProps(), creationProps.getDBScriptPath(),
         creationProps.getDBUserName(), creationProps.getDBPassword(), cm);
   }
New to GrepCode? Check out our FAQ X