/**
 * Copyright (c) 2013-2014 by Cisco Systems, Inc. 
 * All rights reserved. 
 */
package com.cisco.oss.foundation.directory.impl;

import com.cisco.oss.foundation.directory.DirectoryServiceClientManager;
import com.cisco.oss.foundation.directory.ServiceInstanceHealth;
import com.cisco.oss.foundation.directory.entity.OperationalStatus;
import com.cisco.oss.foundation.directory.entity.ProvidedServiceInstance;
import com.cisco.oss.foundation.directory.exception.ErrorCode;
import com.cisco.oss.foundation.directory.exception.ServiceDirectoryError;
import com.cisco.oss.foundation.directory.exception.ServiceException;
import com.cisco.oss.foundation.directory.exception.ServiceRuntimeException;

/**
 * It is the Directory Registration Service to perform the ServiceInstance registration.
 * 
 * It registers ServiceInstance to DirectoryServer. 
 * 
 * @author zuxiang
 *
 */
public class DirectoryRegistrationService {

	/**
	 * The remote ServiceDirectory node client.
	 */
	private final DirectoryServiceClientManager directoryServiceClientManager;

	/**
	 * Constructor.
	 * 
	 * @param directoryServiceClientManager
	 * 		DirectoryServiceClientManager to get DirectoryServiceClient.
	 */
	public DirectoryRegistrationService(
			DirectoryServiceClientManager directoryServiceClientManager) {
		this.directoryServiceClientManager = directoryServiceClientManager;
	}

	/**
	 * Register a ProvidedServiceInstance.
	 * 
	 * @param serviceInstance
	 * 		the ProvidedServiceInstance.
	 */
	public void registerService(ProvidedServiceInstance serviceInstance) {
		getServiceDirectoryClient().registerInstance(serviceInstance);
	}

	/**
	 * Register a ProvidedServiceInstance with the OperationalStatus.
	 * 
	 * @param serviceInstance
	 * 		the ProvidedServiceInstance.
	 * @param status
	 * 		the OperationalStatus of the ProvidedServiceInstance.
	 */
	public void registerService(ProvidedServiceInstance serviceInstance,
			OperationalStatus status) {

		serviceInstance.setStatus(status);
		registerService(serviceInstance);
	}

	/**
	 * Register a ProvidedServiceInstance with the ServiceInstanceHealth callback.
	 * 
	 * @param serviceInstance
	 * 		the ProvidedServiceInstance.
	 * @param registryHealth
	 * 		the ServiceInstanceHealth callback.
	 */
	public void registerService(ProvidedServiceInstance serviceInstance, ServiceInstanceHealth registryHealth) {
		// Monitor disabled ProvidedServiceInstance should not have the ServiceInstanceHealth.
		if(serviceInstance.isMonitorEnabled()== false){
			throw new ServiceRuntimeException(new ServiceDirectoryError(ErrorCode.SERVICE_INSTANCE_HEALTH_ERROR));
		}
		registerService(serviceInstance);
	}

	/**
	 * Update the uri of the ProvidedServiceInstance by serviceName and providerId.
	 * 
	 * @param serviceName
	 * 		the serviceName of the ProvidedServiceInstance.
	 * @param providerId
	 * 		the providerId of the ProvidedServiceInstance.
	 * @param uri
	 * 		the new uri.
	 */
	public void updateServiceUri(String serviceName, String providerId,
			String uri) {
		getServiceDirectoryClient().updateInstanceUri(serviceName, providerId,
				uri, false);
	}

	/**
	 * Update the OperationalStatus of the ProvidedServiceInstance by serviceName and providerId.
	 * 
	 * @param serviceName
	 * 		the serviceName of the ProvidedServiceInstance.
	 * @param providerId
	 * 		the providerId of the ProvidedServiceInstance.
	 * @param status
	 * 		the new OperationalStatus of the ProvidedServiceInstance.
	 */
	public void updateServiceOperationalStatus(String serviceName,
			String providerId, OperationalStatus status) {
		getServiceDirectoryClient().updateInstanceStatus(serviceName,
				providerId, status, false);

	}

	/**
	 * Update the ProvidedServiceInstance.
	 * 
	 * @param serviceInstance
	 * 		the ProvidedServiceInstance.
	 */
	public void updateService(ProvidedServiceInstance serviceInstance) {
		getServiceDirectoryClient().updateInstance(serviceInstance);

	}

	/**
	 * Unregister a ProvidedServiceInstance by serviceName and providerId.
	 * 
	 * @param serviceName
	 * 		the serviceName of ProvidedServiceInstance.
	 * @param providerId
	 * 		the provierId of ProvidedServiceInstance.
	 */
	public void unregisterService(String serviceName, String providerId) {
		getServiceDirectoryClient().unregisterInstance(serviceName, providerId, false);
	}

	/**
	 * Get the DirectoryServiceClient.
	 * 
	 * @return the DirectoryServiceClient to access remote directory server.
	 */
	protected DirectoryServiceClient getServiceDirectoryClient() {
		try {
			return directoryServiceClientManager.getDirectoryServiceClient();
		} catch (ServiceException e) {
			throw new ServiceRuntimeException(e.getServiceDirectoryError());
		}
	}
}

@@ -127,16 +127,74 @@
 .impl;%0A%0A
+import com.cisco.oss.foundation.directory.Configurations;%0A
 import c
@@ -258,16 +258,16 @@
 anager;%0A
-
 import c
@@ -974,16 +974,392 @@
 ervice %7B
+%0A%09%0A%09/**%0A%09 * The property to disable the ILLEGAL_SERVICE_INSTANCE_OWNER_ERROR error in the Directory tool.%0A%09 */%0A%09public static final String SD_API_REGISTRY_DISABLE_OWNER_ERROR_PROPERTY_NAME = %22registry.disable.owner.error%22;%0A%09%0A%09/**%0A%09 * Default to enable ILLEGAL_SERVICE_INSTANCE_OWNER_ERROR.%0A%09 */%0A%09public static final boolean SD_API_REGISTRY_DISABLE_OWNER_ERROR_DEFAULT = false;
 %0A%0A%09/**%0A%09
@@ -1482,16 +1482,62 @@
 Manager;
+%0A%09%0A%09private boolean disableOwnerError = false;
 %0A%0A%09/**%0A%09
@@ -1844,16 +1844,166 @@
 anager;%0A
+%09%09disableOwnerError = Configurations.getBoolean(SD_API_REGISTRY_DISABLE_OWNER_ERROR_PROPERTY_NAME, %0A%09%09%09%09SD_API_REGISTRY_DISABLE_OWNER_ERROR_DEFAULT);%0A
 %09%7D%0A%0A%09/**
@@ -3731,21 +3731,33 @@
 %09%09%09uri, 
-false
+disableOwnerError
 );%0A%09%7D%0A%0A%09
@@ -4301,21 +4301,33 @@
 status, 
-false
+disableOwnerError
 );%0A%0A%09%7D%0A%0A
@@ -4957,21 +4957,33 @@
 iderId, 
-false
+disableOwnerError
 );%0A%09%7D%0A%0A%09

Add the "registry.disable.owner.error" property to allow Directory Tool to unregister/update ServiceInstance without the "ILLEGAL_OWNER_ERROR".