2 * This document is a part of the source code and related artifacts
3 * for CollectionSpace, an open source collections management system
4 * for museums and related institutions:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
24 package org.collectionspace.services.common.config;
27 import java.util.ArrayList;
28 import java.util.Hashtable;
29 import java.util.List;
31 import org.collectionspace.services.common.ClientType;
32 import org.collectionspace.services.common.RepositoryClientConfigType;
33 import org.collectionspace.services.common.ServiceMain;
34 import org.collectionspace.services.common.repository.RepositoryClient;
35 import org.collectionspace.services.common.repository.RepositoryClientFactory;
36 import org.collectionspace.services.common.service.ServiceBindingType;
37 import org.collectionspace.services.common.tenant.TenantBindingType;
38 import org.collectionspace.services.common.tenant.TenantBindingConfig;
39 import org.collectionspace.services.common.types.PropertyItemType;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
44 * ServicesConfigReader reads service layer specific configuration
46 * $LastChangedRevision: $
49 public class TenantBindingConfigReaderImpl
50 extends AbstractConfigReaderImpl<TenantBindingConfig> {
52 final private static String CONFIG_FILE_NAME = "tenant-bindings.xml";
53 final Logger logger = LoggerFactory.getLogger(TenantBindingConfigReaderImpl.class);
54 private TenantBindingConfig tenantBindingConfig;
55 //tenant name, tenant binding
56 private Hashtable<String, TenantBindingType> tenantBindings =
57 new Hashtable<String, TenantBindingType>();
58 //tenant-qualified servicename, service binding
59 private Hashtable<String, ServiceBindingType> serviceBindings =
60 new Hashtable<String, ServiceBindingType>();
61 //tenant-qualified service, workspace
62 private Hashtable<String, String> serviceWorkspaces = new Hashtable<String, String>();
64 public TenantBindingConfigReaderImpl(String serverRootDir) {
69 public String getFileName() {
70 return CONFIG_FILE_NAME;
74 public void read() throws Exception {
75 String configFileName = getAbsoluteFileName(CONFIG_FILE_NAME);
76 File configFile = new File(configFileName);
77 if (!configFile.exists()) {
78 String msg = "Could not find configuration file " + configFileName;
80 throw new RuntimeException(msg);
82 tenantBindingConfig = (TenantBindingConfig) parse(configFile, TenantBindingConfig.class);
83 for (TenantBindingType tenantBinding : tenantBindingConfig.getTenantBinding()) {
84 tenantBindings.put(tenantBinding.getId(), tenantBinding);
85 readServiceBindings(tenantBinding);
86 if (logger.isDebugEnabled()) {
87 logger.debug("read() added tenant id=" + tenantBinding.getId()
88 + " name=" + tenantBinding.getName());
93 private void readServiceBindings(TenantBindingType tenantBinding) throws Exception {
94 for (ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()) {
95 String key = getTenantQualifiedServiceName(tenantBinding.getId(),
96 serviceBinding.getName());
97 serviceBindings.put(key, serviceBinding);
98 if (logger.isDebugEnabled()) {
99 logger.debug("readServiceBindings() added service "
101 + " workspace=" + serviceBinding.getName());
107 * retrieveWorkspaceIds is called at initialization time to retrieve
108 * workspace ids of all the tenants
111 public void retrieveAllWorkspaceIds() throws Exception {
112 for (TenantBindingType tenantBinding : tenantBindings.values()) {
113 retrieveWorkspaceIds(tenantBinding);
118 * retrieveWorkspaceIds retrieves workspace ids for services used by
120 * @param tenantBinding
123 public void retrieveWorkspaceIds(TenantBindingType tenantBinding) throws Exception {
124 Hashtable<String, String> workspaceIds = new Hashtable<String, String>();
125 ServiceMain svcMain = ServiceMain.getInstance();
126 RepositoryClientConfigType rclientConfig = svcMain.getServicesConfigReader().getConfiguration().getRepositoryClient();
127 ClientType clientType = svcMain.getClientType();
128 if (clientType.equals(ClientType.JAVA)
129 && rclientConfig.getName().equalsIgnoreCase("nuxeo-java")) {
130 //FIXME only one repository client is recognized
131 workspaceIds = svcMain.getNuxeoConnector().retrieveWorkspaceIds(
132 tenantBinding.getRepositoryDomain());
134 //verify if workspace exists for each service in the tenant binding
135 for (ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()) {
136 String serviceName = serviceBinding.getName();
137 String repositoryClientName = serviceBinding.getRepositoryClient();
138 if (repositoryClientName == null) {
139 //no repository needed for this service...skip
140 if (logger.isInfoEnabled()) {
141 logger.info("The service " + serviceName
142 + " does not seem to require a document repository.");
147 if (repositoryClientName.isEmpty()) {
148 String msg = "Invalid repositoryClient " + serviceName;
152 repositoryClientName = repositoryClientName.trim();
153 RepositoryClient repositoryClient = getRepositoryClient(
154 repositoryClientName);
155 if (repositoryClient == null) {
156 String msg = "Could not find repositoryClient " + repositoryClientName
157 + " for service=" + serviceName;
161 String workspaceId = null;
162 //workspace name is service name by convention
163 String workspace = serviceName.toLowerCase();
164 if (clientType.equals(ClientType.JAVA)) {
165 workspaceId = workspaceIds.get(workspace);
166 if (workspaceId == null) {
167 if (logger.isWarnEnabled()) {
168 logger.warn("Failed to retrieve workspace ID for " + workspace
169 + " from repository, trying to create a new workspace ...");
171 workspaceId = repositoryClient.createWorkspace(
172 tenantBinding.getRepositoryDomain(),
173 serviceBinding.getName());
174 if (workspaceId == null) {
175 if (logger.isWarnEnabled()) {
176 logger.warn("Failed to create workspace in repository"
177 + " for service=" + workspace);
181 if (logger.isDebugEnabled()) {
182 logger.debug("Successfully created workspace in repository" +
183 " id=" + workspaceId + " for service=" + workspace);
187 workspaceId = serviceBinding.getRepositoryWorkspaceId();
188 if (workspaceId == null || "".equals(workspaceId)) {
189 logger.error("Could not find workspace in repository for" +
190 " service=" + workspace);
191 //FIXME: should we throw an exception here?
195 String tenantService = getTenantQualifiedServiceName(tenantBinding.getId(), serviceName);
196 serviceWorkspaces.put(tenantService, workspaceId);
197 if (logger.isInfoEnabled()) {
198 logger.info("Created/retrieved repository workspace=" +
199 workspace + " id=" + workspaceId
200 + " for service=" + serviceName);
206 public TenantBindingConfig getConfiguration() {
207 return tenantBindingConfig;
211 * getTenantBinding gets tenant binding for given tenant
215 public TenantBindingType getTenantBinding(
217 return tenantBindings.get(tenantId);
221 * getServiceBinding gets service binding for given tenant for a given service
226 public ServiceBindingType getServiceBinding(
227 String tenantId, String serviceName) {
228 String key = getTenantQualifiedServiceName(tenantId, serviceName);
229 return serviceBindings.get(key);
233 * getServiceBinding gets service binding for given tenant for a given service
238 public List<ServiceBindingType> getServiceBindingsByType(
239 String tenantId, String serviceType) {
240 ArrayList<ServiceBindingType> list = null;
241 TenantBindingType tenant = tenantBindings.get(tenantId);
242 if (tenant != null) {
243 for (ServiceBindingType sb : tenant.getServiceBindings()) {
244 if (serviceType.equals(sb.getType())) {
246 list = new ArrayList<ServiceBindingType>();
256 * getWorkspaceId retrieves workspace id for given tenant for given service
261 public String getWorkspaceId(String tenantId, String serviceName) {
262 String tenantService = getTenantQualifiedServiceName(tenantId, serviceName);
263 return serviceWorkspaces.get(tenantService);
269 * @return the properly qualified service name
271 public static String getTenantQualifiedServiceName(
272 String tenantId, String serviceName) {
273 return tenantId + "." + serviceName.toLowerCase();
276 private RepositoryClient getRepositoryClient(String clientName) {
277 return RepositoryClientFactory.getInstance().getClient(clientName);
281 * Sets properties in the passed list on the local properties for this TenantBinding.
282 * Note: will only set properties not already set on the TenantBinding.
285 * @param propagateToServices If true, recurses to set set properties
286 * on the associated services.
288 public void setDefaultPropertiesOnTenants(List<PropertyItemType> propList,
289 boolean propagateToServices) {
290 // For each tenant, set properties in list that are not already set
291 if (propList == null || propList.isEmpty()) {
294 for (TenantBindingType tenant : tenantBindings.values()) {
295 for (PropertyItemType prop : propList) {
296 TenantBindingUtils.setPropertyValue(tenant,
297 prop, TenantBindingUtils.SET_PROP_IF_MISSING);
299 if (propagateToServices) {
300 TenantBindingUtils.propagatePropertiesToServices(tenant,
301 TenantBindingUtils.SET_PROP_IF_MISSING);