2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2020 Ericsson. All rights reserved.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
20 package org.onap.so.asdc.etsi.pkg.processor;
22 import java.io.ByteArrayInputStream;
23 import java.io.IOException;
24 import java.time.Instant;
25 import java.util.Optional;
26 import java.util.concurrent.TimeUnit;
27 import java.util.zip.ZipEntry;
28 import java.util.zip.ZipInputStream;
29 import org.onap.so.asdc.etsi.pkg.processor.exceptions.SOL004ResourcePackageFailureException;
30 import org.onap.so.asdc.etsi.pkg.processor.exceptions.SOL004ResourcePackageProcessingException;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import org.springframework.beans.factory.annotation.Autowired;
34 import org.springframework.beans.factory.annotation.Value;
35 import org.springframework.stereotype.Service;
36 import com.google.common.collect.ImmutableSet;
40 * @author Waqas Ikram (waqas.ikram@est.tech)
44 public class EtsiResourcePackageProcessor {
46 private final static Logger LOGGER = LoggerFactory.getLogger(EtsiResourcePackageProcessor.class);
47 private static final String ONBOARDED_PACKAGE_DIR_PATH = "Artifacts/Deployment/ONBOARDED_PACKAGE";
48 private final SdcResourceProvider sdcResourceProvider;
49 private final EtsiCatalogServiceProvider catalogServiceProvider;
50 private static final int SLEEP_TIME_IN_SECONDS = 5;
52 private static final ImmutableSet<JobStatus> JOB_FINISHED_STATES =
53 ImmutableSet.of(JobStatus.FINISHED, JobStatus.ERROR, JobStatus.TIMEOUT);
55 @Value("${etsi-catalog-manager.rest.timeoutInSeconds:300}")
56 private int timeOutInSeconds;
59 public EtsiResourcePackageProcessor(final SdcResourceProvider sdcResourceProvider,
60 final EtsiCatalogServiceProvider catalogServiceProvider) {
61 this.sdcResourceProvider = sdcResourceProvider;
62 this.catalogServiceProvider = catalogServiceProvider;
65 public void processPackageIfExists(final String vnfUuid) {
66 LOGGER.debug("Processing vnf with UUID: {} ", vnfUuid);
68 final Optional<byte[]> optional = sdcResourceProvider.getVnfResource(vnfUuid);
69 if (optional.isPresent()) {
70 final byte[] resourceContent = optional.get();
72 if (containsOnBoardedSol004Package(resourceContent)) {
73 final EtsiCatalogPackageOnboardingJob onboardingJob = catalogServiceProvider
74 .onBoardResource(new EtsiCatalogPackageOnboardingRequest().csarId(vnfUuid));
75 LOGGER.debug("Successfully created job with id: {} to onboard vnf with UUID: {}",
76 onboardingJob.getJobId(), vnfUuid);
78 if (onboardingJob.getJobId() == null) {
79 throw new SOL004ResourcePackageFailureException(
80 "Received invalid jobId " + onboardingJob.getJobId());
83 final Optional<EtsiCatalogPackageOnboadingJobStatus> jobStatusOptional =
84 waitForJobToFinish(onboardingJob);
86 if (!jobStatusOptional.isPresent()) {
87 final String message = "Job status timeout reached failed to onboard vnf with UUID: " + vnfUuid;
88 LOGGER.debug(message, vnfUuid);
89 throw new SOL004ResourcePackageFailureException(message);
92 final EtsiCatalogPackageOnboadingJobStatus onboadingJobStatus = jobStatusOptional.get();
93 final JobStatus jobStatus = getJobStatus(onboadingJobStatus);
94 final ErrorCode errorCode = getErrorCode(onboadingJobStatus);
96 LOGGER.debug("Final job status: {}, error code: {}", jobStatus, errorCode);
97 if (!JobStatus.FINISHED.equals(jobStatus) && !ErrorCode.PACKAGE_EXIST.equals(errorCode)) {
98 final String message = "Failed to onboard vnf with UUID: " + vnfUuid + " job status: "
99 + jobStatus + " errorCode: " + errorCode;
100 LOGGER.debug(message, vnfUuid);
101 throw new SOL004ResourcePackageFailureException(message);
103 LOGGER.debug("Successfully onboarded package in ETSI catalog .. ");
107 } catch (final Exception exception) {
108 final String message = "Unable to process resource received from SDC";
109 LOGGER.error(message, exception);
110 throw new SOL004ResourcePackageProcessingException(message, exception);
115 private Optional<EtsiCatalogPackageOnboadingJobStatus> waitForJobToFinish(
116 final EtsiCatalogPackageOnboardingJob onboardingJob) throws InterruptedException {
117 JobStatus currentJobStatus = null;
118 final long startTimeInMillis = System.currentTimeMillis();
119 final long timeOutTime = startTimeInMillis + TimeUnit.SECONDS.toMillis(timeOutInSeconds);
121 LOGGER.debug("Will wait till {} for {} job to finish", Instant.ofEpochMilli(timeOutTime).toString(),
122 onboardingJob.getJobId());
124 while (timeOutTime > System.currentTimeMillis()) {
126 final EtsiCatalogPackageOnboadingJobStatus onboadingJobStatus =
127 catalogServiceProvider.getJobStatus(onboardingJob.getJobId());
128 LOGGER.debug("Current job status {} ", onboadingJobStatus);
130 currentJobStatus = getJobStatus(onboadingJobStatus);
131 if (JOB_FINISHED_STATES.contains(currentJobStatus)) {
132 return Optional.of(onboadingJobStatus);
135 LOGGER.debug("Onboarding not finished yet, will try again in {} seconds", SLEEP_TIME_IN_SECONDS);
136 TimeUnit.SECONDS.sleep(SLEEP_TIME_IN_SECONDS);
139 LOGGER.warn("Timeout current job status: {}", currentJobStatus);
140 return Optional.empty();
143 private boolean containsOnBoardedSol004Package(final byte[] resourceContent) throws IOException {
144 try (final ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(resourceContent))) {
146 while ((entry = zipStream.getNextEntry()) != null) {
147 if (entry.getName() != null && entry.getName().contains(ONBOARDED_PACKAGE_DIR_PATH)) {
148 LOGGER.debug("Found entry: {} that contains {} in name", entry.getName(),
149 ONBOARDED_PACKAGE_DIR_PATH);
155 LOGGER.debug("Unable to find {} dir in downloaded package", ONBOARDED_PACKAGE_DIR_PATH);
159 private JobStatus getJobStatus(final EtsiCatalogPackageOnboadingJobStatus onboadingJobStatus) {
160 if (onboadingJobStatus.getResponseDescriptor() != null) {
161 return JobStatus.getJobStatus(onboadingJobStatus.getResponseDescriptor().getStatus());
163 LOGGER.warn("Found null ResponseDescriptor {}", onboadingJobStatus);
164 return JobStatus.UNKNOWN;
167 private ErrorCode getErrorCode(final EtsiCatalogPackageOnboadingJobStatus onboadingJobStatus) {
168 if (onboadingJobStatus.getResponseDescriptor() != null) {
169 return ErrorCode.getErrorCode(onboadingJobStatus.getResponseDescriptor().getErrorCode());
171 LOGGER.warn("Found null ResponseDescriptor {}", onboadingJobStatus);
172 return ErrorCode.UNKNOWN;