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