/*
* Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.registry.deployment.synchronizer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.deployment.synchronizer.ArtifactRepository;
import org.wso2.carbon.deployment.synchronizer.DeploymentSynchronizerException;
import org.wso2.carbon.deployment.synchronizer.DeploymentSynchronizerConstants;
import org.wso2.carbon.deployment.synchronizer.util.RepositoryConfigParameter;
import org.wso2.carbon.registry.core.Collection;
import org.wso2.carbon.registry.core.RegistryConstants;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.session.UserRegistry;
import org.wso2.carbon.registry.deployment.synchronizer.utils.RegistryServiceReferenceHolder;
import org.wso2.carbon.registry.synchronization.RegistrySynchronizer;
import org.wso2.carbon.registry.synchronization.SynchronizationException;
import org.wso2.carbon.registry.synchronization.Utils;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import java.util.List;
/**
* Use this class in conjunction with the DeploymentSynchronizer to synchronize a file system
* repository against a repository stored in the registry.
*/
public class RegistryBasedArtifactRepository implements ArtifactRepository {
private static final Log log = LogFactory.getLog(RegistryBasedArtifactRepository.class);
private UserRegistry registry;
private String registryPath;
private String basePath;
private String subscriptionId;
public RegistryBasedArtifactRepository(){}
public RegistryBasedArtifactRepository(UserRegistry registry,
String registryPath, String basePath) {
this.registry = registry;
this.registryPath = registryPath;
this.basePath = basePath;
}
public void init(int tenantId) throws DeploymentSynchronizerException {
try {
UserRegistry configRegistry = getConfigurationRegistry(tenantId);
String tenantRegistryPath = getRegistryPath(tenantId);
this.registry = configRegistry;
this.registryPath = tenantRegistryPath;
this.basePath = RegistryConstants.CONFIG_REGISTRY_BASE_PATH;
if (!configRegistry.resourceExists(tenantRegistryPath)) {
Collection collection = configRegistry.newCollection();
configRegistry.put(tenantRegistryPath, collection);
collection.discard();
}
} catch (RegistryException e) {
throw new DeploymentSynchronizerException("Error while accessing registry for " +
"tenant: " + tenantId, e);
}
// try {
// if (!registry.resourceExists(registryPath)) {
// Collection collection = registry.newCollection();
// registry.put(registryPath, collection);
// collection.discard();
// }
// } catch (RegistryException e) {
// handleException("Error while creating the registry collection at: " + registryPath, e);
// }
}
/**
* This method is used to get configuration registry.
*
* @param tenantId tenant id.
* @return UserRegistry.
* @throws RegistryException Throws when an registry error occurs when getting SystemConfiguration registry.
*/
private static UserRegistry getConfigurationRegistry(int tenantId) throws RegistryException {
return RegistryServiceReferenceHolder.getRegistryService().getConfigSystemRegistry(tenantId);
}
/**
* This method is used to get registry path.
*
* @param tenantId tenant id.
* @return registry path.
*/
private static String getRegistryPath(int tenantId) {
if (tenantId == MultitenantConstants.SUPER_TENANT_ID) {
return DeploymentSynchronizerConstants.SUPER_TENANT_REGISTRY_PATH;
} else {
return DeploymentSynchronizerConstants.TENANT_REGISTRY_PATH;
}
}
public boolean commit(int tenantId, String filePath) throws DeploymentSynchronizerException {
if (log.isDebugEnabled()) {
log.debug("Committing artifacts at " + filePath + " to the collection at " +
registryPath);
}
try {
if (!RegistrySynchronizer.isCheckedOut(filePath)) {
RegistrySynchronizer.checkOut(registry, filePath, registryPath);
}
Utils.addResource(filePath);
Utils.setResourcesDelete(filePath);
return RegistrySynchronizer.checkIn(registry, filePath, false);
} catch (SynchronizationException e) {
handleException("Error while committing artifacts to the registry", e);
}
return false;
}
public boolean checkout(int tenantId, String filePath) throws DeploymentSynchronizerException {
if (log.isDebugEnabled()) {
log.debug("Checking out artifacts from " + registryPath + " to the file system " +
"at " + filePath);
}
boolean succeed = false;
try {
if (RegistrySynchronizer.isCheckedOut(filePath)) {
succeed = RegistrySynchronizer.update(registry, filePath, false);
} else {
succeed = RegistrySynchronizer.checkOut(registry, filePath, registryPath);
}
} catch (SynchronizationException e) {
handleException("Error while updating artifacts in the file system from the registry", e);
}
return succeed;
}
public void initAutoCheckout(boolean useEventing) throws DeploymentSynchronizerException {
// In the registry based implementation we can subscribe for registry events
if (useEventing && subscriptionId == null && RegistryServiceReferenceHolder.getEventingService() != null) {
String absolutePath = RegistryUtils.getAbsoluteRegistryPath(registryPath, basePath);
subscriptionId = RegistryUtils.subscribeForRegistryEvents(registry, absolutePath,
RegistryUtils.getEventReceiverEndpoint());
if (log.isDebugEnabled()) {
log.debug("Subscribed for registry events on the collection: " + absolutePath +
" with the subscription ID: " + subscriptionId);
}
}
}
public void cleanupAutoCheckout() {
if (subscriptionId == null) {
return;
}
boolean unsubscribe = RegistryUtils.unsubscribeForRegistryEvents(subscriptionId,
registry.getTenantId());
if (!unsubscribe) {
log.warn("Subscription for registry events could not be removed");
} else if (log.isDebugEnabled()) {
log.debug("Unsubscribed from registry events with the ID: " + subscriptionId);
}
subscriptionId = null;
}
@Override
public String getRepositoryType() {
return DeploymentSynchronizerConstants.REPOSITORY_TYPE_REGISTRY;
}
@Override
public List<RepositoryConfigParameter> getParameters(){
//Returning null since the Registry Based Artifact Repository does not have any specific
//configuration parameters.
return null;
}
@Override
public boolean checkout(int tenantId, String filePath, int depth)
throws DeploymentSynchronizerException {
throw new DeploymentSynchronizerException("Not implemented yet.");
}
@Override
public boolean update(int tenantId, String rootPath, String filePath, int depth) throws DeploymentSynchronizerException {
throw new DeploymentSynchronizerException("Not implemented yet.");
}
@Override
public void cleanupTenantContext(int tenantId) {
//nothing to do yet. TODO implement reg based tenant contexts
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RegistryBasedArtifactRepository that = (RegistryBasedArtifactRepository) o;
if (!getRepositoryType().equals(that.getRepositoryType())) {
return false;
}
return true;
}
@Override
public int hashCode() {
return getRepositoryType().hashCode();
}
private void handleException(String msg, Exception e) throws DeploymentSynchronizerException {
log.error(msg, e);
throw new DeploymentSynchronizerException(msg, e);
}
}