blob: 8e569048696baab56f819907a8bc233cac0f9e49 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.apache.ambari.server.state;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ObjectNotFoundException;
import org.apache.ambari.server.ServiceComponentNotFoundException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.collections.Predicate;
import org.apache.ambari.server.collections.PredicateUtils;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.ServiceResponse;
import org.apache.ambari.server.controller.internal.AmbariServerLDAPConfigurationHandler;
import org.apache.ambari.server.controller.internal.AmbariServerSSOConfigurationHandler;
import org.apache.ambari.server.controller.internal.DeleteHostComponentStatusMetaData;
import org.apache.ambari.server.events.MaintenanceModeEvent;
import org.apache.ambari.server.events.ServiceCredentialStoreUpdateEvent;
import org.apache.ambari.server.events.ServiceInstalledEvent;
import org.apache.ambari.server.events.ServiceRemovedEvent;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.dao.ClusterDAO;
import org.apache.ambari.server.orm.dao.ClusterServiceDAO;
import org.apache.ambari.server.orm.dao.ServiceConfigDAO;
import org.apache.ambari.server.orm.dao.ServiceDesiredStateDAO;
import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
import org.apache.ambari.server.orm.entities.ClusterEntity;
import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
import org.apache.ambari.server.orm.entities.ClusterServiceEntityPK;
import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
import org.apache.ambari.server.orm.entities.ServiceDesiredStateEntity;
import org.apache.ambari.server.orm.entities.ServiceDesiredStateEntityPK;
import org.apache.ambari.server.orm.entities.StackEntity;
import org.apache.ambari.server.serveraction.kerberos.Component;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.google.inject.ProvisionException;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import com.google.inject.persist.Transactional;
public class ServiceImpl implements Service {
private final Lock lock = new ReentrantLock();
private ServiceDesiredStateEntityPK serviceDesiredStateEntityPK;
private ClusterServiceEntityPK serviceEntityPK;
private static final Logger LOG = LoggerFactory.getLogger(ServiceImpl.class);
private final Cluster cluster;
private final ConcurrentMap<String, ServiceComponent> components = new ConcurrentHashMap<>();
private boolean isClientOnlyService;
private boolean isCredentialStoreSupported;
private boolean isCredentialStoreRequired;
private final boolean ssoIntegrationSupported;
private final Predicate ssoEnabledTest;
private final boolean ldapIntegrationSupported;
private final Predicate ldapEnabledTest;
private final boolean ssoRequiresKerberos;
private final Predicate kerberosEnabledTest;
private AmbariMetaInfo ambariMetaInfo;
private AtomicReference<MaintenanceState> maintenanceState = new AtomicReference<>();
@Inject
private ServiceConfigDAO serviceConfigDAO;
@Inject
private AmbariManagementController ambariManagementController;
@Inject
private ConfigHelper configHelper;
@Inject
private AmbariServerSSOConfigurationHandler ambariServerSSOConfigurationHandler;
@Inject
private AmbariServerLDAPConfigurationHandler ambariServerLDAPConfigurationHandler;
private final ClusterServiceDAO clusterServiceDAO;
private final ServiceDesiredStateDAO serviceDesiredStateDAO;
private final ClusterDAO clusterDAO;
private final ServiceComponentFactory serviceComponentFactory;
/**
* Used to publish events relating to service CRUD operations.
*/
private final AmbariEventPublisher eventPublisher;
/**
* The name of the service.
*/
private final String serviceName;
private final String displayName;
@AssistedInject
ServiceImpl(@Assisted Cluster cluster, @Assisted String serviceName,
@Assisted RepositoryVersionEntity desiredRepositoryVersion, ClusterDAO clusterDAO,
ClusterServiceDAO clusterServiceDAO, ServiceDesiredStateDAO serviceDesiredStateDAO,
ServiceComponentFactory serviceComponentFactory, AmbariMetaInfo ambariMetaInfo,
AmbariEventPublisher eventPublisher) throws AmbariException {
this.cluster = cluster;
this.clusterDAO = clusterDAO;
this.clusterServiceDAO = clusterServiceDAO;
this.serviceDesiredStateDAO = serviceDesiredStateDAO;
this.serviceComponentFactory = serviceComponentFactory;
this.eventPublisher = eventPublisher;
this.serviceName = serviceName;
this.ambariMetaInfo = ambariMetaInfo;
ClusterServiceEntity serviceEntity = new ClusterServiceEntity();
serviceEntity.setClusterId(cluster.getClusterId());
serviceEntity.setServiceName(serviceName);
ServiceDesiredStateEntity serviceDesiredStateEntity = new ServiceDesiredStateEntity();
serviceDesiredStateEntity.setServiceName(serviceName);
serviceDesiredStateEntity.setClusterId(cluster.getClusterId());
serviceDesiredStateEntity.setDesiredRepositoryVersion(desiredRepositoryVersion);
serviceDesiredStateEntityPK = getServiceDesiredStateEntityPK(serviceDesiredStateEntity);
serviceEntityPK = getServiceEntityPK(serviceEntity);
serviceDesiredStateEntity.setClusterServiceEntity(serviceEntity);
serviceEntity.setServiceDesiredStateEntity(serviceDesiredStateEntity);
StackId stackId = desiredRepositoryVersion.getStackId();
ServiceInfo sInfo = ambariMetaInfo.getService(stackId.getStackName(),
stackId.getStackVersion(), serviceName);
displayName = sInfo.getDisplayName();
isClientOnlyService = sInfo.isClientOnlyService();
isCredentialStoreSupported = sInfo.isCredentialStoreSupported();
isCredentialStoreRequired = sInfo.isCredentialStoreRequired();
ssoIntegrationSupported = sInfo.isSingleSignOnSupported();
ssoEnabledTest = compileSsoEnabledPredicate(sInfo);
ssoRequiresKerberos = sInfo.isKerberosRequiredForSingleSignOnIntegration();
kerberosEnabledTest = compileKerberosEnabledPredicate(sInfo);
if (ssoIntegrationSupported && ssoRequiresKerberos && (kerberosEnabledTest == null)) {
LOG.warn("The service, {}, requires Kerberos to be enabled for SSO integration support; " +
"however, the kerberosEnabledTest specification has not been specified in the metainfo.xml file. " +
"Automated SSO integration will not be allowed for this service.",
serviceName);
}
ldapIntegrationSupported = sInfo.isLdapSupported();
ldapEnabledTest = StringUtils.isNotBlank(sInfo.getLdapEnabledTest()) ? PredicateUtils.fromJSON(sInfo.getLdapEnabledTest()) : null;
persist(serviceEntity);
}
@AssistedInject
ServiceImpl(@Assisted Cluster cluster, @Assisted ClusterServiceEntity serviceEntity,
ClusterDAO clusterDAO, ClusterServiceDAO clusterServiceDAO,
ServiceDesiredStateDAO serviceDesiredStateDAO,
ServiceComponentFactory serviceComponentFactory, AmbariMetaInfo ambariMetaInfo,
AmbariEventPublisher eventPublisher) throws AmbariException {
this.cluster = cluster;
this.clusterDAO = clusterDAO;
this.clusterServiceDAO = clusterServiceDAO;
this.serviceDesiredStateDAO = serviceDesiredStateDAO;
this.serviceComponentFactory = serviceComponentFactory;
this.eventPublisher = eventPublisher;
serviceName = serviceEntity.getServiceName();
this.ambariMetaInfo = ambariMetaInfo;
ServiceDesiredStateEntity serviceDesiredStateEntity = serviceEntity.getServiceDesiredStateEntity();
serviceDesiredStateEntityPK = getServiceDesiredStateEntityPK(serviceDesiredStateEntity);
serviceEntityPK = getServiceEntityPK(serviceEntity);
if (!serviceEntity.getServiceComponentDesiredStateEntities().isEmpty()) {
for (ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity
: serviceEntity.getServiceComponentDesiredStateEntities()) {
try {
components.put(serviceComponentDesiredStateEntity.getComponentName(),
serviceComponentFactory.createExisting(this,
serviceComponentDesiredStateEntity));
} catch (ProvisionException ex) {
StackId stackId = new StackId(serviceComponentDesiredStateEntity.getDesiredStack());
LOG.error(String.format("Can not get component info: stackName=%s, stackVersion=%s, serviceName=%s, componentName=%s",
stackId.getStackName(), stackId.getStackVersion(),
serviceEntity.getServiceName(), serviceComponentDesiredStateEntity.getComponentName()));
ex.printStackTrace();
}
}
}
StackId stackId = getDesiredStackId();
ServiceInfo sInfo = ambariMetaInfo.getService(stackId.getStackName(),
stackId.getStackVersion(), getName());
isClientOnlyService = sInfo.isClientOnlyService();
isCredentialStoreSupported = sInfo.isCredentialStoreSupported();
isCredentialStoreRequired = sInfo.isCredentialStoreRequired();
displayName = sInfo.getDisplayName();
ssoIntegrationSupported = sInfo.isSingleSignOnSupported();
ssoEnabledTest = compileSsoEnabledPredicate(sInfo);
ssoRequiresKerberos = sInfo.isKerberosRequiredForSingleSignOnIntegration();
kerberosEnabledTest = compileKerberosEnabledPredicate(sInfo);
if (ssoIntegrationSupported && ssoRequiresKerberos && (kerberosEnabledTest == null)) {
LOG.warn("The service, {}, requires Kerberos to be enabled for SSO integration support; " +
"however, the kerberosEnabledTest specification has not been specified in the metainfo.xml file. " +
"Automated SSO integration will not be allowed for this service.",
serviceName);
}
ldapIntegrationSupported = sInfo.isLdapSupported();
ldapEnabledTest = StringUtils.isNotBlank(sInfo.getLdapEnabledTest()) ? PredicateUtils.fromJSON(sInfo.getLdapEnabledTest()) : null;
}
/***
* Refresh Service info due to current stack
* @throws AmbariException
*/
@Override
public void updateServiceInfo() throws AmbariException {
try {
ServiceInfo serviceInfo = ambariMetaInfo.getService(this);
isClientOnlyService = serviceInfo.isClientOnlyService();
isCredentialStoreSupported = serviceInfo.isCredentialStoreSupported();
isCredentialStoreRequired = serviceInfo.isCredentialStoreRequired();
} catch (ObjectNotFoundException e) {
throw new RuntimeException("Trying to create a ServiceInfo"
+ " not recognized in stack info"
+ ", clusterName=" + cluster.getClusterName()
+ ", serviceName=" + getName()
+ ", stackInfo=" + getDesiredStackId().getStackName());
}
}
@Override
public String getName() {
return serviceName;
}
@Override
public String getDisplayName() {
return StringUtils.isBlank(displayName) ? serviceName : displayName;
}
@Override
public long getClusterId() {
return cluster.getClusterId();
}
@Override
public Map<String, ServiceComponent> getServiceComponents() {
return new HashMap<>(components);
}
@Override
public Set<String> getServiceHosts() {
Set<String> hostNames = new HashSet<>();
for (ServiceComponent serviceComponent : getServiceComponents().values()) {
hostNames.addAll(serviceComponent.getServiceComponentsHosts());
}
return hostNames;
}
@Override
public void addServiceComponents(
Map<String, ServiceComponent> components) throws AmbariException {
for (ServiceComponent sc : components.values()) {
addServiceComponent(sc);
}
}
@Override
public void addServiceComponent(ServiceComponent component) throws AmbariException {
if (components.containsKey(component.getName())) {
throw new AmbariException("Cannot add duplicate ServiceComponent"
+ ", clusterName=" + cluster.getClusterName()
+ ", clusterId=" + cluster.getClusterId()
+ ", serviceName=" + getName()
+ ", serviceComponentName=" + component.getName());
}
components.put(component.getName(), component);
}
@Override
public ServiceComponent addServiceComponent(String serviceComponentName)
throws AmbariException {
ServiceComponent component = serviceComponentFactory.createNew(this, serviceComponentName);
addServiceComponent(component);
return component;
}
@Override
public ServiceComponent getServiceComponent(String componentName)
throws AmbariException {
ServiceComponent serviceComponent = components.get(componentName);
if (null == serviceComponent) {
throw new ServiceComponentNotFoundException(cluster.getClusterName(),
getName(), componentName);
}
return serviceComponent;
}
@Override
public State getDesiredState() {
ServiceDesiredStateEntity serviceDesiredStateEntity = getServiceDesiredStateEntity();
return serviceDesiredStateEntity.getDesiredState();
}
@Override
public void setDesiredState(State state) {
if (LOG.isDebugEnabled()) {
LOG.debug("Setting DesiredState of Service, clusterName={}, clusterId={}, serviceName={}, oldDesiredState={}, newDesiredState={}",
cluster.getClusterName(), cluster.getClusterId(), getName(), getDesiredState(), state);
}
ServiceDesiredStateEntity serviceDesiredStateEntity = getServiceDesiredStateEntity();
serviceDesiredStateEntity.setDesiredState(state);
serviceDesiredStateDAO.merge(serviceDesiredStateEntity);
}
/**
* {@inheritDoc}
*/
@Override
public StackId getDesiredStackId() {
ServiceDesiredStateEntity serviceDesiredStateEntity = getServiceDesiredStateEntity();
if (null == serviceDesiredStateEntity) {
return null;
} else {
StackEntity desiredStackEntity = serviceDesiredStateEntity.getDesiredStack();
return new StackId(desiredStackEntity);
}
}
/**
* {@inheritDoc}
*/
@Override
public RepositoryVersionEntity getDesiredRepositoryVersion() {
ServiceDesiredStateEntity serviceDesiredStateEntity = getServiceDesiredStateEntity();
return serviceDesiredStateEntity.getDesiredRepositoryVersion();
}
/**
* {@inheritDoc}
*/
@Override
@Transactional
public void setDesiredRepositoryVersion(RepositoryVersionEntity repositoryVersionEntity) {
ServiceDesiredStateEntity serviceDesiredStateEntity = getServiceDesiredStateEntity();
serviceDesiredStateEntity.setDesiredRepositoryVersion(repositoryVersionEntity);
serviceDesiredStateDAO.merge(serviceDesiredStateEntity);
Collection<ServiceComponent> components = getServiceComponents().values();
for (ServiceComponent component : components) {
component.setDesiredRepositoryVersion(repositoryVersionEntity);
}
}
/**
* {@inheritDoc}
*/
@Override
public RepositoryVersionState getRepositoryState() {
if (components.isEmpty()) {
return RepositoryVersionState.NOT_REQUIRED;
}
List<RepositoryVersionState> states = new ArrayList<>();
for (ServiceComponent component : components.values()) {
states.add(component.getRepositoryState());
}
return RepositoryVersionState.getAggregateState(states);
}
@Override
public ServiceResponse convertToResponse() {
RepositoryVersionEntity desiredRespositoryVersion = getDesiredRepositoryVersion();
StackId desiredStackId = desiredRespositoryVersion.getStackId();
Map<String, Map<String, String>> existingConfigurations;
try {
existingConfigurations = configHelper.calculateExistingConfigurations(ambariManagementController, cluster);
} catch (AmbariException e) {
LOG.warn("Failed to get the existing configurations for the cluster. Predicate calculations may not be correct due to missing data.");
existingConfigurations = Collections.emptyMap();
}
ServiceResponse r = new ServiceResponse(cluster.getClusterId(), cluster.getClusterName(),
getName(), desiredStackId, desiredRespositoryVersion.getVersion(), getRepositoryState(),
getDesiredState().toString(), isCredentialStoreSupported(), isCredentialStoreEnabled(),
ssoIntegrationSupported, isSsoIntegrationDesired(), isSsoIntegrationEnabled(existingConfigurations),
isKerberosRequiredForSsoIntegration(), isKerberosEnabled(existingConfigurations), ldapIntegrationSupported,isLdapIntegrationEnabeled(existingConfigurations), isLdapIntegrationDesired());
r.setDesiredRepositoryVersionId(desiredRespositoryVersion.getId());
r.setMaintenanceState(getMaintenanceState().name());
return r;
}
@Override
public Cluster getCluster() {
return cluster;
}
/**
* Get a true or false value specifying whether
* credential store is supported by this service.
*
* @return true or false
*/
@Override
public boolean isCredentialStoreSupported() {
return isCredentialStoreSupported;
}
/**
* Get a true or false value specifying whether
* credential store is required by this service.
*
* @return true or false
*/
@Override
public boolean isCredentialStoreRequired() {
return isCredentialStoreRequired;
}
/**
* Get a true or false value specifying whether
* credential store use is enabled for this service.
*
* @return true or false
*/
@Override
public boolean isCredentialStoreEnabled() {
ServiceDesiredStateEntity desiredStateEntity = getServiceDesiredStateEntity();
if (desiredStateEntity != null) {
return desiredStateEntity.isCredentialStoreEnabled();
} else {
LOG.warn("Trying to fetch a member from an entity object that may " +
"have been previously deleted, serviceName = " + getName());
}
return false;
}
/**
* Set a true or false value specifying whether this
* service is to be enabled for credential store use.
*
* @param credentialStoreEnabled - true or false
*/
@Override
public void setCredentialStoreEnabled(boolean credentialStoreEnabled) {
if (LOG.isDebugEnabled()) {
LOG.debug("Setting CredentialStoreEnabled of Service, clusterName={}, clusterId={}, serviceName={}, oldCredentialStoreEnabled={}, newCredentialStoreEnabled={}",
cluster.getClusterName(), cluster.getClusterId(), getName(), isCredentialStoreEnabled(), credentialStoreEnabled);
}
ServiceDesiredStateEntity desiredStateEntity = getServiceDesiredStateEntity();
if (desiredStateEntity != null) {
ServiceCredentialStoreUpdateEvent serviceCredentialStoreUpdateEvent = null;
//create event only if the value changed
if (desiredStateEntity.isCredentialStoreEnabled() != credentialStoreEnabled) {
StackId stackId = getDesiredStackId();
serviceCredentialStoreUpdateEvent =
new ServiceCredentialStoreUpdateEvent(getClusterId(), stackId.getStackName(),
stackId.getStackVersion(), getName());
}
desiredStateEntity.setCredentialStoreEnabled(credentialStoreEnabled);
desiredStateEntity = serviceDesiredStateDAO.merge(desiredStateEntity);
//publish event after the value has changed
if (serviceCredentialStoreUpdateEvent != null) {
eventPublisher.publish(serviceCredentialStoreUpdateEvent);
}
} else {
LOG.warn("Setting a member on an entity object that may have been "
+ "previously deleted, serviceName = " + getName());
}
}
@Override
public void debugDump(StringBuilder sb) {
sb.append("Service={ serviceName=").append(getName())
.append(", clusterName=").append(cluster.getClusterName())
.append(", clusterId=").append(cluster.getClusterId())
.append(", desiredStackVersion=").append(getDesiredStackId())
.append(", desiredState=").append(getDesiredState())
.append(", components=[ ");
boolean first = true;
for (ServiceComponent sc : components.values()) {
if (!first) {
sb.append(" , ");
}
first = false;
sb.append("\n ");
sc.debugDump(sb);
sb.append(" ");
}
sb.append(" ] }");
}
/**
*
*/
private void persist(ClusterServiceEntity serviceEntity) {
persistEntities(serviceEntity);
// publish the service installed event
StackId stackId = getDesiredStackId();
cluster.addService(this);
ServiceInstalledEvent event = new ServiceInstalledEvent(getClusterId(), stackId.getStackName(),
stackId.getStackVersion(), getName());
eventPublisher.publish(event);
}
@Transactional
void persistEntities(ClusterServiceEntity serviceEntity) {
long clusterId = cluster.getClusterId();
ClusterEntity clusterEntity = clusterDAO.findById(clusterId);
serviceEntity.setClusterEntity(clusterEntity);
clusterServiceDAO.create(serviceEntity);
clusterEntity.getClusterServiceEntities().add(serviceEntity);
clusterDAO.merge(clusterEntity);
clusterServiceDAO.merge(serviceEntity);
}
@Override
public boolean canBeRemoved() {
//
// A service can be deleted if all it's components
// can be removed, irrespective of the state of
// the service itself.
//
for (ServiceComponent sc : components.values()) {
if (!sc.canBeRemoved()) {
LOG.warn("Found non removable component when trying to delete service" + ", clusterName="
+ cluster.getClusterName() + ", serviceName=" + getName() + ", componentName="
+ sc.getName());
return false;
}
}
return true;
}
@Transactional
void deleteAllServiceConfigs() throws AmbariException {
long clusterId = getClusterId();
ServiceConfigEntity lastServiceConfigEntity = serviceConfigDAO.findMaxVersion(clusterId, getName());
// de-select every configuration from the service
if (lastServiceConfigEntity != null) {
for (ClusterConfigEntity serviceConfigEntity : lastServiceConfigEntity.getClusterConfigEntities()) {
LOG.info("Disabling and unmapping configuration {}", serviceConfigEntity);
serviceConfigEntity.setSelected(false);
serviceConfigEntity.setUnmapped(true);
clusterDAO.merge(serviceConfigEntity);
}
}
LOG.info("Deleting all configuration associations for {} on cluster {}", getName(), cluster.getClusterName());
List<ServiceConfigEntity> serviceConfigEntities =
serviceConfigDAO.findByService(cluster.getClusterId(), getName());
for (ServiceConfigEntity serviceConfigEntity : serviceConfigEntities) {
// unmapping all service configs
for (ClusterConfigEntity clusterConfigEntity : serviceConfigEntity.getClusterConfigEntities()) {
if (!clusterConfigEntity.isUnmapped()) {
LOG.info("Unmapping configuration {}", clusterConfigEntity);
clusterConfigEntity.setUnmapped(true);
clusterDAO.merge(clusterConfigEntity);
}
}
// Only delete the historical version information and not original
// config data
serviceConfigDAO.remove(serviceConfigEntity);
}
}
void deleteAllServiceConfigGroups() throws AmbariException {
for (Long configGroupId : cluster.getConfigGroupsByServiceName(serviceName).keySet()) {
cluster.deleteConfigGroup(configGroupId);
}
}
@Override
@Transactional
public void deleteAllComponents(DeleteHostComponentStatusMetaData deleteMetaData) {
lock.lock();
try {
LOG.info("Deleting all components for service" + ", clusterName=" + cluster.getClusterName()
+ ", serviceName=" + getName());
// FIXME check dependencies from meta layer
for (ServiceComponent component : components.values()) {
if (!component.canBeRemoved()) {
deleteMetaData.setAmbariException(new AmbariException("Found non removable component when trying to"
+ " delete all components from service" + ", clusterName=" + cluster.getClusterName()
+ ", serviceName=" + getName() + ", componentName=" + component.getName()));
return;
}
}
for (ServiceComponent serviceComponent : components.values()) {
serviceComponent.delete(deleteMetaData);
if (deleteMetaData.getAmbariException() != null) {
return;
}
}
components.clear();
} finally {
lock.unlock();
}
}
@Override
public void deleteServiceComponent(String componentName, DeleteHostComponentStatusMetaData deleteMetaData)
throws AmbariException {
lock.lock();
try {
ServiceComponent component = getServiceComponent(componentName);
LOG.info("Deleting servicecomponent for cluster" + ", clusterName=" + cluster.getClusterName()
+ ", serviceName=" + getName() + ", componentName=" + componentName);
// FIXME check dependencies from meta layer
if (!component.canBeRemoved()) {
throw new AmbariException("Could not delete component from cluster"
+ ", clusterName=" + cluster.getClusterName()
+ ", serviceName=" + getName()
+ ", componentName=" + componentName);
}
component.delete(deleteMetaData);
components.remove(componentName);
} finally {
lock.unlock();
}
}
@Override
public boolean isClientOnlyService() {
return isClientOnlyService;
}
@Override
@Transactional
public void delete(DeleteHostComponentStatusMetaData deleteMetaData) {
List<Component> components = getComponents(); // XXX temporal coupling, need to call this BEFORE deletingAllComponents
deleteAllComponents(deleteMetaData);
if (deleteMetaData.getAmbariException() != null) {
return;
}
StackId stackId = getDesiredStackId();
try {
deleteAllServiceConfigs();
deleteAllServiceConfigGroups();
removeEntities();
} catch (AmbariException e) {
deleteMetaData.setAmbariException(e);
return;
}
// publish the service removed event
if (null == stackId) {
return;
}
ServiceRemovedEvent event = new ServiceRemovedEvent(getClusterId(), stackId.getStackName(),
stackId.getStackVersion(), getName(), components);
eventPublisher.publish(event);
}
private List<Component> getComponents() {
List<Component> result = new ArrayList<>();
for (ServiceComponent component : getServiceComponents().values()) {
for (ServiceComponentHost host : component.getServiceComponentHosts().values()) {
result.add(new Component(host.getHostName(), getName(), component.getName(), host.getHost().getHostId()));
}
}
return result;
}
@Transactional
protected void removeEntities() throws AmbariException {
serviceDesiredStateDAO.removeByPK(serviceDesiredStateEntityPK);
clusterServiceDAO.removeByPK(serviceEntityPK);
}
@Override
public void setMaintenanceState(MaintenanceState state) {
ServiceDesiredStateEntity serviceDesiredStateEntity = getServiceDesiredStateEntity();
serviceDesiredStateEntity.setMaintenanceState(state);
maintenanceState.set(serviceDesiredStateDAO.merge(serviceDesiredStateEntity).getMaintenanceState());
// broadcast the maintenance mode change
MaintenanceModeEvent event = new MaintenanceModeEvent(state, this);
eventPublisher.publish(event);
}
@Override
public MaintenanceState getMaintenanceState() {
if (maintenanceState.get() == null) {
maintenanceState.set(getServiceDesiredStateEntity().getMaintenanceState());
}
return maintenanceState.get();
}
@Override
public boolean isKerberosEnabled() {
if (kerberosEnabledTest != null) {
Map<String, Map<String, String>> existingConfigurations;
try {
existingConfigurations = configHelper.calculateExistingConfigurations(ambariManagementController, cluster);
} catch (AmbariException e) {
LOG.warn("Failed to get the existing configurations for the cluster. Predicate calculations may not be correct due to missing data.");
existingConfigurations = Collections.emptyMap();
}
return isKerberosEnabled(existingConfigurations);
}
return false;
}
@Override
public boolean isKerberosEnabled(Map<String, Map<String, String>> configurations) {
return kerberosEnabledTest != null && kerberosEnabledTest.evaluate(configurations);
}
private ClusterServiceEntityPK getServiceEntityPK(ClusterServiceEntity serviceEntity) {
ClusterServiceEntityPK pk = new ClusterServiceEntityPK();
pk.setClusterId(serviceEntity.getClusterId());
pk.setServiceName(serviceEntity.getServiceName());
return pk;
}
private ServiceDesiredStateEntityPK getServiceDesiredStateEntityPK(ServiceDesiredStateEntity serviceDesiredStateEntity) {
ServiceDesiredStateEntityPK pk = new ServiceDesiredStateEntityPK();
pk.setClusterId(serviceDesiredStateEntity.getClusterId());
pk.setServiceName(serviceDesiredStateEntity.getServiceName());
return pk;
}
// Refresh the cached reference on setters
private ServiceDesiredStateEntity getServiceDesiredStateEntity() {
return serviceDesiredStateDAO.findByPK(serviceDesiredStateEntityPK);
}
private Predicate compileSsoEnabledPredicate(ServiceInfo sInfo) {
if (StringUtils.isNotBlank(sInfo.getSingleSignOnEnabledTest())) {
if (StringUtils.isNotBlank(sInfo.getSingleSignOnEnabledConfiguration())) {
LOG.warn("Both <ssoEnabledTest> and <enabledConfiguration> have been declared within <sso> for {}; using <ssoEnabledTest>", serviceName);
}
return PredicateUtils.fromJSON(sInfo.getSingleSignOnEnabledTest());
} else if (StringUtils.isNotBlank(sInfo.getSingleSignOnEnabledConfiguration())) {
LOG.warn("Only <enabledConfiguration> have been declared within <sso> for {}; converting its value to an equals predicate", serviceName);
final String equalsPredicateJson = "{\"equals\": [\"" + sInfo.getSingleSignOnEnabledConfiguration() + "\", \"true\"]}";
return PredicateUtils.fromJSON(equalsPredicateJson);
}
return null;
}
private Predicate compileKerberosEnabledPredicate(ServiceInfo sInfo) {
if (StringUtils.isNotBlank(sInfo.getKerberosEnabledTest())) {
return PredicateUtils.fromJSON(sInfo.getKerberosEnabledTest());
}
return null;
}
private boolean isSsoIntegrationDesired() {
return ambariServerSSOConfigurationHandler.getSSOEnabledServices().contains(serviceName);
}
private boolean isSsoIntegrationEnabled(Map<String, Map<String, String>> existingConfigurations) {
return ssoIntegrationSupported && ssoEnabledTest != null && ssoEnabledTest.evaluate(existingConfigurations);
}
private boolean isKerberosRequiredForSsoIntegration() {
return ssoRequiresKerberos;
}
private boolean isLdapIntegrationEnabeled(Map<String, Map<String, String>> existingConfigurations) {
return ldapIntegrationSupported && ldapEnabledTest != null && ldapEnabledTest.evaluate(existingConfigurations);
}
private boolean isLdapIntegrationDesired() {
return ambariServerLDAPConfigurationHandler.getLDAPEnabledServices().contains(serviceName);
}
}