blob: d294fff8b83c91d32ad3e64b29f69d1ce6c761a0 [file] [log] [blame]
/*******************************************************************************
* Copyright 2017 General Electric Company
*
* Licensed 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.
*
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
package com.ge.predix.acs.service.policy.admin;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import javax.transaction.Transactional;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ge.predix.acs.commons.exception.UntrustedIssuerException;
import com.ge.predix.acs.model.PolicySet;
import com.ge.predix.acs.policy.evaluation.cache.PolicyEvaluationCache;
import com.ge.predix.acs.service.policy.admin.dao.PolicySetEntity;
import com.ge.predix.acs.service.policy.admin.dao.PolicySetRepository;
import com.ge.predix.acs.service.policy.validation.PolicySetValidationException;
import com.ge.predix.acs.service.policy.validation.PolicySetValidator;
import com.ge.predix.acs.utils.JsonUtils;
import com.ge.predix.acs.zone.management.dao.ZoneEntity;
import com.ge.predix.acs.zone.resolver.ZoneResolver;
/**
* @author acs-engineers@ge.com
*/
@Component
@SuppressWarnings("nls")
public class PolicyManagementServiceImpl implements PolicyManagementService {
private static final Logger LOGGER = LoggerFactory.getLogger(PolicyManagementServiceImpl.class);
@Autowired
private PolicyEvaluationCache cache;
@Autowired
private PolicySetRepository policySetRepository;
@Autowired
private ZoneResolver zoneResolver;
@Autowired
private PolicySetValidator policySetValidator;
private final JsonUtils jsonUtils = new JsonUtils();
@Override
public void upsertPolicySet(final PolicySet policySet) {
String policySetName = policySet.getName();
try {
ZoneEntity zone = this.zoneResolver.getZoneEntityOrFail();
validatePolicySet(zone, policySet);
String policySetPayload = this.jsonUtils.serialize(policySet);
upsertPolicySetInTransaction(policySetName, zone, policySetPayload);
} catch (Exception e) {
handleException(e, policySetName);
}
}
@Transactional
private void upsertPolicySetInTransaction(final String policySetName, final ZoneEntity zone,
final String policySetPayload) {
PolicySetEntity existingPolicySetEntity = this.policySetRepository.getByZoneAndPolicySetId(zone, policySetName);
PolicySetEntity policySetEntity = new PolicySetEntity(zone, policySetName, policySetPayload);
// If policy Set already exists, set PK of entity for update
if (null != existingPolicySetEntity) {
LOGGER.debug("Found an existing policy set policySetName = {}, zone = {}, upserting now .", policySetName,
zone);
policySetEntity.setId(existingPolicySetEntity.getId());
} else {
LOGGER.debug("No existing policy set found for policySetName = {}, zone = {}, inserting now .",
policySetName, zone);
}
this.cache.resetForPolicySet(zone.getName(), policySetName);
this.policySetRepository.save(policySetEntity);
}
private void handleException(final Exception e, final String policySetName) {
String message = String
.format("Creation of Policy set %s failed with the following error %s", policySetName, e.getMessage());
LOGGER.error(message, e);
if (e instanceof UntrustedIssuerException || e instanceof PolicyManagementException) {
throw (RuntimeException) e;
}
throw new PolicyManagementException(message, e);
}
@Override
public PolicySet getPolicySet(final String policySetName) {
ZoneEntity zone = this.zoneResolver.getZoneEntityOrFail();
PolicySetEntity policySetEntity = this.policySetRepository.getByZoneAndPolicySetId(zone, policySetName);
if (policySetEntity != null) {
return this.jsonUtils.deserialize(policySetEntity.getPolicySetJson(), PolicySet.class);
}
LOGGER.debug("No policy set found for policySetName = {}, zone = {}.", policySetName, zone);
return null;
}
@Override
public List<PolicySet> getAllPolicySets() {
ZoneEntity zone = this.zoneResolver.getZoneEntityOrFail();
ArrayList<PolicySet> result = new ArrayList<>();
List<PolicySetEntity> policySetEnityList = this.policySetRepository.findByZone(zone);
for (PolicySetEntity policySetEntity : policySetEnityList) {
result.add(this.jsonUtils.deserialize(policySetEntity.getPolicySetJson(), PolicySet.class));
}
return result;
}
@Override
public void deletePolicySet(final String policySetId) {
ZoneEntity zone = this.zoneResolver.getZoneEntityOrFail();
PolicySetEntity policySetEntity = this.policySetRepository.getByZoneAndPolicySetId(zone, policySetId);
if (policySetEntity != null) {
LOGGER.info("Found an existing policy set policySetName={}, zone={}, deleting now.", policySetId,
zone.getName());
PolicySet policySet = this.jsonUtils.deserialize(policySetEntity.getPolicySetJson(), PolicySet.class);
if (policySet != null) {
this.policySetValidator.removeCachedConditions(policySet);
}
// Since we only support one policy set and we don't want to load that policy set when checking for a
// cached invalidation, we use a hard-coded value for the policy set key.
this.cache.resetForPolicySet(zone.getName(), policySetId);
this.policySetRepository.delete(policySetEntity);
} else {
LOGGER.debug("Cound not find an existing policy set " + "policySetName={}, zone={}, Could not delete it.",
policySetId, zone.getName());
}
}
private void validatePolicySet(final ZoneEntity zone, final PolicySet policySet) {
String policySetName = policySet.getName();
if (StringUtils.isEmpty(policySetName)) {
throw new PolicyManagementException("Failed to add policy set because the policy set name is missing");
}
// Validate whether the policy set name is URI acceptable.
try {
URI policySetNameURI = new URI(policySetName);
LOGGER.debug("Creating policy set '{}'.", policySetNameURI);
} catch (URISyntaxException e1) {
LOGGER.debug("Failed to add policy set for policySetName = {}, " + "zone = {}, inserting now.",
policySet.getName(), zone);
throw new PolicyManagementException(
String.format("Failed to add policy set because the policy set name '%s' is not URI friendly.",
policySet.getName()), e1);
}
try {
this.policySetValidator.validatePolicySet(policySet);
} catch (PolicySetValidationException e) {
LOGGER.debug("Policy Validation Failed policySetName = {}, zone = {}.", policySet.getName(), zone);
throw new PolicyManagementException(e.getMessage(), e);
}
}
}