mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
MT admin - add export/import tenant also expose delete tenant (BETA)
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8047 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -22,6 +22,12 @@
|
||||
<property name="passwordEncoder" ref="passwordEncoder"/>
|
||||
<property name="tenantFileContentStore" ref="tenantFileContentStore"/>
|
||||
<property name="workflowService" ref="WorkflowService"/>
|
||||
<property name="repositoryExporterService" ref="repositoryExporterComponent"/>
|
||||
|
||||
<property name="namespaceService" ref="NamespaceService"/>
|
||||
<property name="searchService" ref="SearchService"/>
|
||||
<property name="workflowDefinitionType" ref="workflowDefinitionType"/>
|
||||
<property name="repositoryWorkflowDefsLocations" ref="customWorkflowDefsRepositoryLocation"/>
|
||||
|
||||
</bean>
|
||||
|
||||
|
@@ -32,7 +32,7 @@ ok> show tenant <tenant domain>
|
||||
|
||||
ok> create <tenant domain> <tenant admin password> [<root contentstore dir>]
|
||||
|
||||
Create tenant. By default the tenant will be enabled. It will have an admin
|
||||
Create empty tenant. By default the tenant will be enabled. It will have an admin
|
||||
user called "admin@<tenant domain>" with supplied admin password. All users
|
||||
that the admin creates, will login using "<username>@<tenant domain>".
|
||||
The root of the contentstore directory can be optionally specified, otherwise
|
||||
@@ -43,16 +43,6 @@ ok> create <tenant domain> <tenant admin password> [<root contentstore dir>]
|
||||
create yyy.zzz.com g00dby3 /usr/tenantstores/yyy.zzz
|
||||
create myorg h3ll0
|
||||
|
||||
ok> createWithoutWorkflows <tenant domain> <tenant admin password> [<root contentstore dir>]
|
||||
|
||||
Same as create, except the default workflows will not be bootstrapped.
|
||||
|
||||
ok> bootstrapWorkflows <tenant domain>
|
||||
|
||||
Bootstrap the default workflows.
|
||||
|
||||
Examples: bootstrapWorkflows yyy.zzz.com
|
||||
|
||||
ok> changeAdminPassword <tenant domain> <tenant admin password>
|
||||
|
||||
Useful if the tenant's admin (admin@<tenant domain>) has forgotten their password.
|
||||
@@ -71,6 +61,31 @@ ok> disable <tenant domain>
|
||||
|
||||
Example: enable yyy.zzz.com
|
||||
|
||||
ok> delete <tenant domain>
|
||||
|
||||
BETA - Delete tenant.
|
||||
|
||||
Note: This currently requires a server restart to clear the index threads. Also
|
||||
tenant index directories should be deleted manually.
|
||||
|
||||
Example: delete yyy.zzz.com
|
||||
|
||||
ok> export <tenant domain> <destination directory>
|
||||
|
||||
Export tenant to given destination directory. Export filenames will be suffixed with '<tenant domain>_'.
|
||||
|
||||
Example: export yyy.zzz.com /usr/exportdir
|
||||
|
||||
ok> import <tenant domain> <source directory> [<root contentstore dir>]
|
||||
|
||||
BETA - create tenant by importing the tenant files from the given source directory. The import filenames must
|
||||
be suffixed with '<tenant domain>_'.
|
||||
|
||||
Note: If importing into a previously deleted tenant then the server must be stopped after the delete
|
||||
(and tenant indexes manually deleted) before restarting and performing the import.
|
||||
|
||||
Example: import yyy.zzz.com /usr/exportdir /usr/tenantstores/yyy.zzz
|
||||
|
||||
##
|
||||
## end
|
||||
##
|
||||
|
@@ -109,6 +109,15 @@
|
||||
<!-- Workflow Patch Deployer -->
|
||||
<bean id="workflowPatchDeployer" parent="workflowDeployer" singleton="false"/>
|
||||
|
||||
<!-- Deploy any additional workflows definitions from repo (used by MT import) -->
|
||||
<!-- note: needs to match bootstrap-context.xml locations ( customWorkflowDefsSpace.xml) -->
|
||||
<bean id="customWorkflowDefsRepositoryLocation" class="org.alfresco.repo.dictionary.RepositoryLocation">
|
||||
<!-- other properties will be defaulted, but can be overriden here -->
|
||||
<property name="path">
|
||||
<value>/app:company_home/app:dictionary/app:workflow_defs</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Workflow Definition Type (bpm:workflowDefinition) -->
|
||||
<bean id="workflowDefinitionType" class="org.alfresco.repo.workflow.WorkflowDefinitionType" init-method="init">
|
||||
<property name="nodeService" ref="NodeService"/>
|
||||
|
@@ -473,7 +473,13 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
||||
if ((existingValue != null) && (existingValue.booleanValue() == true))
|
||||
{
|
||||
String name = (String)nodeService.getProperty(existingNodeRef, ContentModel.PROP_NAME);
|
||||
throw new AlfrescoRuntimeException("Cannot activate '"+modelDefinition.getName()+"' - existing active model: " + name);
|
||||
|
||||
// for MT import, model may have been activated by DictionaryRepositoryBootstrap
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Re-activating '"+modelDefinition.getName()+"' - existing active model: " + name);
|
||||
}
|
||||
//throw new AlfrescoRuntimeException("Cannot activate '"+modelDefinition.getName()+"' - existing active model: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -498,6 +498,16 @@ public class ImporterBootstrap extends AbstractLifecycleBean
|
||||
*/
|
||||
private File getFile(String view)
|
||||
{
|
||||
// Try as a file location
|
||||
File file = new File(view);
|
||||
if ((file != null) && (file.exists()))
|
||||
{
|
||||
return file;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try as a classpath location
|
||||
|
||||
// Get input stream
|
||||
InputStream viewStream = getClass().getClassLoader().getResourceAsStream(view);
|
||||
if (viewStream == null)
|
||||
@@ -522,6 +532,7 @@ public class ImporterBootstrap extends AbstractLifecycleBean
|
||||
}
|
||||
return tempFile;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
package org.alfresco.repo.tenant;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
@@ -45,17 +46,23 @@ import org.alfresco.repo.attributes.MapAttributeValue;
|
||||
import org.alfresco.repo.attributes.StringAttributeValue;
|
||||
import org.alfresco.repo.content.TenantRoutingFileContentStore;
|
||||
import org.alfresco.repo.dictionary.DictionaryComponent;
|
||||
import org.alfresco.repo.dictionary.RepositoryLocation;
|
||||
import org.alfresco.repo.importer.ImporterBootstrap;
|
||||
import org.alfresco.repo.node.db.DbNodeServiceImpl;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.workflow.WorkflowDefinitionType;
|
||||
import org.alfresco.repo.workflow.WorkflowDeployer;
|
||||
import org.alfresco.service.cmr.admin.RepoAdminService;
|
||||
import org.alfresco.service.cmr.attributes.AttributeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.view.RepositoryExporterService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.AbstractLifecycleBean;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
@@ -85,6 +92,11 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
|
||||
private PasswordEncoder passwordEncoder;
|
||||
private TenantRoutingFileContentStore tenantFileContentStore;
|
||||
private WorkflowService workflowService;
|
||||
private RepositoryExporterService repositoryExporterService;
|
||||
private NamespaceService namespaceService;
|
||||
private SearchService searchService;
|
||||
private RepositoryLocation repoWorkflowDefsLocation;
|
||||
private WorkflowDefinitionType workflowDefinitionType;
|
||||
|
||||
|
||||
protected final static String REGEX_VALID_TENANT_NAME = "^[a-zA-Z0-9]([a-zA-Z0-9]|.[a-zA-Z0-9])*$"; // note: must also be a valid filename
|
||||
@@ -139,6 +151,32 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
|
||||
this.workflowService = workflowService;
|
||||
}
|
||||
|
||||
public void setRepositoryExporterService(RepositoryExporterService repositoryExporterService)
|
||||
{
|
||||
this.repositoryExporterService = repositoryExporterService;
|
||||
}
|
||||
|
||||
public void setNamespaceService(NamespaceService namespaceService)
|
||||
{
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
public void setSearchService(SearchService searchService)
|
||||
{
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
public void setRepositoryWorkflowDefsLocations(RepositoryLocation repoWorkflowDefsLocation)
|
||||
{
|
||||
this.repoWorkflowDefsLocation = repoWorkflowDefsLocation;
|
||||
}
|
||||
|
||||
public void setWorkflowDefinitionType(WorkflowDefinitionType workflowDefinitionType)
|
||||
{
|
||||
this.workflowDefinitionType = workflowDefinitionType;
|
||||
}
|
||||
|
||||
|
||||
public static final String PROTOCOL_STORE_USER = "user";
|
||||
public static final String PROTOCOL_STORE_WORKSPACE = "workspace";
|
||||
public static final String PROTOCOL_STORE_SYSTEM = "system";
|
||||
@@ -155,6 +193,9 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
|
||||
|
||||
private static final String ADMIN_BASENAME = TenantService.ADMIN_BASENAME;
|
||||
|
||||
public final static String CRITERIA_ALL = "/*"; // immediate children only
|
||||
public final static String defaultSubtypeOfWorkflowDefinitionType = "subtypeOf('bpm:workflowDefinition')";
|
||||
|
||||
private List<TenantDeployer> tenantDeployers = new ArrayList<TenantDeployer>();
|
||||
|
||||
|
||||
@@ -275,11 +316,20 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
|
||||
tenantFileContentStore.init();
|
||||
|
||||
// create tenant-specific stores
|
||||
bootstrapUserTenantStore(tenantDomain, tenantAdminRawPassword);
|
||||
bootstrapSystemTenantStore(tenantDomain);
|
||||
bootstrapVersionTenantStore(tenantDomain);
|
||||
bootstrapSpacesArchiveTenantStore(tenantDomain);
|
||||
bootstrapSpacesTenantStore(tenantDomain);
|
||||
ImporterBootstrap userImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("userBootstrap");
|
||||
bootstrapUserTenantStore(userImporterBootstrap, tenantDomain, tenantAdminRawPassword);
|
||||
|
||||
ImporterBootstrap systemImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("systemBootstrap");
|
||||
bootstrapSystemTenantStore(systemImporterBootstrap, tenantDomain);
|
||||
|
||||
ImporterBootstrap versionImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("versionBootstrap");
|
||||
bootstrapVersionTenantStore(versionImporterBootstrap, tenantDomain);
|
||||
|
||||
ImporterBootstrap spacesArchiveImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("spacesArchiveBootstrap");
|
||||
bootstrapSpacesArchiveTenantStore(spacesArchiveImporterBootstrap, tenantDomain);
|
||||
|
||||
ImporterBootstrap spacesImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("spacesBootstrap");
|
||||
bootstrapSpacesTenantStore(spacesImporterBootstrap, tenantDomain);
|
||||
|
||||
// notify listeners that tenant has been created & hence enabled
|
||||
for (TenantDeployer tenantDeployer : tenantDeployers)
|
||||
@@ -295,6 +345,82 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
|
||||
logger.info("Tenant created: " + tenantDomain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export tenant - equivalent to the tenant admin running a 'complete repo' export from the Web Client Admin
|
||||
*/
|
||||
public void exportTenant(final String tenantDomain, final File directoryDestination)
|
||||
{
|
||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork()
|
||||
{
|
||||
repositoryExporterService.export(directoryDestination, tenantDomain);
|
||||
return null;
|
||||
}
|
||||
}, getTenantAdminUser(tenantDomain));
|
||||
|
||||
logger.info("Tenant exported: " + tenantDomain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create tenant by restoring from a complete repository export. This is equivalent to a bootstrap import using restore-context.xml.
|
||||
*/
|
||||
public void importTenant(final String tenantDomain, final File directorySource, String rootContentStoreDir)
|
||||
{
|
||||
// Check that all the passed values are not null
|
||||
ParameterCheck.mandatory("tenantDomain", tenantDomain);
|
||||
|
||||
if (! Pattern.matches(REGEX_VALID_TENANT_NAME, tenantDomain))
|
||||
{
|
||||
throw new IllegalArgumentException(tenantDomain + " is not a valid tenant name (must match " + REGEX_VALID_TENANT_NAME + ")");
|
||||
}
|
||||
|
||||
if (existsTenant(tenantDomain))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Tenant already exists: " + tenantDomain);
|
||||
}
|
||||
else
|
||||
{
|
||||
authenticationComponent.setSystemUserAsCurrentUser();
|
||||
|
||||
if (rootContentStoreDir == null)
|
||||
{
|
||||
rootContentStoreDir = tenantFileContentStore.getDefaultRootDir();
|
||||
}
|
||||
|
||||
// init - need to enable tenant (including tenant service) before stores bootstrap
|
||||
Tenant tenant = new Tenant(tenantDomain, true, rootContentStoreDir);
|
||||
putTenantAttributes(tenantDomain, tenant);
|
||||
|
||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork()
|
||||
{
|
||||
dictionaryComponent.init();
|
||||
tenantFileContentStore.init();
|
||||
|
||||
// import tenant-specific stores
|
||||
importBootstrapUserTenantStore(tenantDomain, directorySource);
|
||||
importBootstrapSystemTenantStore(tenantDomain, directorySource);
|
||||
importBootstrapVersionTenantStore(tenantDomain, directorySource);
|
||||
importBootstrapSpacesArchiveTenantStore(tenantDomain, directorySource);
|
||||
importBootstrapSpacesModelsTenantStore(tenantDomain, directorySource);
|
||||
importBootstrapSpacesTenantStore(tenantDomain, directorySource);
|
||||
|
||||
// notify listeners that tenant has been created & hence enabled
|
||||
for (TenantDeployer tenantDeployer : tenantDeployers)
|
||||
{
|
||||
tenantDeployer.onEnableTenant();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}, getTenantAdminUser(tenantDomain));
|
||||
}
|
||||
|
||||
logger.info("Tenant imported: " + tenantDomain);
|
||||
}
|
||||
|
||||
public boolean existsTenant(String tenantDomain)
|
||||
{
|
||||
// Check that all the passed values are not null
|
||||
@@ -477,6 +603,21 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
|
||||
throw new AlfrescoRuntimeException("Failed to find workflow process def: " + resourceClasspath);
|
||||
}
|
||||
|
||||
// in case of import, also deploy any custom workflow definitions defined in the repo
|
||||
// TODO refactor/review repository bootstrap order of undeployed workflow definitions
|
||||
|
||||
StoreRef storeRef = repoWorkflowDefsLocation.getStoreRef();
|
||||
NodeRef rootNode = nodeService.getRootNode(storeRef);
|
||||
List<NodeRef> nodeRefs = searchService.selectNodes(rootNode, repoWorkflowDefsLocation.getPath()+CRITERIA_ALL+"["+defaultSubtypeOfWorkflowDefinitionType+"]", null, namespaceService, false);
|
||||
|
||||
if (nodeRefs.size() > 0)
|
||||
{
|
||||
for (NodeRef nodeRef : nodeRefs)
|
||||
{
|
||||
workflowDefinitionType.deploy(nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Tenant workflows bootstrapped: " + tenantService.getCurrentUserDomain());
|
||||
}
|
||||
|
||||
@@ -586,32 +727,27 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
|
||||
return tenants; // list of tenants or empty list
|
||||
}
|
||||
|
||||
private void bootstrapUserTenantStore(String tenantDomain, char[] tenantAdminRawPassword)
|
||||
private void importBootstrapSystemTenantStore(String tenantDomain, File directorySource)
|
||||
{
|
||||
// Bootstrap Tenant-Specific User Store
|
||||
StoreRef bootstrapStoreRef = new StoreRef(PROTOCOL_STORE_USER, tenantService.getName(STORE_BASE_ID_USER, tenantDomain));
|
||||
// Import Bootstrap (restore) Tenant-Specific Version Store
|
||||
Properties bootstrapView = new Properties();
|
||||
bootstrapView.put("path", "/");
|
||||
bootstrapView.put("location", directorySource.getPath()+"/"+tenantDomain+"_system.acp");
|
||||
|
||||
ImporterBootstrap userImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("userBootstrap");
|
||||
userImporterBootstrap.setStoreUrl(bootstrapStoreRef.toString());
|
||||
List<Properties> bootstrapViews = new ArrayList<Properties>(1);
|
||||
bootstrapViews.add(bootstrapView);
|
||||
|
||||
// override admin username property
|
||||
String salt = null; // GUID.generate();
|
||||
Properties props = userImporterBootstrap.getConfiguration();
|
||||
ImporterBootstrap systemImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("systemBootstrap");
|
||||
systemImporterBootstrap.setBootstrapViews(bootstrapViews);
|
||||
systemImporterBootstrap.setLog(true);
|
||||
|
||||
props.put("alfresco_user_store.adminusername", getTenantAdminUser(tenantDomain));
|
||||
props.put("alfresco_user_store.adminpassword", passwordEncoder.encodePassword(new String(tenantAdminRawPassword), salt));
|
||||
|
||||
userImporterBootstrap.bootstrap();
|
||||
|
||||
logger.debug("Bootstrapped store: " + tenantService.getBaseName(bootstrapStoreRef));
|
||||
bootstrapSystemTenantStore(systemImporterBootstrap, tenantDomain);
|
||||
}
|
||||
|
||||
private void bootstrapSystemTenantStore(String tenantDomain)
|
||||
private void bootstrapSystemTenantStore(ImporterBootstrap systemImporterBootstrap, String tenantDomain)
|
||||
{
|
||||
// Bootstrap Tenant-Specific System Store
|
||||
StoreRef bootstrapStoreRef = new StoreRef(PROTOCOL_STORE_SYSTEM, tenantService.getName(STORE_BASE_ID_SYSTEM, tenantDomain));
|
||||
|
||||
ImporterBootstrap systemImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("systemBootstrap");
|
||||
systemImporterBootstrap.setStoreUrl(bootstrapStoreRef.toString());
|
||||
|
||||
// override default property (workspace://SpacesStore)
|
||||
@@ -624,12 +760,65 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
|
||||
logger.debug("Bootstrapped store: " + tenantService.getBaseName(bootstrapStoreRef));
|
||||
}
|
||||
|
||||
private void bootstrapVersionTenantStore(String tenantDomain)
|
||||
private void importBootstrapUserTenantStore(String tenantDomain, File directorySource)
|
||||
{
|
||||
// Import Bootstrap (restore) Tenant-Specific User Store
|
||||
Properties bootstrapView = new Properties();
|
||||
bootstrapView.put("path", "/");
|
||||
bootstrapView.put("location", directorySource.getPath()+"/"+tenantDomain+"_users.acp");
|
||||
|
||||
List<Properties> bootstrapViews = new ArrayList<Properties>(1);
|
||||
bootstrapViews.add(bootstrapView);
|
||||
|
||||
ImporterBootstrap userImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("userBootstrap");
|
||||
userImporterBootstrap.setBootstrapViews(bootstrapViews);
|
||||
userImporterBootstrap.setLog(true);
|
||||
|
||||
bootstrapUserTenantStore(userImporterBootstrap, tenantDomain, null);
|
||||
}
|
||||
|
||||
private void bootstrapUserTenantStore(ImporterBootstrap userImporterBootstrap, String tenantDomain, char[] tenantAdminRawPassword)
|
||||
{
|
||||
// Bootstrap Tenant-Specific User Store
|
||||
StoreRef bootstrapStoreRef = new StoreRef(PROTOCOL_STORE_USER, tenantService.getName(STORE_BASE_ID_USER, tenantDomain));
|
||||
userImporterBootstrap.setStoreUrl(bootstrapStoreRef.toString());
|
||||
|
||||
// override admin username property
|
||||
Properties props = userImporterBootstrap.getConfiguration();
|
||||
props.put("alfresco_user_store.adminusername", getTenantAdminUser(tenantDomain));
|
||||
|
||||
if (tenantAdminRawPassword != null)
|
||||
{
|
||||
String salt = null; // GUID.generate();
|
||||
props.put("alfresco_user_store.adminpassword", passwordEncoder.encodePassword(new String(tenantAdminRawPassword), salt));
|
||||
}
|
||||
|
||||
userImporterBootstrap.bootstrap();
|
||||
|
||||
logger.debug("Bootstrapped store: " + tenantService.getBaseName(bootstrapStoreRef));
|
||||
}
|
||||
|
||||
private void importBootstrapVersionTenantStore(String tenantDomain, File directorySource)
|
||||
{
|
||||
// Import Bootstrap (restore) Tenant-Specific Version Store
|
||||
Properties bootstrapView = new Properties();
|
||||
bootstrapView.put("path", "/");
|
||||
bootstrapView.put("location", directorySource.getPath()+"/"+tenantDomain+"_versions.acp");
|
||||
|
||||
List<Properties> bootstrapViews = new ArrayList<Properties>(1);
|
||||
bootstrapViews.add(bootstrapView);
|
||||
|
||||
ImporterBootstrap versionImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("versionBootstrap");
|
||||
versionImporterBootstrap.setBootstrapViews(bootstrapViews);
|
||||
versionImporterBootstrap.setLog(true);
|
||||
|
||||
bootstrapVersionTenantStore(versionImporterBootstrap, tenantDomain);
|
||||
}
|
||||
|
||||
private void bootstrapVersionTenantStore(ImporterBootstrap versionImporterBootstrap, String tenantDomain)
|
||||
{
|
||||
// Bootstrap Tenant-Specific Version Store
|
||||
StoreRef bootstrapStoreRef = new StoreRef(PROTOCOL_STORE_WORKSPACE, tenantService.getName(STORE_BASE_ID_VERSION, tenantDomain));
|
||||
|
||||
ImporterBootstrap versionImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("versionBootstrap");
|
||||
versionImporterBootstrap.setStoreUrl(bootstrapStoreRef.toString());
|
||||
|
||||
versionImporterBootstrap.bootstrap();
|
||||
@@ -637,12 +826,27 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
|
||||
logger.debug("Bootstrapped store: " + tenantService.getBaseName(bootstrapStoreRef));
|
||||
}
|
||||
|
||||
private void bootstrapSpacesArchiveTenantStore(String tenantDomain)
|
||||
private void importBootstrapSpacesArchiveTenantStore(String tenantDomain, File directorySource)
|
||||
{
|
||||
// Bootstrap Tenant-Specific Spaces Store
|
||||
StoreRef bootstrapStoreRef = new StoreRef(PROTOCOL_STORE_ARCHIVE, tenantService.getName(STORE_BASE_ID_SPACES, tenantDomain));
|
||||
// Import Bootstrap (restore) Tenant-Specific Spaces Archive Store
|
||||
Properties bootstrapView = new Properties();
|
||||
bootstrapView.put("path", "/");
|
||||
bootstrapView.put("location", directorySource.getPath()+"/"+tenantDomain+"_spaces_archive.acp");
|
||||
|
||||
List<Properties> bootstrapViews = new ArrayList<Properties>(1);
|
||||
bootstrapViews.add(bootstrapView);
|
||||
|
||||
ImporterBootstrap spacesArchiveImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("spacesArchiveBootstrap");
|
||||
spacesArchiveImporterBootstrap.setBootstrapViews(bootstrapViews);
|
||||
spacesArchiveImporterBootstrap.setLog(true);
|
||||
|
||||
bootstrapSpacesArchiveTenantStore(spacesArchiveImporterBootstrap, tenantDomain);
|
||||
}
|
||||
|
||||
private void bootstrapSpacesArchiveTenantStore(ImporterBootstrap spacesArchiveImporterBootstrap, String tenantDomain)
|
||||
{
|
||||
// Bootstrap Tenant-Specific Spaces Archive Store
|
||||
StoreRef bootstrapStoreRef = new StoreRef(PROTOCOL_STORE_ARCHIVE, tenantService.getName(STORE_BASE_ID_SPACES, tenantDomain));
|
||||
spacesArchiveImporterBootstrap.setStoreUrl(bootstrapStoreRef.toString());
|
||||
|
||||
// override default property (archive://SpacesStore)
|
||||
@@ -655,12 +859,47 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
|
||||
logger.debug("Bootstrapped store: " + tenantService.getBaseName(bootstrapStoreRef));
|
||||
}
|
||||
|
||||
private void bootstrapSpacesTenantStore(String tenantDomain)
|
||||
private void importBootstrapSpacesModelsTenantStore(String tenantDomain, File directorySource)
|
||||
{
|
||||
// Import Bootstrap (restore) Tenant-Specific Spaces Store
|
||||
Properties bootstrapView = new Properties();
|
||||
bootstrapView.put("path", "/");
|
||||
bootstrapView.put("location", directorySource.getPath()+"/"+tenantDomain+"_models.acp");
|
||||
|
||||
List<Properties> bootstrapViews = new ArrayList<Properties>(1);
|
||||
bootstrapViews.add(bootstrapView);
|
||||
|
||||
ImporterBootstrap spacesImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("spacesBootstrap");
|
||||
spacesImporterBootstrap.setBootstrapViews(bootstrapViews);
|
||||
spacesImporterBootstrap.setLog(true);
|
||||
|
||||
bootstrapSpacesTenantStore(spacesImporterBootstrap, tenantDomain);
|
||||
}
|
||||
|
||||
private void importBootstrapSpacesTenantStore(String tenantDomain, File directorySource)
|
||||
{
|
||||
// Import Bootstrap (restore) Tenant-Specific Spaces Store
|
||||
Properties bootstrapView = new Properties();
|
||||
bootstrapView.put("path", "/");
|
||||
bootstrapView.put("location", directorySource.getPath()+"/"+tenantDomain+"_spaces.acp");
|
||||
bootstrapView.put("uuidBinding", "UPDATE_EXISTING");
|
||||
|
||||
List<Properties> bootstrapViews = new ArrayList<Properties>(1);
|
||||
bootstrapViews.add(bootstrapView);
|
||||
|
||||
ImporterBootstrap spacesImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("spacesBootstrap");
|
||||
spacesImporterBootstrap.setBootstrapViews(bootstrapViews);
|
||||
spacesImporterBootstrap.setLog(true);
|
||||
|
||||
spacesImporterBootstrap.setUseExistingStore(true);
|
||||
|
||||
bootstrapSpacesTenantStore(spacesImporterBootstrap, tenantDomain);
|
||||
}
|
||||
|
||||
private void bootstrapSpacesTenantStore(ImporterBootstrap spacesImporterBootstrap, String tenantDomain)
|
||||
{
|
||||
// Bootstrap Tenant-Specific Spaces Store
|
||||
StoreRef bootstrapStoreRef = new StoreRef(PROTOCOL_STORE_WORKSPACE, tenantService.getName(STORE_BASE_ID_SPACES, tenantDomain));
|
||||
|
||||
final ImporterBootstrap spacesImporterBootstrap = (ImporterBootstrap)getApplicationContext().getBean("spacesBootstrap");
|
||||
spacesImporterBootstrap.setStoreUrl(bootstrapStoreRef.toString());
|
||||
|
||||
// override admin username property
|
||||
|
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
package org.alfresco.repo.tenant;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -40,6 +41,10 @@ public interface TenantAdminService extends TenantDeployerService
|
||||
|
||||
public void createTenant(String tenantDomain, char[] adminRawPassword, String rootContentStoreDir);
|
||||
|
||||
public void exportTenant(String tenantDomain, File directoryDestination);
|
||||
|
||||
public void importTenant(String tenantDomain, File directorySource, String rootContentStoreDir);
|
||||
|
||||
public boolean existsTenant(String tenantDomain);
|
||||
|
||||
public void bootstrapWorkflows();
|
||||
|
@@ -25,6 +25,7 @@
|
||||
package org.alfresco.repo.tenant;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
@@ -252,6 +253,43 @@ public class TenantInterpreter extends BaseInterpreter
|
||||
out.println("bootstrap workflows deployed for tenant: " + newTenant);
|
||||
}
|
||||
|
||||
else if (command[0].equals("import"))
|
||||
{
|
||||
if ((command.length != 3) && (command.length != 4))
|
||||
{
|
||||
return "Syntax Error, try 'help'.\n";
|
||||
}
|
||||
|
||||
String newTenant = new String(command[1]).toLowerCase();
|
||||
File directorySource = new File(command[2]);
|
||||
|
||||
String rootContentStoreDir = null;
|
||||
if (command.length == 4)
|
||||
{
|
||||
rootContentStoreDir = new String(command[3]);
|
||||
}
|
||||
|
||||
tenantAdminService.importTenant(newTenant, directorySource, rootContentStoreDir);
|
||||
|
||||
out.println("imported tenant: " + newTenant);
|
||||
out.print(executeCommand("bootstrapWorkflows " + newTenant));
|
||||
}
|
||||
|
||||
else if (command[0].equals("export"))
|
||||
{
|
||||
if (command.length != 3)
|
||||
{
|
||||
return "Syntax Error, try 'help'.\n";
|
||||
}
|
||||
|
||||
String tenant = new String(command[1]).toLowerCase();
|
||||
File directoryDestination = new File(command[2]);
|
||||
|
||||
tenantAdminService.exportTenant(tenant, directoryDestination);
|
||||
|
||||
out.println("exported tenant: " + tenant);
|
||||
}
|
||||
|
||||
// TODO - not fully working yet
|
||||
else if (command[0].equals("delete"))
|
||||
{
|
||||
|
@@ -171,7 +171,7 @@ public class WorkflowDefinitionType implements ContentServicePolicies.OnContentU
|
||||
undeploy(nodeRef);
|
||||
}
|
||||
|
||||
private void deploy(NodeRef nodeRef)
|
||||
public void deploy(NodeRef nodeRef)
|
||||
{
|
||||
// Ignore if the node is a working copy
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY) == false)
|
||||
|
Reference in New Issue
Block a user