Aharoni, Pavel (pa0916) | ca3cb01 | 2018-10-22 15:29:57 +0300 | [diff] [blame] | 1 | /*-
|
| 2 | * ============LICENSE_START=======================================================
|
| 3 | * OSAM
|
| 4 | * ================================================================================
|
| 5 | * Copyright (C) 2018 AT&T
|
| 6 | * ================================================================================
|
| 7 | * Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 | * you may not use this file except in compliance with the License.
|
| 9 | * You may obtain a copy of the License at
|
| 10 | *
|
| 11 | * http://www.apache.org/licenses/LICENSE-2.0
|
| 12 | *
|
| 13 | * Unless required by applicable law or agreed to in writing, software
|
| 14 | * distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 | * See the License for the specific language governing permissions and
|
| 17 | * limitations under the License.
|
| 18 | * ============LICENSE_END=========================================================
|
| 19 | */
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 | package org.onap.osam.services;
|
| 24 |
|
| 25 | import com.google.common.collect.ImmutableMap;
|
| 26 | import org.apache.commons.collections.CollectionUtils;
|
| 27 | import org.apache.commons.lang3.StringUtils;
|
| 28 | import org.hibernate.SessionFactory;
|
| 29 | import org.onap.osam.aai.AaiClientInterface;
|
| 30 | import org.onap.osam.aai.AaiResponse;
|
| 31 | import org.onap.osam.aai.exceptions.InvalidAAIResponseException;
|
| 32 | import org.onap.osam.aai.model.AaiNodeQueryResponse;
|
| 33 | import org.onap.osam.aai.model.ResourceType;
|
| 34 | import org.onap.osam.domain.mso.CloudConfiguration;
|
| 35 | import org.onap.osam.exceptions.DbFailureUncheckedException;
|
| 36 | import org.onap.osam.exceptions.GenericUncheckedException;
|
| 37 | import org.onap.osam.exceptions.MaxRetriesException;
|
| 38 | import org.onap.osam.exceptions.OperationNotAllowedException;
|
| 39 | import org.onap.osam.job.Job;
|
| 40 | import org.onap.osam.job.Job.JobStatus;
|
| 41 | import org.onap.osam.job.JobAdapter;
|
| 42 | import org.onap.osam.job.JobType;
|
| 43 | import org.onap.osam.job.JobsBrokerService;
|
| 44 | import org.onap.osam.model.JobAuditStatus;
|
| 45 | import org.onap.osam.model.NameCounter;
|
| 46 | import org.onap.osam.model.ServiceInfo;
|
| 47 | import org.onap.osam.model.serviceInstantiation.ServiceInstantiation;
|
| 48 | import org.onap.osam.model.serviceInstantiation.VfModule;
|
| 49 | import org.onap.osam.model.serviceInstantiation.Vnf;
|
| 50 | import org.onap.osam.mso.MsoBusinessLogicImpl;
|
| 51 | import org.onap.osam.mso.MsoProperties;
|
| 52 | import org.onap.osam.mso.model.ServiceInstantiationRequestDetails;
|
| 53 | import org.onap.osam.mso.rest.AsyncRequestStatus;
|
| 54 | import org.onap.osam.utils.DaoUtils;
|
| 55 | import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
|
| 56 | import org.onap.portalsdk.core.service.DataAccessService;
|
| 57 | import org.springframework.beans.factory.annotation.Autowired;
|
| 58 | import org.springframework.stereotype.Service;
|
| 59 |
|
| 60 | import java.sql.Timestamp;
|
| 61 | import java.time.LocalDateTime;
|
| 62 | import java.util.*;
|
| 63 | import java.util.function.Consumer;
|
| 64 | import java.util.stream.Collectors;
|
| 65 |
|
| 66 | @Service
|
| 67 | public class AsyncInstantiationBusinessLogicImpl implements IAsyncInstantiationBusinessLogic {
|
| 68 |
|
| 69 | private static final int MAX_RETRIES_GETTING_COUNTER = 100;
|
| 70 | private static final int MAX_RETRIES_GETTING_FREE_NAME_FROM_AAI = 10000;
|
| 71 | public static final String NAME_FOR_CHECK_AAI_STATUS = "NAME_FOR_CHECK_AAI_STATUS";
|
| 72 |
|
| 73 | private final DataAccessService dataAccessService;
|
| 74 |
|
| 75 | private final JobAdapter jobAdapter;
|
| 76 |
|
| 77 | private final JobsBrokerService jobService;
|
| 78 |
|
| 79 | private SessionFactory sessionFactory;
|
| 80 |
|
| 81 | private AaiClientInterface aaiClient;
|
| 82 |
|
| 83 | private int maxRetriesGettingFreeNameFromAai = MAX_RETRIES_GETTING_FREE_NAME_FROM_AAI;
|
| 84 |
|
| 85 | private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AsyncInstantiationBusinessLogicImpl.class);
|
| 86 | private Map<String, JobStatus> msoStateToJobStatusMap = ImmutableMap.<String, JobStatus>builder()
|
| 87 | .put("inprogress", JobStatus.IN_PROGRESS)
|
| 88 | .put("failed", JobStatus.FAILED)
|
| 89 | .put("pause", JobStatus.PAUSE)
|
| 90 | .put("paused", JobStatus.PAUSE)
|
| 91 | .put("complete", JobStatus.COMPLETED)
|
| 92 | .put("pending", JobStatus.IN_PROGRESS)
|
| 93 | .put("pendingmanualtask", JobStatus.PAUSE)
|
| 94 | .put("unlocked", JobStatus.IN_PROGRESS)
|
| 95 | .build();
|
| 96 |
|
| 97 |
|
| 98 | @Autowired
|
| 99 | public AsyncInstantiationBusinessLogicImpl(DataAccessService dataAccessService,
|
| 100 | JobAdapter jobAdapter,
|
| 101 | JobsBrokerService jobService,
|
| 102 | SessionFactory sessionFactory,
|
| 103 | AaiClientInterface aaiClient) {
|
| 104 | this.dataAccessService = dataAccessService;
|
| 105 | this.jobAdapter = jobAdapter;
|
| 106 | this.jobService = jobService;
|
| 107 | this.sessionFactory = sessionFactory;
|
| 108 | this.aaiClient = aaiClient;
|
| 109 | }
|
| 110 |
|
| 111 | @Override
|
| 112 | public List<ServiceInfo> getAllServicesInfo() {
|
| 113 | return dataAccessService.getList(ServiceInfo.class, filterByCreationDateAndNotDeleted(), orderByCreatedDateAndStatus(), null);
|
| 114 | }
|
| 115 |
|
| 116 | private String filterByCreationDateAndNotDeleted() {
|
| 117 | LocalDateTime minus3Months = LocalDateTime.now().minusMonths(3);
|
| 118 | Timestamp filterDate = Timestamp.valueOf(minus3Months);
|
| 119 | return " where" +
|
| 120 | " hidden = false" +
|
| 121 | " and deleted_at is null" + // don't fetch deleted
|
| 122 | " and created >= '" + filterDate + "' ";
|
| 123 | }
|
| 124 |
|
| 125 | private String orderByCreatedDateAndStatus() {
|
| 126 | return " createdBulkDate DESC ,\n" +
|
| 127 | " (CASE jobStatus\n" +
|
| 128 | " WHEN 'COMPLETED' THEN 0\n" +
|
| 129 | " WHEN 'FAILED' THEN 0\n" +
|
| 130 | " WHEN 'IN_PROGRESS' THEN 1\n" +
|
| 131 | " WHEN 'PAUSE' THEN 2\n" +
|
| 132 | " WHEN 'PENDING' THEN 3\n" +
|
| 133 | " WHEN 'STOPPED' THEN 3 END),\n" +
|
| 134 | " statusModifiedDate ";
|
| 135 | }
|
| 136 |
|
| 137 | @Override
|
| 138 | public List<UUID> pushBulkJob(ServiceInstantiation request, String userId) {
|
| 139 | List<UUID> uuids = new ArrayList<>();
|
| 140 | Date createdBulkDate = Calendar.getInstance().getTime();
|
| 141 | int bulkSize = request.getBulkSize();
|
| 142 | UUID templateId = UUID.randomUUID();
|
| 143 | for (int i = 0; i < bulkSize; i++) {
|
| 144 | //Job job = jobAdapter.createJob(JobType.ServiceInstantiation, request, templateId, userId, i);
|
| 145 | Job job = jobAdapter.createJob(JobType.NoOp, request, templateId, userId, i);//should be some instatiation, this was changed as part of code cleaning
|
| 146 |
|
| 147 | UUID jobId = jobService.add(job);
|
| 148 | auditVidStatus(jobId,job.getStatus());
|
| 149 | uuids.add(jobId);
|
| 150 | dataAccessService.saveDomainObject(createServiceInfo(userId, request, jobId, templateId, createdBulkDate), DaoUtils.getPropsMap());
|
| 151 | }
|
| 152 | return uuids;
|
| 153 | }
|
| 154 |
|
| 155 | private ServiceInfo createServiceInfo(String userId, ServiceInstantiation serviceInstantiation, UUID jobId, UUID templateId, Date createdBulkDate) {
|
| 156 | return new ServiceInfo(
|
| 157 | userId, Job.JobStatus.PENDING, serviceInstantiation.isPause(), jobId, templateId,
|
| 158 | serviceInstantiation.getOwningEntityId(),
|
| 159 | serviceInstantiation.getOwningEntityName(),
|
| 160 | serviceInstantiation.getProjectName(),
|
| 161 | serviceInstantiation.getAicZoneId(),
|
| 162 | serviceInstantiation.getAicZoneName(),
|
| 163 | serviceInstantiation.getTenantId(),
|
| 164 | serviceInstantiation.getTenantName(),
|
| 165 | serviceInstantiation.getLcpCloudRegionId(),
|
| 166 | null,
|
| 167 | serviceInstantiation.getSubscriptionServiceType(),
|
| 168 | serviceInstantiation.getSubscriberName(),
|
| 169 | null,
|
| 170 | serviceInstantiation.getInstanceName(),
|
| 171 | serviceInstantiation.getModelInfo().getModelInvariantId(),
|
| 172 | serviceInstantiation.getModelInfo().getModelName(),
|
| 173 | serviceInstantiation.getModelInfo().getModelVersion(),
|
| 174 | createdBulkDate
|
| 175 | );
|
| 176 | }
|
| 177 |
|
| 178 |
|
| 179 | /*//@Override
|
| 180 | public RequestDetailsWrapper<ServiceInstantiationRequestDetails> generateServiceInstantiationRequest(UUID jobId, ServiceInstantiation payload, String userId) {
|
| 181 |
|
| 182 | ServiceInstantiationRequestDetails.ServiceInstantiationOwningEntity owningEntity = new ServiceInstantiationRequestDetails.ServiceInstantiationOwningEntity(payload.getOwningEntityId(), payload.getOwningEntityName());
|
| 183 |
|
| 184 | SubscriberInfo subscriberInfo = new SubscriberInfo();
|
| 185 | subscriberInfo.setGlobalSubscriberId(payload.getGlobalSubscriberId());
|
| 186 |
|
| 187 | String serviceInstanceName = null;
|
| 188 | if(payload.isUserProvidedNaming()) {
|
| 189 | serviceInstanceName = getUniqueName(payload.getInstanceName(), ResourceType.SERVICE_INSTANCE);
|
| 190 | String finalServiceInstanceName = serviceInstanceName;
|
| 191 | updateServiceInfo(jobId, x -> x.setServiceInstanceName(finalServiceInstanceName));
|
| 192 | }
|
| 193 | ServiceInstantiationRequestDetails.RequestInfo requestInfo = new ServiceInstantiationRequestDetails.RequestInfo(
|
| 194 | serviceInstanceName,
|
| 195 | payload.getProductFamilyId(),
|
| 196 | "VID",
|
| 197 | payload.isRollbackOnFailure(),
|
| 198 | userId);
|
| 199 |
|
| 200 | List<ServiceInstantiationRequestDetails.ServiceInstantiationService> serviceInstantiationService = new LinkedList<>();
|
| 201 | List<Map<String, String>> unFilteredInstanceParams = payload.getInstanceParams() != null ? payload.getInstanceParams() : new LinkedList<>();
|
| 202 | List<Map<String, String>> filteredInstanceParams = removeUnNeededParams(unFilteredInstanceParams);
|
| 203 | ServiceInstantiationRequestDetails.ServiceInstantiationService serviceInstantiationService1 = new ServiceInstantiationRequestDetails.ServiceInstantiationService(
|
| 204 | payload.getModelInfo(),
|
| 205 | serviceInstanceName,
|
| 206 | filteredInstanceParams,
|
| 207 | createServiceInstantiationVnfList(payload)
|
| 208 | );
|
| 209 | serviceInstantiationService.add(serviceInstantiationService1);
|
| 210 |
|
| 211 | ServiceInstantiationRequestDetails.RequestParameters requestParameters = new ServiceInstantiationRequestDetails.RequestParameters(payload.getSubscriptionServiceType(), false, serviceInstantiationService);
|
| 212 |
|
| 213 | ServiceInstantiationRequestDetails.Project project = payload.getProjectName() != null ? new ServiceInstantiationRequestDetails.Project(payload.getProjectName()) : null;
|
| 214 |
|
| 215 | ServiceInstantiationRequestDetails requestDetails = new ServiceInstantiationRequestDetails(payload.getModelInfo(), owningEntity, subscriberInfo,
|
| 216 | project, requestInfo, requestParameters);
|
| 217 |
|
| 218 | RequestDetailsWrapper<ServiceInstantiationRequestDetails> requestDetailsWrapper = new RequestDetailsWrapper(requestDetails);
|
| 219 | debugRequestDetails(requestDetailsWrapper, logger);
|
| 220 | return requestDetailsWrapper;
|
| 221 | }*/
|
| 222 |
|
| 223 | private List<Map<String, String>> removeUnNeededParams(List<Map<String, String>> instanceParams) {
|
| 224 | List<String> keysToRemove = new ArrayList<>();
|
| 225 | if (instanceParams != null && !instanceParams.isEmpty()) {
|
| 226 | for (String key : instanceParams.get(0).keySet()) {
|
| 227 | for (String paramToIgnore : PARAMS_TO_IGNORE)
|
| 228 | if ((key.equalsIgnoreCase(paramToIgnore))) {
|
| 229 | keysToRemove.add(key);
|
| 230 | }
|
| 231 | }
|
| 232 | for (String key : keysToRemove) {
|
| 233 | instanceParams.get(0).remove(key);
|
| 234 | }
|
| 235 | //TODO will be removed on once we stop using List<Map<String, String>>
|
| 236 | if (instanceParams.get(0).isEmpty()) {
|
| 237 | return Collections.emptyList();
|
| 238 | }
|
| 239 | }
|
| 240 | return instanceParams;
|
| 241 | }
|
| 242 |
|
| 243 | private ServiceInstantiationRequestDetails.ServiceInstantiationVnfList createServiceInstantiationVnfList(ServiceInstantiation payload) {
|
| 244 | CloudConfiguration cloudConfiguration = new CloudConfiguration();
|
| 245 | cloudConfiguration.setTenantId(payload.getTenantId());
|
| 246 | cloudConfiguration.setLcpCloudRegionId(payload.getLcpCloudRegionId());
|
| 247 |
|
| 248 | Map<String, Vnf> vnfs = payload.getVnfs();
|
| 249 | List<ServiceInstantiationRequestDetails.ServiceInstantiationVnf> vnfList = new ArrayList<>();
|
| 250 | for (Vnf vnf : vnfs.values()) {
|
| 251 | Map<String, Map<String, VfModule>> vfModules = vnf.getVfModules();
|
| 252 | List<VfModule> convertedUnFilteredVfModules = convertVfModuleMapToList(vfModules);
|
| 253 | List<VfModule> filteredVfModules = filterInstanceParamsFromVfModuleAndUniqueNames(convertedUnFilteredVfModules, vnf.isUserProvidedNaming());
|
| 254 | ServiceInstantiationRequestDetails.ServiceInstantiationVnf serviceInstantiationVnf = new ServiceInstantiationRequestDetails.ServiceInstantiationVnf(
|
| 255 | vnf.getModelInfo(),
|
| 256 | cloudConfiguration,
|
| 257 | vnf.getPlatformName(),
|
| 258 | vnf.getLineOfBusiness(),
|
| 259 | payload.getProductFamilyId(),
|
| 260 | removeUnNeededParams(vnf.getInstanceParams()),
|
| 261 | filteredVfModules,
|
| 262 | vnf.isUserProvidedNaming() ? getUniqueName(vnf.getInstanceName(), ResourceType.GENERIC_VNF) : null
|
| 263 | );
|
| 264 | vnfList.add(serviceInstantiationVnf);
|
| 265 | }
|
| 266 |
|
| 267 | return new ServiceInstantiationRequestDetails.ServiceInstantiationVnfList(vnfList);
|
| 268 | }
|
| 269 |
|
| 270 | private List<VfModule> convertVfModuleMapToList(Map<String, Map<String, VfModule>> vfModules) {
|
| 271 | return vfModules.values().stream().flatMap(vfModule -> vfModule.values().stream()).collect(Collectors.toList());
|
| 272 | }
|
| 273 |
|
| 274 | private List<VfModule> filterInstanceParamsFromVfModuleAndUniqueNames(List<VfModule> unFilteredVfModules, boolean isUserProvidedNaming) {
|
| 275 | return unFilteredVfModules.stream().map(vfModule ->
|
| 276 | new VfModule(
|
| 277 | vfModule.getModelInfo(),
|
| 278 | getUniqueNameIfNeeded(isUserProvidedNaming, vfModule.getInstanceName(), ResourceType.VF_MODULE),
|
| 279 | getUniqueNameIfNeeded(isUserProvidedNaming, vfModule.getVolumeGroupInstanceName(), ResourceType.VOLUME_GROUP),
|
| 280 | removeUnNeededParams(vfModule.getInstanceParams())))
|
| 281 | .collect(Collectors.toList());
|
| 282 | }
|
| 283 |
|
| 284 | private String getUniqueNameIfNeeded(boolean isUserProvidedNaming, String name, ResourceType resourceType) {
|
| 285 | return isUserProvidedNaming && !StringUtils.isEmpty(name) ?
|
| 286 | getUniqueName(name, resourceType) : null;
|
| 287 | }
|
| 288 |
|
| 289 | @Override
|
| 290 | public String getServiceInstantiationPath(ServiceInstantiation serviceInstantiationRequest) {
|
| 291 | //in case pause flag is true - use assign , else - use create.
|
| 292 | return MsoBusinessLogicImpl.validateEndpointPath(
|
| 293 | serviceInstantiationRequest.isPause() ?
|
| 294 | "mso.restapi.serviceInstanceAssign" : "mso.restapi.serviceInstanceCreate"
|
| 295 | );
|
| 296 | }
|
| 297 |
|
| 298 | @Override
|
| 299 | public String getOrchestrationRequestsPath() {
|
| 300 | return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_GET_ORC_REQ);
|
| 301 | }
|
| 302 |
|
| 303 | @Override
|
| 304 | public ServiceInfo updateServiceInfo(UUID jobUUID, Consumer<ServiceInfo> serviceUpdater) {
|
| 305 | ServiceInfo serviceInfo = getServiceInfoByJobId(jobUUID);
|
| 306 | serviceUpdater.accept(serviceInfo);
|
| 307 | dataAccessService.saveDomainObject(serviceInfo, DaoUtils.getPropsMap());
|
| 308 | return serviceInfo;
|
| 309 | }
|
| 310 |
|
| 311 | @Override
|
| 312 | public ServiceInfo updateServiceInfoAndAuditStatus(UUID jobUuid, JobStatus jobStatus) {
|
| 313 | auditVidStatus(jobUuid,jobStatus);
|
| 314 | return updateServiceInfo(jobUuid, x -> setServiceInfoStatus(x, jobStatus));
|
| 315 | }
|
| 316 |
|
| 317 | private void setServiceInfoStatus(ServiceInfo serviceInfo, JobStatus jobStatus) {
|
| 318 | serviceInfo.setJobStatus(jobStatus);
|
| 319 | serviceInfo.setStatusModifiedDate(new Date());
|
| 320 | }
|
| 321 |
|
| 322 | public ServiceInfo getServiceInfoByJobId(UUID jobUUID) {
|
| 323 | List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, String.format(" where jobId = '%s' ", jobUUID), null, null);
|
| 324 | if (serviceInfoList.size() != 1) {
|
| 325 | throw new GenericUncheckedException("Failed to retrieve job with uuid " + jobUUID + " from ServiceInfo table. Instances found: " + serviceInfoList.size());
|
| 326 | }
|
| 327 | return serviceInfoList.get(0);
|
| 328 | }
|
| 329 |
|
| 330 | public List<JobAuditStatus> getAuditStatuses(UUID jobUUID, JobAuditStatus.SourceStatus source) {
|
| 331 | return dataAccessService.getList(
|
| 332 | JobAuditStatus.class,
|
| 333 | String.format(" where SOURCE = '%s' and JOB_ID = '%s'",source, jobUUID),
|
| 334 | " CREATED_DATE ", null);
|
| 335 | }
|
| 336 |
|
| 337 | private JobAuditStatus getLatestAuditStatus(UUID jobUUID, JobAuditStatus.SourceStatus source){
|
| 338 | List<JobAuditStatus> list = getAuditStatuses(jobUUID,source);
|
| 339 | return !list.isEmpty() ? list.get(list.size()-1) : null;
|
| 340 | }
|
| 341 |
|
| 342 | @Override
|
| 343 | public void auditVidStatus(UUID jobUUID, JobStatus jobStatus){
|
| 344 | JobAuditStatus vidStatus = new JobAuditStatus(jobUUID, jobStatus.toString(), JobAuditStatus.SourceStatus.VID);
|
| 345 | auditStatus(vidStatus);
|
| 346 | }
|
| 347 |
|
| 348 | @Override
|
| 349 | public void auditMsoStatus(UUID jobUUID, AsyncRequestStatus.Request msoRequestStatus){
|
| 350 | auditMsoStatus(jobUUID, msoRequestStatus.requestStatus.getRequestState(), msoRequestStatus.requestId, msoRequestStatus.requestStatus.getStatusMessage());
|
| 351 | }
|
| 352 |
|
| 353 | @Override
|
| 354 | public void auditMsoStatus(UUID jobUUID, String jobStatus, String requestId, String additionalInfo){
|
| 355 | JobAuditStatus msoStatus = new JobAuditStatus(jobUUID, jobStatus, JobAuditStatus.SourceStatus.MSO,
|
| 356 | requestId != null ? UUID.fromString(requestId) : null,
|
| 357 | additionalInfo);
|
| 358 | auditStatus(msoStatus);
|
| 359 | }
|
| 360 |
|
| 361 | private void auditStatus(JobAuditStatus jobAuditStatus){
|
| 362 | JobAuditStatus latestStatus = getLatestAuditStatus(jobAuditStatus.getJobId(),jobAuditStatus.getSource());
|
| 363 | if (latestStatus == null || !latestStatus.equals(jobAuditStatus))
|
| 364 | dataAccessService.saveDomainObject(jobAuditStatus, DaoUtils.getPropsMap());
|
| 365 |
|
| 366 | }
|
| 367 |
|
| 368 | public Job.JobStatus calcStatus(AsyncRequestStatus asyncRequestStatus) {
|
| 369 | String msoRequestState = asyncRequestStatus.request.requestStatus.getRequestState().toLowerCase().replaceAll("[^a-z]+", "");
|
| 370 | JobStatus jobStatus = msoStateToJobStatusMap.get(msoRequestState);
|
| 371 | return (jobStatus != null ? jobStatus : JobStatus.IN_PROGRESS);
|
| 372 | }
|
| 373 |
|
| 374 | @Override
|
| 375 | public void handleFailedInstantiation(UUID jobUUID) {
|
| 376 | ServiceInfo serviceInfo = updateServiceInfoAndAuditStatus(jobUUID, JobStatus.FAILED);
|
| 377 | List<ServiceInfo> serviceInfoList = dataAccessService.getList(
|
| 378 | ServiceInfo.class,
|
| 379 | String.format(" where templateId = '%s' and jobStatus = '%s'",
|
| 380 | serviceInfo.getTemplateId(),
|
| 381 | JobStatus.PENDING),
|
| 382 | null, null);
|
| 383 | serviceInfoList.forEach(si -> updateServiceInfoAndAuditStatus(si.getJobId(), JobStatus.STOPPED));
|
| 384 | }
|
| 385 |
|
| 386 | @Override
|
| 387 | public void deleteJob(UUID jobId) {
|
| 388 | jobService.delete(jobId);
|
| 389 | Date now = new Date();
|
| 390 | updateServiceInfo(jobId, x -> x.setDeletedAt(now));
|
| 391 | }
|
| 392 |
|
| 393 | @Override
|
| 394 | public void hideServiceInfo(UUID jobUUID) {
|
| 395 | ServiceInfo serviceInfo = getServiceInfoByJobId(jobUUID);
|
| 396 | if (!serviceInfo.getJobStatus().isFinal()) {
|
| 397 | String message = String.format( "jobId %s: Service status does not allow hide service, status = %s",
|
| 398 | serviceInfo.getJobId(),
|
| 399 | serviceInfo.getJobStatus());
|
| 400 | logger.error(EELFLoggerDelegate.errorLogger, message);
|
| 401 | throw new OperationNotAllowedException(message);
|
| 402 | }
|
| 403 | serviceInfo.setHidden(true);
|
| 404 | dataAccessService.saveDomainObject(serviceInfo, DaoUtils.getPropsMap());
|
| 405 | }
|
| 406 |
|
| 407 | @Override
|
| 408 | public int
|
| 409 |
|
| 410 |
|
| 411 | getCounterForName(String name) {
|
| 412 |
|
| 413 | String hqlSelectNC = "from NameCounter where name = :name";
|
| 414 | String hqlUpdateCounter = "update NameCounter set counter = :newCounter " +
|
| 415 | "where name= :name " +
|
| 416 | "and counter= :prevCounter";
|
| 417 |
|
| 418 | Integer counter = null;
|
| 419 | GenericUncheckedException lastException = null;
|
| 420 | for (int i = 0; i< MAX_RETRIES_GETTING_COUNTER && counter==null; i++) {
|
| 421 | try {
|
| 422 | counter = calcCounter(name, hqlSelectNC, hqlUpdateCounter);
|
| 423 | }
|
| 424 | catch (GenericUncheckedException exception) {
|
| 425 | lastException = exception; //do nothing, we will try again in the loop
|
| 426 | }
|
| 427 | }
|
| 428 |
|
| 429 | if (counter!=null) {
|
| 430 | return counter;
|
| 431 | }
|
| 432 |
|
| 433 | throw lastException!=null ? new DbFailureUncheckedException(lastException) :
|
| 434 | new DbFailureUncheckedException("Failed to get counter for "+name+" due to unknown error");
|
| 435 |
|
| 436 | }
|
| 437 |
|
| 438 | private Integer calcCounter(String name, String hqlSelectNC, String hqlUpdateCounter) {
|
| 439 | Integer counter;
|
| 440 | counter = DaoUtils.tryWithSessionAndTransaction(sessionFactory, session -> {
|
| 441 | NameCounter nameCounter = (NameCounter) session.createQuery(hqlSelectNC)
|
| 442 | .setText("name", name)
|
| 443 | .uniqueResult();
|
| 444 | if (nameCounter != null) {
|
| 445 | int updatedRows = session.createQuery(hqlUpdateCounter)
|
| 446 | .setText("name", nameCounter.getName())
|
| 447 | .setInteger("prevCounter", nameCounter.getCounter())
|
| 448 | .setInteger("newCounter", nameCounter.getCounter() + 1)
|
| 449 | .executeUpdate();
|
| 450 | if (updatedRows == 1) {
|
| 451 | return nameCounter.getCounter() + 1;
|
| 452 | }
|
| 453 | } else {
|
| 454 | Object nameAsId = session.save(new NameCounter(name));
|
| 455 | //if save success
|
| 456 | if (nameAsId != null) {
|
| 457 | return 1;
|
| 458 | }
|
| 459 | }
|
| 460 | //in case of failure return null, in order to continue the loop
|
| 461 | return null;
|
| 462 | });
|
| 463 | return counter;
|
| 464 | }
|
| 465 |
|
| 466 | @Override
|
| 467 | public int getMaxRetriesGettingFreeNameFromAai() {
|
| 468 | return maxRetriesGettingFreeNameFromAai;
|
| 469 | }
|
| 470 |
|
| 471 | @Override
|
| 472 | public void setMaxRetriesGettingFreeNameFromAai(int maxRetriesGettingFreeNameFromAai) {
|
| 473 | this.maxRetriesGettingFreeNameFromAai = maxRetriesGettingFreeNameFromAai;
|
| 474 | }
|
| 475 |
|
| 476 | @Override
|
| 477 | public String getUniqueName(String name, ResourceType resourceType) {
|
| 478 | //check that name aai response well before increasing counter from DB
|
| 479 | //Prevents unnecessary increasing of the counter while AAI doesn't response
|
| 480 | isNameFreeInAai(NAME_FOR_CHECK_AAI_STATUS, resourceType);
|
| 481 |
|
| 482 | for (int i=0; i<getMaxRetriesGettingFreeNameFromAai(); i++) {
|
| 483 | int counter = getCounterForName(name);
|
| 484 | String newName = formatNameAndCounter(name, counter);
|
| 485 | if (isNameFreeInAai(newName, resourceType)) {
|
| 486 | return newName;
|
| 487 | }
|
| 488 | }
|
| 489 |
|
| 490 | throw new MaxRetriesException("find unused name for "+name, getMaxRetriesGettingFreeNameFromAai());
|
| 491 | }
|
| 492 |
|
| 493 | //the method is protected so we can call it in the UT
|
| 494 | protected String formatNameAndCounter(String name, int counter) {
|
| 495 | return name + "_" + String.format("%03d", counter);
|
| 496 | }
|
| 497 |
|
| 498 | private boolean isNameFreeInAai(String name, ResourceType resourceType) throws InvalidAAIResponseException {
|
| 499 | AaiResponse<AaiNodeQueryResponse> aaiResponse = aaiClient.searchNodeTypeByName(name, resourceType);
|
| 500 | if (aaiResponse.getHttpCode() > 399 || aaiResponse.getT() == null) {
|
| 501 | throw new InvalidAAIResponseException(aaiResponse);
|
| 502 | }
|
| 503 | return CollectionUtils.isEmpty(aaiResponse.getT().resultData);
|
| 504 | }
|
| 505 |
|
| 506 | }
|