diff options
author | waqas.ikram <waqas.ikram@est.tech> | 2020-05-01 18:26:26 +0100 |
---|---|---|
committer | waqas.ikram <waqas.ikram@est.tech> | 2020-05-01 18:45:39 +0100 |
commit | 7ceffbb04dddbdf39e232340223c792d40d514f0 (patch) | |
tree | 294ba45db1dc5e96f09186855921dd2660b0fde0 /adapters/etsi-sol003-adapter/etsi-sol003-pkgm | |
parent | 7511bc24717091b316b70b95a827600567bc285e (diff) |
Refactor SOL003 Adapter to organize its modules
Change-Id: Iffa86178559a3bdd541e72c2d134e05dba2bd569
Issue-ID: SO-2771
Signed-off-by: waqas.ikram <waqas.ikram@est.tech>
Diffstat (limited to 'adapters/etsi-sol003-adapter/etsi-sol003-pkgm')
58 files changed, 18710 insertions, 0 deletions
diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/pom.xml b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/pom.xml new file mode 100644 index 0000000000..250ac504c7 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/pom.xml @@ -0,0 +1,109 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.so.adapters</groupId> + <artifactId>etsi-sol003-pkgm</artifactId> + <version>1.6.0-SNAPSHOT</version> + </parent> + <artifactId>etsi-sol003-pkgm-adapter</artifactId> + <name>ETSI SOL003 VNF Package Management Adapter</name> + + <build> + <plugins> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <systemPropertyVariables> + <so.log.level>DEBUG</so.log.level> + </systemPropertyVariables> + <rerunFailingTestsCount>2</rerunFailingTestsCount> + <parallel>suites</parallel> + <useUnlimitedThreads>false</useUnlimitedThreads> + <threadCount>1</threadCount> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + <exclusions> + <exclusion> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + <exclusions> + <exclusion> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-tomcat</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-actuator</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onap.so</groupId> + <artifactId>common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.so.adapters</groupId> + <artifactId>etsi-sol003-adapter-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.so.adapters</groupId> + <artifactId>etsi-sol003-pkgm-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.so.adapters</groupId> + <artifactId>etsi-sol003-pkgm-ext-clients</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-client</artifactId> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-common</artifactId> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.inject</groupId> + <artifactId>jersey-hk2</artifactId> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.media</groupId> + <artifactId>jersey-media-json-jackson</artifactId> + </dependency> + <dependency> + <groupId>org.yaml</groupId> + <artifactId>snakeyaml</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project>
\ No newline at end of file diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/ConversionServiceConfiguration.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/ConversionServiceConfiguration.java new file mode 100644 index 0000000000..fd19d0e0a1 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/ConversionServiceConfiguration.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm; + +import org.onap.so.adapters.etsi.sol003.adapter.common.VnfmAdapterUrlProvider; +import org.onap.so.adapters.etsisol003adapter.pkgm.converters.etsicatalog.sol003.PkgChangeNotificationConverter; +import org.onap.so.adapters.etsisol003adapter.pkgm.converters.etsicatalog.sol003.PkgOnboardingNotificationConverter; +import org.onap.so.adapters.etsisol003adapter.pkgm.converters.etsicatalog.sol003.VnfPkgInfoConverter; +import org.onap.so.adapters.etsisol003adapter.pkgm.converters.sol003.etsicatalog.PkgmSubscriptionRequestConverter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class ConversionServiceConfiguration { + + private final VnfmAdapterUrlProvider vnfmAdapterUrlProvider; + + @Autowired + public ConversionServiceConfiguration(final VnfmAdapterUrlProvider vnfmAdapterUrlProvider) { + this.vnfmAdapterUrlProvider = vnfmAdapterUrlProvider; + } + + @Bean + public ConversionService conversionService() { + final DefaultConversionService service = new DefaultConversionService(); + service.addConverter(new VnfPkgInfoConverter(vnfmAdapterUrlProvider)); + service.addConverter(new PkgmSubscriptionRequestConverter()); + service.addConverter(new PkgChangeNotificationConverter(vnfmAdapterUrlProvider)); + service.addConverter(new PkgOnboardingNotificationConverter(vnfmAdapterUrlProvider)); + return service; + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/PackageManagementConstants.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/PackageManagementConstants.java new file mode 100644 index 0000000000..5922aab9ca --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/PackageManagementConstants.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm; + +/** + * ETSI SOL003 VNF Package Management Adapter constants + * + * @author Ronan Kenny (ronan.kenny@est.tech) + * @author Gareth Roper (gareth.roper@est.tech) + */ +public class PackageManagementConstants { + + public static final String APPLICATION_ZIP = "application/zip"; + + /** + * Name of the subscription cache + */ + public static final String PACKAGE_MANAGEMENT_SUBSCRIPTION_CACHE = "PackageManagementSubscriptionCache"; + + private PackageManagementConstants() {} +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/AbstractCacheServiceProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/AbstractCacheServiceProvider.java new file mode 100644 index 0000000000..6dd67faa9e --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/AbstractCacheServiceProvider.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.cache; + +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; + +/** + * @author Ronan Kenny (ronan.kenny@est.tech) + * @author Gareth Roper (gareth.roper@est.tech) + */ +public abstract class AbstractCacheServiceProvider { + + private final CacheManager cacheManager; + private final String cacheName; + + public AbstractCacheServiceProvider(final String cacheName, final CacheManager cacheManager) { + this.cacheName = cacheName; + this.cacheManager = cacheManager; + } + + public Cache getCache() { + final Cache cache = cacheManager.getCache(cacheName); + if (cache == null) { + throw new CacheNotFoundException("Unable to find " + cacheName + " cache"); + } + return cache; + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/CacheManagerConfiguration.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/CacheManagerConfiguration.java new file mode 100644 index 0000000000..c184a25bef --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/CacheManagerConfiguration.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.cache; + +import java.util.Arrays; +import org.onap.so.adapters.etsisol003adapter.pkgm.PackageManagementConstants; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.concurrent.ConcurrentMapCache; +import org.springframework.cache.support.SimpleCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Ronan Kenny (ronan.kenny@est.tech) + * @author Gareth Roper (gareth.roper@est.tech) + */ +@Configuration +public class CacheManagerConfiguration { + + @Bean + public CacheManager cacheManager() { + final SimpleCacheManager manager = new SimpleCacheManager(); + manager.setCaches(Arrays.asList(getCache(PackageManagementConstants.PACKAGE_MANAGEMENT_SUBSCRIPTION_CACHE))); + + return manager; + } + + private Cache getCache(final String name) { + return new ConcurrentMapCache(name); + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/CacheNotFoundException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/CacheNotFoundException.java new file mode 100644 index 0000000000..6b2f4710da --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/CacheNotFoundException.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.cache; + +/** + * Exception for failure to find the cache. + * + * @author Ronan Kenny (ronan.kenny@est.tech) + * @author Gareth Roper (gareth.roper@est.tech) + * + */ +public class CacheNotFoundException extends RuntimeException { + + private static final long serialVersionUID = -372361485260755367L; + + public CacheNotFoundException(final String message) { + super(message); + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/PkgmCacheServiceProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/PkgmCacheServiceProvider.java new file mode 100644 index 0000000000..34ed1cfc0c --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/PkgmCacheServiceProvider.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.cache; + +import java.util.Map; +import java.util.Optional; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.PkgmSubscriptionRequest; + +/** + * Interface which provides methods for communicating with the cache + * + * @author Ronan Kenny (ronan.kenny@est.tech) + * @author Gareth Roper (gareth.roper@est.tech) + * + */ +public interface PkgmCacheServiceProvider { + + /** + * Checks cache if subscription request Id is already present. If not, it adds the subscription to the cache. + * + * @param subscriptionId + * @param pkgmSubscriptionRequest + */ + void addSubscription(final String subscriptionId, final PkgmSubscriptionRequest pkgmSubscriptionRequest); + + /** + * Gets individual subscription from cache + * + * @param subscriptionId + * @return <AbstractMap.SimpleImmutableEntry<String, PkgmSubscriptionRequest>> + */ + Optional<PkgmSubscriptionRequest> getSubscription(final String subscriptionId); + + /** + * Gets Map of subscriptions from cache + * + * @return Map<String, PkgmSubscriptionRequest>> + */ + Map<String, PkgmSubscriptionRequest> getSubscriptions(); + + /** + * Delete subscription from cache + * + * @param subscriptionId + * @return Boolean + */ + boolean deleteSubscription(final String subscriptionId); + + /** + * Checks if subscription exists in cache and return its subscriptionId + * + * @param pkgmSubscriptionRequest + * @return Subscription Id + */ + Optional<String> getSubscriptionId(final PkgmSubscriptionRequest pkgmSubscriptionRequest); +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/PkgmCacheServiceProviderImpl.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/PkgmCacheServiceProviderImpl.java new file mode 100644 index 0000000000..4811132e92 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/cache/PkgmCacheServiceProviderImpl.java @@ -0,0 +1,118 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.cache; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import org.onap.so.adapters.etsisol003adapter.pkgm.PackageManagementConstants; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.PkgmSubscriptionRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.stereotype.Service; + +/** + * Implementation which provides methods for communicating with the cache + * + * @author Ronan Kenny (ronan.kenny@est.tech) + * @author Gareth Roper (gareth.roper@est.tech) + */ +@Service +public class PkgmCacheServiceProviderImpl extends AbstractCacheServiceProvider implements PkgmCacheServiceProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(PkgmCacheServiceProviderImpl.class); + + @Autowired + public PkgmCacheServiceProviderImpl(final CacheManager cacheManager) { + super(PackageManagementConstants.PACKAGE_MANAGEMENT_SUBSCRIPTION_CACHE, cacheManager); + } + + @Override + public void addSubscription(final String subscriptionId, final PkgmSubscriptionRequest pkgmSubscriptionRequest) { + LOGGER.debug("Adding {} to cache with subscription id: {}", pkgmSubscriptionRequest, subscriptionId); + getCache().put(subscriptionId, pkgmSubscriptionRequest); + } + + @Override + public Optional<PkgmSubscriptionRequest> getSubscription(final String subscriptionId) { + LOGGER.debug("Getting subscription from cache using Id: {}", subscriptionId); + final Cache cache = getCache(); + final PkgmSubscriptionRequest cacheValue = cache.get(subscriptionId, PkgmSubscriptionRequest.class); + if (cacheValue != null) { + return Optional.of(cacheValue); + } + LOGGER.error("Unable to find Subscription in cache using Id: {}", subscriptionId); + return Optional.empty(); + } + + @Override + public Map<String, PkgmSubscriptionRequest> getSubscriptions() { + LOGGER.info("Getting all subscriptions from cache"); + final Cache cache = getCache(); + + final Object nativeCache = cache.getNativeCache(); + if (nativeCache instanceof ConcurrentHashMap) { + @SuppressWarnings("unchecked") + final ConcurrentHashMap<Object, Object> concurrentHashMap = (ConcurrentHashMap<Object, Object>) nativeCache; + final Map<String, PkgmSubscriptionRequest> result = new HashMap<>(); + concurrentHashMap.keySet().forEach(key -> { + final Optional<PkgmSubscriptionRequest> optional = getSubscription(key.toString()); + optional.ifPresent(pkgmSubscriptionRequest -> result.put(key.toString(), pkgmSubscriptionRequest)); + }); + return result; + } + LOGGER.error("Unable to find Subscriptions in cache"); + return Collections.emptyMap(); + } + + @Override + public boolean deleteSubscription(final String subscriptionId) { + final Cache cache = getCache(); + final Optional<PkgmSubscriptionRequest> optional = getSubscription(subscriptionId); + if (optional.isPresent()) { + cache.evict(subscriptionId); + return true; + } + return false; + } + + @Override + public Optional<String> getSubscriptionId(final PkgmSubscriptionRequest pkgmSubscriptionRequest) { + final Cache cache = getCache(); + final Object nativeCache = cache.getNativeCache(); + if (nativeCache instanceof ConcurrentHashMap) { + @SuppressWarnings("unchecked") + final ConcurrentHashMap<Object, Object> concurrentHashMap = (ConcurrentHashMap<Object, Object>) nativeCache; + final Optional<Entry<Object, Object>> optional = concurrentHashMap.entrySet().stream() + .filter(entry -> entry.getValue().equals(pkgmSubscriptionRequest)).findAny(); + if (optional.isPresent()) { + return Optional.of(optional.get().getKey().toString()); + } + } + return Optional.empty(); + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/AbstractPkgNotificationConverter.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/AbstractPkgNotificationConverter.java new file mode 100644 index 0000000000..5f2ee1d5ab --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/AbstractPkgNotificationConverter.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.converters.etsicatalog.sol003; + +import org.onap.so.adapters.etsi.sol003.adapter.common.VnfmAdapterUrlProvider; +import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgmLinks; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.model.URIisprovidedbytheclientwhencreatingthesubscriptionVnfPackageOnboardingNotificationLinks; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.model.URIisprovidedbytheclientwhencreatingthesubscriptionVnfPackageOnboardingNotificationLinksVnfPackage; + +/** + * A base class that can be extended by classes for converting Etsi Catalog Manager Pkg Notification classes. Provides + * common methods that will be useful to those classes. + * + * @author andrew.a.lamb@est.tech + */ +abstract public class AbstractPkgNotificationConverter { + + private final VnfmAdapterUrlProvider vnfmAdapterUrlProvider; + + public AbstractPkgNotificationConverter(final VnfmAdapterUrlProvider vnfmAdapterUrlProvider) { + this.vnfmAdapterUrlProvider = vnfmAdapterUrlProvider; + } + + protected URIisprovidedbytheclientwhencreatingthesubscriptionVnfPackageOnboardingNotificationLinks convert( + final PkgmLinks pkgmLinks, final String vnfPkgId, final String subscriptionId) { + final URIisprovidedbytheclientwhencreatingthesubscriptionVnfPackageOnboardingNotificationLinksVnfPackage linksVnfPackage = + new URIisprovidedbytheclientwhencreatingthesubscriptionVnfPackageOnboardingNotificationLinksVnfPackage(); + if (pkgmLinks.getVnfPackage() != null) { + linksVnfPackage.setHref(vnfmAdapterUrlProvider.getVnfPackageUrl(vnfPkgId)); + } + + final URIisprovidedbytheclientwhencreatingthesubscriptionVnfPackageOnboardingNotificationLinksVnfPackage linksSubscription = + new URIisprovidedbytheclientwhencreatingthesubscriptionVnfPackageOnboardingNotificationLinksVnfPackage(); + if (pkgmLinks.getSubscription() != null) { + linksSubscription.setHref(vnfmAdapterUrlProvider.getSubscriptionUriString(subscriptionId)); + } + + final URIisprovidedbytheclientwhencreatingthesubscriptionVnfPackageOnboardingNotificationLinks links = + new URIisprovidedbytheclientwhencreatingthesubscriptionVnfPackageOnboardingNotificationLinks(); + links.setVnfPackage(linksVnfPackage); + links.setSubscription(linksSubscription); + return links; + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/PkgChangeNotificationConverter.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/PkgChangeNotificationConverter.java new file mode 100644 index 0000000000..5787d35b9a --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/PkgChangeNotificationConverter.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.converters.etsicatalog.sol003; + +import static org.slf4j.LoggerFactory.getLogger; +import org.onap.so.adapters.etsi.sol003.adapter.common.VnfmAdapterUrlProvider; +import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgChangeNotification; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.model.VnfPackageChangeNotification; +import org.slf4j.Logger; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Service; + +/** + * Converter to convert from an Etsi Catalog Manager {@link PkgChangeNotification} Object to its equivalent SOL003 + * {@link VnfPackageChangeNotification} Object + * + * @author andrew.a.lamb@est.tech + */ +@Service +public class PkgChangeNotificationConverter extends AbstractPkgNotificationConverter + implements Converter<PkgChangeNotification, VnfPackageChangeNotification> { + private static final Logger logger = getLogger(PkgChangeNotificationConverter.class); + + public PkgChangeNotificationConverter(final VnfmAdapterUrlProvider vnfmAdapterUrlProvider) { + super(vnfmAdapterUrlProvider); + } + + /** + * Convert a {@link PkgChangeNotification} Object to an {@link VnfPackageChangeNotification} Object + * + * @param pkgChangeNotification The PkgChangeNotification Object to Convert + * @return The Converted VnfPackageChangeNotification Object + */ + @Override + public VnfPackageChangeNotification convert(final PkgChangeNotification pkgChangeNotification) { + logger.info("Converting PkgChangeNotification\n{}", pkgChangeNotification.toString()); + final VnfPackageChangeNotification vnfPackageChangeNotification = new VnfPackageChangeNotification(); + vnfPackageChangeNotification.setId(pkgChangeNotification.getId()); + + if (pkgChangeNotification.getNotificationType() != null) { + vnfPackageChangeNotification.setNotificationType(VnfPackageChangeNotification.NotificationTypeEnum + .fromValue(pkgChangeNotification.getNotificationType().getValue())); + } + + vnfPackageChangeNotification.setSubscriptionId(pkgChangeNotification.getSubscriptionId()); + vnfPackageChangeNotification.setTimeStamp(pkgChangeNotification.getTimeStamp()); + vnfPackageChangeNotification.setVnfPkgId(pkgChangeNotification.getVnfPkgId()); + + vnfPackageChangeNotification.setVnfdId(pkgChangeNotification.getVnfdId()); + + if (pkgChangeNotification.getChangeType() != null) { + vnfPackageChangeNotification.setChangeType(VnfPackageChangeNotification.ChangeTypeEnum + .fromValue(pkgChangeNotification.getChangeType().getValue())); + } + + if (pkgChangeNotification.getOperationalState() != null) { + vnfPackageChangeNotification.setOperationalState(VnfPackageChangeNotification.OperationalStateEnum + .fromValue(pkgChangeNotification.getOperationalState().getValue())); + } + + vnfPackageChangeNotification.setLinks(convert(pkgChangeNotification.getLinks(), + pkgChangeNotification.getVnfPkgId(), pkgChangeNotification.getSubscriptionId())); + + return vnfPackageChangeNotification; + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/PkgOnboardingNotificationConverter.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/PkgOnboardingNotificationConverter.java new file mode 100644 index 0000000000..96a5d827e6 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/PkgOnboardingNotificationConverter.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.converters.etsicatalog.sol003; + +import static org.slf4j.LoggerFactory.getLogger; +import org.onap.so.adapters.etsi.sol003.adapter.common.VnfmAdapterUrlProvider; +import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgOnboardingNotification; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.model.VnfPackageOnboardingNotification; +import org.slf4j.Logger; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Service; + +/** + * Converter to convert from an Etsi Catalog Manager {@link PkgOnboardingNotification} Object to its equivalent SOL003 + * {@link VnfPackageOnboardingNotification} Object + * + * @author andrew.a.lamb@est.tech + */ +@Service +public class PkgOnboardingNotificationConverter extends AbstractPkgNotificationConverter + implements Converter<PkgOnboardingNotification, VnfPackageOnboardingNotification> { + private static final Logger logger = getLogger(PkgOnboardingNotificationConverter.class); + + public PkgOnboardingNotificationConverter(final VnfmAdapterUrlProvider vnfmAdapterUrlProvider) { + super(vnfmAdapterUrlProvider); + } + + + /** + * Convert a {@link PkgOnboardingNotification} Object to an {@link VnfPackageOnboardingNotification} Object + * + * @param pkgOnboardingNotification The PkgOnboardingNotification Object to Convert + * @return The Converted VnfPackageOnboardingNotification Object + */ + @Override + public VnfPackageOnboardingNotification convert(final PkgOnboardingNotification pkgOnboardingNotification) { + logger.info("Converting PkgChangeNotification\n{}", pkgOnboardingNotification.toString()); + final VnfPackageOnboardingNotification vnfPackageOnboardingNotification = + new VnfPackageOnboardingNotification(); + vnfPackageOnboardingNotification.setId(pkgOnboardingNotification.getId()); + + if (pkgOnboardingNotification.getNotificationType() != null) { + vnfPackageOnboardingNotification.setNotificationType(VnfPackageOnboardingNotification.NotificationTypeEnum + .fromValue(pkgOnboardingNotification.getNotificationType().getValue())); + } + + vnfPackageOnboardingNotification.setSubscriptionId(pkgOnboardingNotification.getSubscriptionId()); + vnfPackageOnboardingNotification.setTimeStamp(pkgOnboardingNotification.getTimeStamp()); + vnfPackageOnboardingNotification.setVnfPkgId(pkgOnboardingNotification.getVnfPkgId()); + vnfPackageOnboardingNotification.setVnfdId(pkgOnboardingNotification.getVnfdId()); + + vnfPackageOnboardingNotification.setLinks(convert(pkgOnboardingNotification.getLinks(), + pkgOnboardingNotification.getVnfPkgId(), pkgOnboardingNotification.getSubscriptionId())); + + return vnfPackageOnboardingNotification; + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/VnfPkgInfoConverter.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/VnfPkgInfoConverter.java new file mode 100644 index 0000000000..0121cc5885 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/etsicatalog/sol003/VnfPkgInfoConverter.java @@ -0,0 +1,198 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.converters.etsicatalog.sol003; + +import java.util.ArrayList; +import java.util.List; +import org.onap.so.adapters.etsi.sol003.adapter.common.VnfmAdapterUrlProvider; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.Checksum; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VNFPKGMLinkSerializer; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPackageArtifactInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPackageSoftwareImageInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.InlineResponse2001; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.VnfPackagesAdditionalArtifacts; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.VnfPackagesChecksum; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.VnfPackagesLinks; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.VnfPackagesLinksSelf; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.VnfPackagesSoftwareImages; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Service; + +/** + * Converter to convert from an Etsi Catalog Manager {@link VnfPkgInfo} Object to its equivalent SOL003 Object + * {@link InlineResponse2001} Object + * + * @author andrew.a.lamb@est.tech + */ +@Service +public class VnfPkgInfoConverter implements Converter<VnfPkgInfo, InlineResponse2001> { + private static final Logger logger = LoggerFactory.getLogger(VnfPkgInfoConverter.class); + private final VnfmAdapterUrlProvider vnfmAdapterUrlProvider; + + public VnfPkgInfoConverter(final VnfmAdapterUrlProvider vnfmAdapterUrlProvider) { + this.vnfmAdapterUrlProvider = vnfmAdapterUrlProvider; + } + + /** + * Convert a {@link VnfPkgInfo} Object to an {@link InlineResponse2001} Object + * + * @param vnfPkgInfo The VnfPkgInfo Object to Convert + * @return The Converted InlineResponse2001 Object + */ + @Override + public InlineResponse2001 convert(final VnfPkgInfo vnfPkgInfo) { + if (vnfPkgInfo == null) { + logger.error("No VnfPkgInfo Object Provided for Conversion. (Null object received, returning Null)"); + return null; + } + final InlineResponse2001 response = new InlineResponse2001(); + response.setId(vnfPkgInfo.getId()); + response.setVnfdId(vnfPkgInfo.getVnfdId()); + response.setVnfProvider(vnfPkgInfo.getVnfProvider()); + response.setVnfProductName(vnfPkgInfo.getVnfProductName()); + response.setVnfSoftwareVersion(vnfPkgInfo.getVnfSoftwareVersion()); + response.setVnfdVersion(vnfPkgInfo.getVnfdVersion()); + response.setChecksum(convertChecksumToVnfPackagesChecksum(vnfPkgInfo.getChecksum())); + response.setSoftwareImages( + convertVnfPackageSoftwareImageInfoListToVnfPackagesSoftwareImagesList(vnfPkgInfo.getSoftwareImages())); + response.setAdditionalArtifacts(convertVnfPackageArtifactInfoListToVnfPackagesAdditionalArtifactsList( + vnfPkgInfo.getAdditionalArtifacts())); + + if (vnfPkgInfo.getOnboardingState() != null) { + response.setOnboardingState( + InlineResponse2001.OnboardingStateEnum.fromValue(vnfPkgInfo.getOnboardingState().getValue())); + } + + if (vnfPkgInfo.getOperationalState() != null) { + response.setOperationalState( + InlineResponse2001.OperationalStateEnum.fromValue(vnfPkgInfo.getOperationalState().getValue())); + } + + response.setUserDefinedData((vnfPkgInfo.getUserDefinedData())); + + if (vnfPkgInfo.getLinks() != null) { + response.setLinks(getVnfPackagesLinks(vnfPkgInfo.getLinks(), vnfPkgInfo.getId())); + } + + return response; + } + + private VnfPackagesChecksum convertChecksumToVnfPackagesChecksum(final Checksum checksum) { + final VnfPackagesChecksum vnfPackagesChecksum = new VnfPackagesChecksum(); + if (checksum != null) { + vnfPackagesChecksum.setAlgorithm(checksum.getAlgorithm()); + vnfPackagesChecksum.setHash(checksum.getHash()); + } + return vnfPackagesChecksum; + } + + private List<VnfPackagesSoftwareImages> convertVnfPackageSoftwareImageInfoListToVnfPackagesSoftwareImagesList( + final List<VnfPackageSoftwareImageInfo> vnfPackageSoftwareImageInfoList) { + final List<VnfPackagesSoftwareImages> vnfPackagesSoftwareImages = new ArrayList<>(); + if (vnfPackageSoftwareImageInfoList != null) { + for (final VnfPackageSoftwareImageInfo vnfPackageSoftwareImageInfo : vnfPackageSoftwareImageInfoList) { + final VnfPackagesSoftwareImages softwareImage = + convertVnfPackageSoftwareImageInfoToVnfPackagesSoftwareImages(vnfPackageSoftwareImageInfo); + vnfPackagesSoftwareImages.add(softwareImage); + } + } + return vnfPackagesSoftwareImages; + } + + private VnfPackagesSoftwareImages convertVnfPackageSoftwareImageInfoToVnfPackagesSoftwareImages( + final VnfPackageSoftwareImageInfo vnfPackageSoftwareImageInfo) { + final VnfPackagesSoftwareImages vnfPackagesSoftwareImages = new VnfPackagesSoftwareImages(); + vnfPackagesSoftwareImages.setId(vnfPackageSoftwareImageInfo.getId()); + vnfPackagesSoftwareImages.setName(vnfPackageSoftwareImageInfo.getName()); + vnfPackagesSoftwareImages.setProvider(vnfPackageSoftwareImageInfo.getProvider()); + vnfPackagesSoftwareImages.setVersion(vnfPackageSoftwareImageInfo.getVersion()); + vnfPackagesSoftwareImages + .setChecksum(convertChecksumToVnfPackagesChecksum(vnfPackageSoftwareImageInfo.getChecksum())); + if (vnfPackageSoftwareImageInfo.getContainerFormat() != null) { + vnfPackagesSoftwareImages.setContainerFormat(VnfPackagesSoftwareImages.ContainerFormatEnum + .fromValue(vnfPackageSoftwareImageInfo.getContainerFormat().getValue())); + } + + if (vnfPackageSoftwareImageInfo.getDiskFormat() != null) { + vnfPackagesSoftwareImages.setDiskFormat(VnfPackagesSoftwareImages.DiskFormatEnum + .fromValue(vnfPackageSoftwareImageInfo.getDiskFormat().getValue())); + } + + vnfPackagesSoftwareImages.setCreatedAt(vnfPackageSoftwareImageInfo.getCreatedAt()); + vnfPackagesSoftwareImages.setMinDisk(vnfPackageSoftwareImageInfo.getMinDisk()); + vnfPackagesSoftwareImages.setMinRam(vnfPackageSoftwareImageInfo.getMinRam()); + vnfPackagesSoftwareImages.setSize(vnfPackageSoftwareImageInfo.getSize()); + vnfPackagesSoftwareImages.setUserMetadata(vnfPackageSoftwareImageInfo.getUserMetadata()); + vnfPackagesSoftwareImages.setImagePath(vnfPackageSoftwareImageInfo.getImagePath()); + return vnfPackagesSoftwareImages; + } + + private List<VnfPackagesAdditionalArtifacts> convertVnfPackageArtifactInfoListToVnfPackagesAdditionalArtifactsList( + final List<VnfPackageArtifactInfo> vnfPackageArtifactInfoList) { + if (vnfPackageArtifactInfoList != null) { + final List<VnfPackagesAdditionalArtifacts> additionalArtifacts = new ArrayList<>(); + for (final VnfPackageArtifactInfo artifactInfo : vnfPackageArtifactInfoList) { + final VnfPackagesAdditionalArtifacts artifact = + convertVnfPackageArtifactInfoToVnfPackagesAdditionalArtifacts(artifactInfo); + additionalArtifacts.add(artifact); + } + return additionalArtifacts; + } + return null; + } + + private VnfPackagesAdditionalArtifacts convertVnfPackageArtifactInfoToVnfPackagesAdditionalArtifacts( + final VnfPackageArtifactInfo vnfPackageArtifactInfo) { + final VnfPackagesAdditionalArtifacts vnfPackagesAdditionalArtifacts = new VnfPackagesAdditionalArtifacts(); + vnfPackagesAdditionalArtifacts.setArtifactPath(vnfPackageArtifactInfo.getArtifactPath()); + vnfPackagesAdditionalArtifacts + .setChecksum(convertChecksumToVnfPackagesChecksum(vnfPackageArtifactInfo.getChecksum())); + vnfPackagesAdditionalArtifacts.setMetadata(vnfPackageArtifactInfo.getMetadata()); + return vnfPackagesAdditionalArtifacts; + } + + private VnfPackagesLinks getVnfPackagesLinks(final VNFPKGMLinkSerializer links, final String vnfPkgId) { + final VnfPackagesLinks vnfPackagesLinks = new VnfPackagesLinks(); + + if (links.getSelf() != null) { + vnfPackagesLinks.setSelf(getVnfPackagesLinksSelf(vnfmAdapterUrlProvider.getVnfPackageUrl(vnfPkgId))); + } + + if (links.getVnfd() != null) { + vnfPackagesLinks.setVnfd(getVnfPackagesLinksSelf(vnfmAdapterUrlProvider.getVnfPackageVnfdUrl(vnfPkgId))); + } + + if (links.getPackageContent() != null) { + vnfPackagesLinks.setPackageContent( + getVnfPackagesLinksSelf(vnfmAdapterUrlProvider.getVnfPackageContentUrl(vnfPkgId))); + } + + return vnfPackagesLinks; + } + + private VnfPackagesLinksSelf getVnfPackagesLinksSelf(final String href) { + return new VnfPackagesLinksSelf().href(href); + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/sol003/etsicatalog/PkgmSubscriptionRequestConverter.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/sol003/etsicatalog/PkgmSubscriptionRequestConverter.java new file mode 100644 index 0000000000..f63ada9c75 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/converters/sol003/etsicatalog/PkgmSubscriptionRequestConverter.java @@ -0,0 +1,198 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.converters.sol003.etsicatalog; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.Version; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfProducts; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfProductsProviders; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.PkgmSubscriptionRequest; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsFilter1; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsFilter1.NotificationTypesEnum; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsFilter1.OperationalStateEnum; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsFilter1.UsageStateEnum; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsFilterVersions; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsFilterVnfProducts; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsFilterVnfProductsFromProviders; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Service; + +/** + * Converter to convert from an Etsi Catalog Manager {@link PkgmSubscriptionRequest} Object to its equivalent ETSI + * Catalog Manager Object + * + * @author Ronan Kenny (ronan.kenny@est.tech) + * @author Gareth Roper (gareth.roper@est.tech) + */ +@Service +public class PkgmSubscriptionRequestConverter implements + Converter<PkgmSubscriptionRequest, org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest> { + + @Override + public org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest convert( + final PkgmSubscriptionRequest pkgmSubscriptionRequest) { + final org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest etsiCatalogManagerSubscriptionRequest = + new org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest(); + + etsiCatalogManagerSubscriptionRequest + .setFilter(getPkgmNotificationsFilter(pkgmSubscriptionRequest.getFilter())); + + return etsiCatalogManagerSubscriptionRequest; + } + + + private org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter getPkgmNotificationsFilter( + final SubscriptionsFilter1 sol003SubscriptionsFilter) { + final org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter etsiCatalogManagerFilters = + new org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter(); + + if (sol003SubscriptionsFilter.getNotificationTypes() != null) { + etsiCatalogManagerFilters.setNotificationTypes( + getPkgmNotificationsFilterNotificationTypes(sol003SubscriptionsFilter.getNotificationTypes())); + } + + etsiCatalogManagerFilters.setVnfProductsFromProviders( + getVnfProductsProviders(sol003SubscriptionsFilter.getVnfProductsFromProviders())); + + etsiCatalogManagerFilters.setVnfdId(getVnfdIds(sol003SubscriptionsFilter.getVnfdId())); + + etsiCatalogManagerFilters.setVnfPkgId(getVnfPkgIds(sol003SubscriptionsFilter.getVnfPkgId())); + + etsiCatalogManagerFilters + .setOperationalState(getOperationalState(sol003SubscriptionsFilter.getOperationalState())); + + etsiCatalogManagerFilters.setUsageState(getUsageState(sol003SubscriptionsFilter.getUsageState())); + + return etsiCatalogManagerFilters; + } + + + private List<org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter.UsageStateEnum> getUsageState( + final List<UsageStateEnum> usageStates) { + if (usageStates != null) { + final List<org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter.UsageStateEnum> etsiCatalogUsageStates = + new ArrayList<>(); + usageStates.stream().forEach(state -> { + etsiCatalogUsageStates.add( + org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter.UsageStateEnum + .fromValue(state.getValue())); + }); + return etsiCatalogUsageStates; + } + return Collections.emptyList(); + } + + + private List<org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter.OperationalStateEnum> getOperationalState( + final List<OperationalStateEnum> operationalStates) { + if (operationalStates != null) { + final List<org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter.OperationalStateEnum> etsiCatalogOperationalStates = + new ArrayList<>(); + operationalStates.forEach(state -> { + etsiCatalogOperationalStates.add( + org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter.OperationalStateEnum + .fromValue(state.getValue())); + }); + + return etsiCatalogOperationalStates; + } + return Collections.emptyList(); + } + + private List<String> getVnfPkgIds(final List<String> vnfPkgId) { + if (vnfPkgId != null) { + final List<String> etsiCatalogManagerVnfPkgId = new ArrayList<>(); + vnfPkgId.forEach(type -> { + etsiCatalogManagerVnfPkgId.add(type); + }); + return etsiCatalogManagerVnfPkgId; + } + return Collections.emptyList(); + } + + private List<String> getVnfdIds(final List<String> vnfdId) { + if (vnfdId != null) { + final List<String> etsiCatalogManagerVnfdId = new ArrayList<>(); + vnfdId.forEach(type -> { + etsiCatalogManagerVnfdId.add(type); + }); + return etsiCatalogManagerVnfdId; + } + return Collections.emptyList(); + } + + private List<VnfProductsProviders> getVnfProductsProviders( + final List<SubscriptionsFilterVnfProductsFromProviders> filterProductsFromProvider) { + + if (filterProductsFromProvider != null && !filterProductsFromProvider.isEmpty()) { + final List<VnfProductsProviders> etsiCatalogManagerVnfProductsProviders = new ArrayList<>(); + filterProductsFromProvider.forEach(vnfProduct -> { + etsiCatalogManagerVnfProductsProviders + .add(new VnfProductsProviders().vnfProvider(vnfProduct.getVnfProvider()) + .vnfProducts(getVnfProducts(vnfProduct.getVnfProducts()))); + }); + return etsiCatalogManagerVnfProductsProviders; + } + return Collections.emptyList(); + } + + private List<VnfProducts> getVnfProducts(final List<SubscriptionsFilterVnfProducts> sol003VnfProducts) { + if (sol003VnfProducts != null) { + final List<VnfProducts> etsiCatalogManagerVnfProductsList = new ArrayList<>(); + sol003VnfProducts.forEach(vnfProduct -> { + etsiCatalogManagerVnfProductsList.add(new VnfProducts().vnfProductName(vnfProduct.getVnfProductName()) + .versions(getVersion(vnfProduct.getVersions()))); + }); + return etsiCatalogManagerVnfProductsList; + } + return Collections.emptyList(); + } + + private List<Version> getVersion(final List<SubscriptionsFilterVersions> sol003FilterVersions) { + if (sol003FilterVersions != null && !sol003FilterVersions.isEmpty()) { + final List<Version> etsiCatalogVersionList = new ArrayList<>(); + sol003FilterVersions.forEach(vnfFilterVersion -> { + etsiCatalogVersionList.add(new Version().vnfSoftwareVersion(vnfFilterVersion.getVnfSoftwareVersion()) + .vnfdVersions(vnfFilterVersion.getVnfdVersions())); + }); + return etsiCatalogVersionList; + } + return Collections.emptyList(); + } + + private List<org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter.NotificationTypesEnum> getPkgmNotificationsFilterNotificationTypes( + final List<NotificationTypesEnum> notificationTypes) { + + if (notificationTypes != null && !notificationTypes.isEmpty()) { + final List<org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter.NotificationTypesEnum> etsiCatalogNotificationTypes = + new ArrayList<>(); + notificationTypes.forEach(type -> etsiCatalogNotificationTypes.add( + org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter.NotificationTypesEnum + .fromValue(type.getValue()))); + return etsiCatalogNotificationTypes; + } + return Collections.emptyList(); + } + + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/AbstractServiceProviderConfiguration.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/AbstractServiceProviderConfiguration.java new file mode 100644 index 0000000000..f9da6981c8 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/AbstractServiceProviderConfiguration.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.extclients; + +import java.time.LocalDateTime; +import java.util.Iterator; +import org.onap.so.adapters.etsisol003adapter.pkgm.JSON; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.EtsiSubscriptionNotificationController; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.client.RestTemplate; +import org.threeten.bp.OffsetDateTime; +import com.google.gson.Gson; + +/** + * A base class that can be extended by classes for configuring HttpRestServiceProvider classes. Provides common methods + * that will be useful to some such classes. + * + * @author gareth.roper@est.tech + */ +public abstract class AbstractServiceProviderConfiguration { + private final JSON.OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new JSON.OffsetDateTimeTypeAdapter(); + + public void setGsonMessageConverter(final RestTemplate restTemplate) { + final Iterator<HttpMessageConverter<?>> iterator = restTemplate.getMessageConverters().iterator(); + while (iterator.hasNext()) { + if (iterator.next() instanceof MappingJackson2HttpMessageConverter) { + iterator.remove(); + } + } + final Gson gson = JSON.createGson().registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter) + .registerTypeAdapter(LocalDateTime.class, + new EtsiSubscriptionNotificationController.LocalDateTimeTypeAdapter()) + .create(); + restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson)); + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java new file mode 100644 index 0000000000..db3c24bd1c --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogPackageManagementServiceProvider.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog; + +import java.util.Optional; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.InlineResponse2001; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public interface EtsiCatalogPackageManagementServiceProvider { + + /** + * GET Package Content, from VNF Package. + * + * @param vnfPkgId The ID of the VNF Package from which the "package_content" will be retrieved. + * @return The Package Content of a VNF Package ("vnfPkgId"). + */ + Optional<byte[]> getVnfPackageContent(final String vnfPkgId); + + /** + * GET VNF packages information from ETSI Catalog. Will return zero or more VNF package representations. + * + * @return An Array of all VNF packages retrieved from the ETSI Catalog. + */ + Optional<InlineResponse2001[]> getVnfPackages(); + + /** + * GET specific VNF package information from ETSI Catalog. + * + * @param vnfPkgId The ID of the VNF Package that you want to query. + * @return The VNF package retrieved from the ETSI Catalog + */ + Optional<InlineResponse2001> getVnfPackage(final String vnfPkgId); + + /** + * GET specific VNF package VNFD from ETSI Catalog. + * + * @param vnfPkgId The ID of the VNF Package that you want to query. + * @return The VNF package retrieved from the ETSI Catalog + */ + Optional<byte[]> getVnfPackageVnfd(final String vnfPkgId); + + /** + * GET Package Artifact, from VNF Package. + * + * @param vnfPkgId The ID of the VNF Package from which the artifact will be retrieved. + * @param artifactPath Sequence of one or more path segments representing the path of the artifact within the VNF + * Package, e.g., foo/bar/run.sh + * @return The Package Artifact of a VNF Package ("vnfPkgId", "artifactPath"). + */ + Optional<byte[]> getVnfPackageArtifact(final String vnfPkgId, final String artifactPath); + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogServiceProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogServiceProvider.java new file mode 100644 index 0000000000..f11fc5c39a --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogServiceProvider.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog; + +/** + * Provides methods for invoking REST calls to the ETSI Catalog Manager. + * + * @author gareth.roper@est.tech + */ +public interface EtsiCatalogServiceProvider + extends EtsiCatalogSubscriptionServiceProvider, EtsiCatalogPackageManagementServiceProvider { + + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java new file mode 100644 index 0000000000..5caeebe53d --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogServiceProviderConfiguration.java @@ -0,0 +1,187 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog; + +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.Iterator; +import java.util.concurrent.TimeUnit; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.onap.logging.filter.spring.SpringClientPayloadFilter; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.AbstractServiceProviderConfiguration; +import org.onap.so.configuration.rest.BasicHttpHeadersProvider; +import org.onap.so.configuration.rest.HttpClientConnectionConfiguration; +import org.onap.so.logging.jaxrs.filter.SOSpringClientFilter; +import org.onap.so.rest.service.HttpRestServiceProvider; +import org.onap.so.rest.service.HttpRestServiceProviderImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.client.RestTemplate; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +/** + * Configures the HttpRestServiceProvider to make REST calls to the ETSI Catalog Manager + * + * @author gareth.roper@est.tech + */ + +@Configuration +public class EtsiCatalogServiceProviderConfiguration extends AbstractServiceProviderConfiguration { + + public static final String ETSI_CATALOG_REST_TEMPLATE_BEAN = "etsiCatalogRestTemplate"; + + public static final String ETSI_CATALOG_SERVICE_PROVIDER_BEAN = "etsiCatalogServiceProvider"; + + private final static Logger LOGGER = LoggerFactory.getLogger(EtsiCatalogServiceProviderConfiguration.class); + + private final HttpClientConnectionConfiguration clientConnectionConfiguration; + + @Value("${etsi-catalog-manager.http.client.ssl.trust-store:#{null}}") + private Resource trustStore; + @Value("${etsi-catalog-manager.http.client.ssl.trust-store-password:#{null}}") + private String trustStorePassword; + + @Autowired + public EtsiCatalogServiceProviderConfiguration( + final HttpClientConnectionConfiguration clientConnectionConfiguration) { + this.clientConnectionConfiguration = clientConnectionConfiguration; + } + + @Bean + @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) + public RestTemplate etsiCatalogRestTemplate() { + final RestTemplate restTemplate = new RestTemplate(); + restTemplate.getInterceptors().add(new SOSpringClientFilter()); + restTemplate.getInterceptors().add((new SpringClientPayloadFilter())); + return restTemplate; + } + + @Bean + @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) + public HttpRestServiceProvider etsiCatalogHttpRestServiceProvider( + @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) final RestTemplate restTemplate) { + setGsonMessageConverter(restTemplate); + + final HttpClientBuilder httpClientBuilder = getHttpClientBuilder(); + if (trustStore != null) { + try { + LOGGER.debug("Setting up HttpComponentsClientHttpRequestFactory with SSL Context"); + LOGGER.debug("Setting client trust-store: {}", trustStore.getURL()); + LOGGER.debug("Creating SSLConnectionSocketFactory with AllowAllHostsVerifier ... "); + final SSLContext sslContext = new SSLContextBuilder() + .loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()).build(); + final SSLConnectionSocketFactory sslConnectionSocketFactory = + new SSLConnectionSocketFactory(sslContext, AllowAllHostsVerifier.INSTANCE); + httpClientBuilder.setSSLSocketFactory(sslConnectionSocketFactory); + final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder + .<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", sslConnectionSocketFactory).build(); + + httpClientBuilder.setConnectionManager(getConnectionManager(socketFactoryRegistry)); + } catch (final KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException + | IOException exception) { + LOGGER.error("Error reading truststore, TLS connection will fail.", exception); + } + + } else { + LOGGER.debug("Setting connection manager without SSL ConnectionSocketFactory ..."); + httpClientBuilder.setConnectionManager(getConnectionManager()); + } + + final HttpComponentsClientHttpRequestFactory factory = + new HttpComponentsClientHttpRequestFactory(httpClientBuilder.build()); + restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory)); + + return new HttpRestServiceProviderImpl(restTemplate, new BasicHttpHeadersProvider().getHttpHeaders()); + } + + private PoolingHttpClientConnectionManager getConnectionManager( + final Registry<ConnectionSocketFactory> socketFactoryRegistry) { + return new PoolingHttpClientConnectionManager(socketFactoryRegistry, null, null, null, + clientConnectionConfiguration.getTimeToLiveInMins(), TimeUnit.MINUTES); + } + + private PoolingHttpClientConnectionManager getConnectionManager() { + return new PoolingHttpClientConnectionManager(clientConnectionConfiguration.getTimeToLiveInMins(), + TimeUnit.MINUTES); + } + + private HttpClientBuilder getHttpClientBuilder() { + return HttpClientBuilder.create().setMaxConnPerRoute(clientConnectionConfiguration.getMaxConnectionsPerRoute()) + .setMaxConnTotal(clientConnectionConfiguration.getMaxConnections()) + .setDefaultRequestConfig(getRequestConfig()); + } + + private RequestConfig getRequestConfig() { + return RequestConfig.custom().setSocketTimeout(clientConnectionConfiguration.getSocketTimeOutInMiliSeconds()) + .setConnectTimeout(clientConnectionConfiguration.getConnectionTimeOutInMilliSeconds()).build(); + } + + private static final class AllowAllHostsVerifier implements HostnameVerifier { + + private static final AllowAllHostsVerifier INSTANCE = new AllowAllHostsVerifier(); + + @Override + public boolean verify(final String hostname, final SSLSession session) { + LOGGER.debug("Skipping hostname verification ..."); + return true; + } + + } + + public void setGsonMessageConverter(final RestTemplate restTemplate) { + final Iterator<HttpMessageConverter<?>> iterator = restTemplate.getMessageConverters().iterator(); + while (iterator.hasNext()) { + if (iterator.next() instanceof MappingJackson2HttpMessageConverter) { + iterator.remove(); + } + } + final Gson gson = new GsonBuilder().create(); + restTemplate.getMessageConverters().add(new GsonHttpMessageConverter(gson)); + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogServiceProviderImpl.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogServiceProviderImpl.java new file mode 100644 index 0000000000..a4e5550061 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogServiceProviderImpl.java @@ -0,0 +1,281 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog; + +import static org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_SERVICE_PROVIDER_BEAN; +import java.util.Optional; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdmSubscription; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscription; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.InlineResponse2001; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.EtsiCatalogManagerBadRequestException; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.EtsiCatalogManagerRequestFailureException; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.SubscriptionNotFoundException; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.VnfPkgBadRequestException; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.VnfPkgConflictException; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.VnfPkgNotFoundException; +import org.onap.so.rest.exceptions.HttpResouceNotFoundException; +import org.onap.so.rest.exceptions.InvalidRestRequestException; +import org.onap.so.rest.exceptions.RestProcessingException; +import org.onap.so.rest.service.HttpRestServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.convert.ConversionService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +/** + * Provides the implementations of the REST Requests to the ETSI Catalog Manager. + * + * @author gareth.roper@est.tech + */ +@Service +public class EtsiCatalogServiceProviderImpl implements EtsiCatalogServiceProvider { + private static final Logger logger = LoggerFactory.getLogger(EtsiCatalogServiceProviderImpl.class); + + private final HttpRestServiceProvider httpServiceProvider; + private final EtsiCatalogUrlProvider etsiCatalogUrlProvider; + private final ConversionService conversionService; + + @Autowired + public EtsiCatalogServiceProviderImpl(final EtsiCatalogUrlProvider etsiCatalogUrlProvider, + @Qualifier(ETSI_CATALOG_SERVICE_PROVIDER_BEAN) final HttpRestServiceProvider httpServiceProvider, + final ConversionService conversionService) { + this.etsiCatalogUrlProvider = etsiCatalogUrlProvider; + this.httpServiceProvider = httpServiceProvider; + this.conversionService = conversionService; + } + + @Override + public Optional<byte[]> getVnfPackageContent(final String vnfPkgId) + throws EtsiCatalogManagerRequestFailureException { + final String vnfRequestUrl = etsiCatalogUrlProvider.getVnfPackageContentUrl(vnfPkgId); + final String vnfRequestName = "getVnfPackageContent"; + return requestVnfElement(vnfPkgId, vnfRequestUrl, vnfRequestName); + } + + @Override + public Optional<byte[]> getVnfPackageArtifact(final String vnfPkgId, final String artifactPath) { + try { + final ResponseEntity<byte[]> response = httpServiceProvider.getHttpResponse( + etsiCatalogUrlProvider.getVnfPackageArtifactUrl(vnfPkgId, artifactPath), byte[].class); + logger.info("getVnfPackageArtifact Request to ETSI Catalog Manager Status Code: {}", + response.getStatusCodeValue()); + if (response.getStatusCode().is2xxSuccessful()) { + return Optional.ofNullable(response.getBody()); + } + } catch (final HttpResouceNotFoundException httpResouceNotFoundException) { + logger.error("Caught HttpResouceNotFoundException", httpResouceNotFoundException); + throw new VnfPkgNotFoundException("No Vnf Package Artifact found with vnfPkgId: \"" + vnfPkgId + + "\" and artifactPath: \"" + artifactPath + "\"."); + } catch (final RestProcessingException restProcessingException) { + logger.error("Caught RestProcessingException with Status Code: {}", restProcessingException.getStatusCode(), + restProcessingException); + if (restProcessingException.getStatusCode() == HttpStatus.CONFLICT.value()) { + throw new VnfPkgConflictException("A conflict occurred with the state of the resource,\n" + + "due to the attribute: onboardingState not being set to ONBOARDED."); + } + } + throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred."); + } + + @Override + public Optional<InlineResponse2001[]> getVnfPackages() { + try { + final ResponseEntity<VnfPkgInfo[]> response = + httpServiceProvider.getHttpResponse(etsiCatalogUrlProvider.getVnfPackagesUrl(), VnfPkgInfo[].class); + logger.info("getVnfPackages Request to ETSI Catalog Manager Status Code: {}", + response.getStatusCodeValue()); + if (response.getStatusCode().is2xxSuccessful()) { + if (response.hasBody()) { + final VnfPkgInfo[] vnfPackages = response.getBody(); + assert (vnfPackages != null); + final InlineResponse2001[] responses = new InlineResponse2001[vnfPackages.length]; + for (int index = 0; index < vnfPackages.length; index++) { + if (conversionService.canConvert(vnfPackages[index].getClass(), InlineResponse2001.class)) { + final InlineResponse2001 inlineResponse2001 = + conversionService.convert(vnfPackages[index], InlineResponse2001.class); + if (inlineResponse2001 != null) { + responses[index] = inlineResponse2001; + } + } else { + logger.error("Unable to find Converter for response class: {}", + vnfPackages[index].getClass()); + } + } + return Optional.of(responses); + } + logger.error("Received response without body ..."); + } + logger.error("Unexpected status code received {}", response.getStatusCode()); + return Optional.empty(); + } catch (final InvalidRestRequestException invalidRestRequestException) { + logger.error("Caught InvalidRestRequestException", invalidRestRequestException); + throw new VnfPkgBadRequestException("Error: Bad Request Received"); + } catch (final HttpResouceNotFoundException httpResouceNotFoundException) { + logger.error("Caught HttpResouceNotFoundException", httpResouceNotFoundException); + throw new VnfPkgNotFoundException("No Vnf Packages found"); + } catch (final RestProcessingException restProcessingException) { + logger.error("Caught RestProcessingException with Status Code: {}", restProcessingException.getStatusCode(), + restProcessingException); + throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred."); + } + } + + @Override + public Optional<InlineResponse2001> getVnfPackage(final String vnfPkgId) { + try { + final ResponseEntity<VnfPkgInfo> response = httpServiceProvider + .getHttpResponse(etsiCatalogUrlProvider.getVnfPackageUrl(vnfPkgId), VnfPkgInfo.class); + logger.info("getVnfPackage Request for vnfPkgId {} to ETSI Catalog Manager Status Code: {}", vnfPkgId, + response.getStatusCodeValue()); + if (response.getStatusCode().is2xxSuccessful()) { + if (response.hasBody()) { + final VnfPkgInfo vnfPkgInfo = response.getBody(); + if (conversionService.canConvert(vnfPkgInfo.getClass(), InlineResponse2001.class)) { + return Optional.ofNullable(conversionService.convert(vnfPkgInfo, InlineResponse2001.class)); + } + logger.error("Unable to find Converter for response class: {}", vnfPkgInfo.getClass()); + } + logger.error("Received response without body ...."); + } + return Optional.empty(); + } catch (final InvalidRestRequestException invalidRestRequestException) { + logger.error("Caught InvalidRestRequestException", invalidRestRequestException); + throw new VnfPkgBadRequestException("Error: Bad Request Received"); + } catch (final HttpResouceNotFoundException httpResouceNotFoundException) { + logger.error("Caught HttpResouceNotFoundException", httpResouceNotFoundException); + throw new VnfPkgNotFoundException("No Vnf Package found with vnfPkgId: " + vnfPkgId); + } catch (final RestProcessingException restProcessingException) { + logger.error("Caught RestProcessingException with Status Code: {}", restProcessingException.getStatusCode(), + restProcessingException); + throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred."); + } + } + + @Override + public Optional<byte[]> getVnfPackageVnfd(final String vnfPkgId) { + final String vnfRequestUrl = etsiCatalogUrlProvider.getVnfPackageVnfdUrl(vnfPkgId); + final String vnfRequestName = "getVnfPackageVnfd"; + return requestVnfElement(vnfPkgId, vnfRequestUrl, vnfRequestName); + } + + @Override + public Optional<PkgmSubscription> postSubscription( + final org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest etsiCatalogManagerSubscriptionRequest) { + try { + final ResponseEntity<PkgmSubscription> responseEntity = + httpServiceProvider.postHttpRequest(etsiCatalogManagerSubscriptionRequest, + etsiCatalogUrlProvider.getSubscriptionUrl(), PkgmSubscription.class); + if (responseEntity.getStatusCode().is2xxSuccessful()) { + if (responseEntity.hasBody()) { + return Optional.of(responseEntity.getBody()); + } + logger.error("Received response without body on postSubscription"); + } + logger.error("Unexpected Status Code Received on postSubscription: {}", responseEntity.getStatusCode()); + return Optional.empty(); + } catch (final InvalidRestRequestException invalidRestRequestException) { + logger.error("Caught InvalidRestRequestException", invalidRestRequestException); + throw new EtsiCatalogManagerBadRequestException( + "Bad Request Received on postSubscription call to ETSI Catalog Manager."); + } catch (final RestProcessingException restProcessingException) { + logger.error("Caught RestProcessingException with Status Code: {}", restProcessingException.getStatusCode(), + restProcessingException); + throw new EtsiCatalogManagerRequestFailureException( + "Internal Server Error Occurred. On postSubscription with StatusCode: " + + restProcessingException.getStatusCode()); + } + } + + @Override + public boolean deleteSubscription(final String subscriptionId) { + try { + final ResponseEntity<Void> responseEntity = httpServiceProvider + .deleteHttpRequest(etsiCatalogUrlProvider.getSubscriptionUrl() + "/" + subscriptionId, Void.class); + + if (responseEntity.getStatusCode().is2xxSuccessful()) { + logger.info("Subscription with ID: {} has been successfully deleted from the ETSI Catalog Manager", + subscriptionId); + return true; + } + logger.error("Unexpected Status Code Received on deleteSubscription: {}", responseEntity.getStatusCode()); + return false; + } catch (final HttpResouceNotFoundException resouceNotFoundException) { + final String message = "Unable to find subscription in ETSI Catalog Manager using id: " + subscriptionId; + logger.error(message); + throw new SubscriptionNotFoundException(message); + } catch (final InvalidRestRequestException invalidRestRequestException) { + logger.error("Caught InvalidRestRequestException on deleteSubscription call to ETSI Catalog Manager.", + invalidRestRequestException); + throw new EtsiCatalogManagerBadRequestException( + "Bad Request Received on deleteSubscription call to ETSI Catalog Manager."); + } + } + + @Override + public Optional<NsdmSubscription> getSubscription(final String subscriptionId) { + try { + final ResponseEntity<NsdmSubscription> responseEntity = httpServiceProvider.getHttpResponse( + etsiCatalogUrlProvider.getSubscriptionUrl() + "/" + subscriptionId, NsdmSubscription.class); + + if (responseEntity.getStatusCode().is2xxSuccessful()) { + logger.debug("Found subscription with ID: {} in ETSI Catalog Manager", subscriptionId); + return Optional.ofNullable(responseEntity.getBody()); + } + logger.error("Unexpected Status Code Received on getting subscription from ETSI Catalog Manager: {}", + responseEntity.getStatusCode()); + } catch (final HttpResouceNotFoundException resouceNotFoundException) { + logger.error("Unable to find subscription in ETSI Catalog Manager using id: {}", subscriptionId); + return Optional.empty(); + } catch (final RestProcessingException | InvalidRestRequestException exception) { + logger.error("Unable to query ETSI Catalog Manager for subscription using id: {}", subscriptionId, + exception); + } + throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred."); + } + + private Optional<byte[]> requestVnfElement(final String vnfPkgId, final String vnfRequestUrl, + final String vnfRequestName) { + try { + final ResponseEntity<byte[]> response = httpServiceProvider.getHttpResponse(vnfRequestUrl, byte[].class); + logger.info("{} Request to ETSI Catalog Manager Status Code: {}", vnfRequestName, + response.getStatusCodeValue()); + if (response.getStatusCode() == HttpStatus.OK) { + return Optional.ofNullable(response.getBody()); + } + } catch (final HttpResouceNotFoundException httpResouceNotFoundException) { + logger.error("Caught HttpResouceNotFoundException", httpResouceNotFoundException); + throw new VnfPkgNotFoundException("No Vnf Package found with vnfPkgId: " + vnfPkgId); + } catch (final RestProcessingException restProcessingException) { + logger.error("Caught RestProcessingException with Status Code: {}", restProcessingException.getStatusCode(), + restProcessingException); + if (restProcessingException.getStatusCode() == HttpStatus.CONFLICT.value()) { + throw new VnfPkgConflictException("A conflict occurred with the state of the resource,\n" + + "due to the attribute: onboardingState not being set to ONBOARDED."); + } + } + throw new EtsiCatalogManagerRequestFailureException("Internal Server Error Occurred."); + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogSubscriptionServiceProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogSubscriptionServiceProvider.java new file mode 100644 index 0000000000..d561f8734b --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogSubscriptionServiceProvider.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog; + +import java.util.Optional; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdmSubscription; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscription; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public interface EtsiCatalogSubscriptionServiceProvider { + + /** + * POST the SubscriptionRequest Object. + * + * @return The ETSI Catalog Manager's PkgmSubscription object. + */ + Optional<PkgmSubscription> postSubscription( + final org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest etsiCatalogManagerSubscriptionRequest); + + /** + * Get the Subscription from ETSI Catalog. + * + * @param subscriptionId Subscription ID + * @return The Subscription {@link NsdmSubscription} from ETSI Catalog + */ + Optional<NsdmSubscription> getSubscription(final String subscriptionId); + + /** + * DELETE the SubscriptionRequest Object. + * + * @return A Boolean representing if the delete was successful or not. + */ + boolean deleteSubscription(final String subscriptionId); + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogUrlProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogUrlProvider.java new file mode 100644 index 0000000000..1725bf9fba --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/etsicatalog/EtsiCatalogUrlProvider.java @@ -0,0 +1,113 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog; + +import static org.slf4j.LoggerFactory.getLogger; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * Provides the URLs for the REST Requests to the ETSI Catalog Manager. + * + * @author gareth.roper@est.tech + */ +@Service +public class EtsiCatalogUrlProvider { + + private static final Logger logger = getLogger(EtsiCatalogUrlProvider.class); + + @Value("${etsi-catalog-manager.vnfpkgm.endpoint}") + private String etsiCatalogManagerEndpoint; + + public EtsiCatalogUrlProvider() {} + + /** + * Get the URL for retrieving the Package Content from the ETSI Catalog.". + * + * @param vnfPkgId The ID of the VNF Package + * @return the URL for the GET operation + */ + public String getVnfPackageContentUrl(final String vnfPkgId) { + final String url = etsiCatalogManagerEndpoint + "/vnf_packages/" + vnfPkgId + "/package_content"; + logger.info("getEtsiCatalogVnfPackageContentUrl: {}", url); + return url; + } + + /** + * Get the URL for retrieving VNF packages information from ETSI Catalog.". + * + * @return the URL for the GET operation + */ + public String getVnfPackagesUrl() { + final String url = etsiCatalogManagerEndpoint + "/vnf_packages"; + logger.info("getEtsiCatalogVnfPackagesEndpoint: {}", url); + return url; + } + + /** + * Get the URL for retrieving specific VNF package information from the ETSI Catalog.". + * + * @param vnfPkgId The ID of the VNF Package + * @return the URL for the GET operation + */ + public String getVnfPackageUrl(final String vnfPkgId) { + final String url = etsiCatalogManagerEndpoint + "/vnf_packages/" + vnfPkgId; + logger.info("getEtsiCatalogVnfPackageEndpoint: {}", url); + return url; + } + + /** + * Get the URL for retrieving VNF Package Artifacts + * + * @param vnfPkgId The ID of the VNF Package + * @param artifactPath The path to the Artifact + * @return the URL for the GET operation + */ + public String getVnfPackageArtifactUrl(final String vnfPkgId, final String artifactPath) { + final String url = etsiCatalogManagerEndpoint + "/vnf_packages/" + vnfPkgId + "/artifacts/" + artifactPath; + logger.info("getVnfPackageArtifactUrl: {}", url); + return url; + } + + /** + * Get the URL for retrieving VNF packages vnfd from ETSI Catalog. + * + * @param vnfPkgId The ID of the VNF Package + * @return the URL for the GET operation + */ + public String getVnfPackageVnfdUrl(final String vnfPkgId) { + final String url = etsiCatalogManagerEndpoint + "/vnf_packages/" + vnfPkgId + "/vnfd"; + logger.info("getEtsiCatalogVnfPackageVnfd: {}", url); + return url; + } + + /** + * Get the URL for posting/retrieving a Subscription + * + * @return the URL for the operation + */ + public String getSubscriptionUrl() { + final String url = etsiCatalogManagerEndpoint + "/subscriptions"; + logger.info("getSubscriptionNotificationUrl: {}", url); + return url; + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/vnfm/VnfmHttpServiceProviderConfiguration.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/vnfm/VnfmHttpServiceProviderConfiguration.java new file mode 100644 index 0000000000..568c3df48b --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/extclients/vnfm/VnfmHttpServiceProviderConfiguration.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm; + +import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.AbstractServiceProviderConfiguration; +import org.onap.so.configuration.rest.BasicHttpHeadersProvider; +import org.onap.so.rest.service.HttpRestServiceProvider; +import org.onap.so.rest.service.HttpRestServiceProviderImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Configuration +public class VnfmHttpServiceProviderConfiguration extends AbstractServiceProviderConfiguration { + public static final String VNFM_ADAPTER_HTTP_SERVICE_PROVIDER_BEAN = "vnfmAdapterHttpServiceProvider"; + + @Bean + @Qualifier(VNFM_ADAPTER_HTTP_SERVICE_PROVIDER_BEAN) + public HttpRestServiceProvider vnfmAdapterHttpRestServiceProvider( + @Autowired @Qualifier(CONFIGURABLE_REST_TEMPLATE) RestTemplate restTemplate) { + setGsonMessageConverter(restTemplate); + return new HttpRestServiceProviderImpl(restTemplate, new BasicHttpHeadersProvider().getHttpHeaders()); + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/EtsiSubscriptionNotificationController.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/EtsiSubscriptionNotificationController.java new file mode 100644 index 0000000000..2b4b486fa8 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/EtsiSubscriptionNotificationController.java @@ -0,0 +1,166 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.rest; + +import static org.onap.so.adapters.etsi.sol003.adapter.common.CommonConstants.ETSI_SUBSCRIPTION_NOTIFICATION_CONTROLLER_BASE_URL; +import static org.slf4j.LoggerFactory.getLogger; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.AbstractMap; +import java.util.Map.Entry; +import javax.ws.rs.core.MediaType; +import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgChangeNotification; +import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgOnboardingNotification; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.InternalServerErrorException; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.NotificationTypeNotSupportedException; +import org.onap.so.adapters.etsisol003adapter.pkgm.subscriptionmgmt.NotificationManager; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +/** + * This controller handles the ETSI Subscription Notification Endpoints. + * + * @author Ronan Kenny (ronan.kenny@est.tech) + * @author Gareth Roper (gareth.roper@est.tech) + * @author Andrew Lamb (andrew.a.lamb@est.tech) + */ +@Controller +@RequestMapping(value = ETSI_SUBSCRIPTION_NOTIFICATION_CONTROLLER_BASE_URL) +public class EtsiSubscriptionNotificationController { + + private static final Logger logger = getLogger(EtsiSubscriptionNotificationController.class); + private final NotificationManager notificationManager; + private final Gson gson; + + @Autowired + public EtsiSubscriptionNotificationController(final NotificationManager notificationManager) { + this.notificationManager = notificationManager; + this.gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()).create(); + } + + @GetMapping(value = "/notification") + public ResponseEntity<Void> testSubscriptionNotificationEndPoint() { + logger.debug("Testing Notification Endpoint"); + return ResponseEntity.noContent().build(); + } + + /** + * POST notification on to subscriber. + * + * @param notification The notification to send. + * @return Response Code: 204 No Content if Successful, ProblemDetails Object if not. + */ + @PostMapping(value = "/notification", consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON) + public ResponseEntity<?> postSubscriptionNotification(@RequestBody final Object notification) { + logger.info("Posting subscription notification class: {} \n{}", notification.getClass(), notification); + final String notificationString = gson.toJson(notification); + + final Entry<String, Object> notificationObject = getNotificationObject(notificationString); + if (notificationManager.processSubscriptionNotification(notificationObject.getValue(), + notificationObject.getKey())) { + logger.info("Notification Delivered Successfully"); + return ResponseEntity.noContent().build(); + } + final String errorMessage = "An error occurred. Sending of notification to VNFM failed."; + logger.error(errorMessage); + throw new InternalServerErrorException(errorMessage); + } + + private Entry<String, Object> getNotificationObject(final String notification) { + logger.info("getNotificationObject() notification: {}", notification); + final String notificationType = getNotificationType(notification); + if (PkgOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION.getValue() + .equals(notificationType)) { + final PkgOnboardingNotification pkgOnboardingNotification = + gson.fromJson(notification, PkgOnboardingNotification.class); + logger.info("Onboarding notification received:\n{}", pkgOnboardingNotification); + return new AbstractMap.SimpleEntry<>(pkgOnboardingNotification.getSubscriptionId(), + pkgOnboardingNotification); + } + if (PkgChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.getValue() + .equals(notificationType)) { + final PkgChangeNotification pkgChangeNotification = + gson.fromJson(notification, PkgChangeNotification.class); + logger.info("Change notification received:\n{}", pkgChangeNotification); + return new AbstractMap.SimpleEntry<>(pkgChangeNotification.getSubscriptionId(), pkgChangeNotification); + + } + + final String errorMessage = "An error occurred. Notification type not supported for: " + notificationType; + logger.error(errorMessage); + throw new NotificationTypeNotSupportedException(errorMessage); + + } + + private String getNotificationType(final String notification) { + try { + logger.info("getNotificationType() notification: {}", notification); + final JsonParser parser = new JsonParser(); + final JsonObject element = (JsonObject) parser.parse(notification); + return element.get("notificationType").getAsString(); + } catch (final Exception e) { + logger.error("An error occurred processing notificiation: {}", e.getMessage()); + } + throw new NotificationTypeNotSupportedException( + "Unable to parse notification type in object \n" + notification); + } + + public static class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> { + + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + @Override + public void write(final JsonWriter out, final LocalDateTime localDateTime) throws IOException { + if (localDateTime == null) { + out.nullValue(); + } else { + out.value(FORMATTER.format(localDateTime)); + } + } + + @Override + public LocalDateTime read(final JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + final String dateTime = in.nextString(); + return LocalDateTime.parse(dateTime, FORMATTER); + } + } + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementController.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementController.java new file mode 100644 index 0000000000..6c1e5e5506 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementController.java @@ -0,0 +1,176 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.rest; + +import static org.onap.so.adapters.etsi.sol003.adapter.common.CommonConstants.PACKAGE_MANAGEMENT_BASE_URL; +import static org.onap.so.adapters.etsisol003adapter.pkgm.PackageManagementConstants.APPLICATION_ZIP; +import static org.slf4j.LoggerFactory.getLogger; +import java.util.Optional; +import javax.ws.rs.core.MediaType; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.EtsiCatalogServiceProvider; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.ProblemDetails; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.InlineResponse2001; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * Controller for handling the VNF Package Management. For further information please read: + * https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/003/02.05.01_60/gs_nfv-sol003v020501p.pdf Use the section number + * above each endpoint to find the corresponding section in the above document. + * + * @author gareth.roper@est.tech + */ +@Controller +@RequestMapping(value = PACKAGE_MANAGEMENT_BASE_URL, consumes = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) +public class Sol003PackageManagementController { + + private final EtsiCatalogServiceProvider etsiCatalogServiceProvider; + private static final String LOG_REQUEST_RECEIVED = "VNF PackageManagement Controller: {} {} {} {}"; + private static final Logger logger = getLogger(Sol003PackageManagementController.class); + + @Autowired + Sol003PackageManagementController(final EtsiCatalogServiceProvider etsiCatalogServiceProvider) { + this.etsiCatalogServiceProvider = etsiCatalogServiceProvider; + } + + /** + * GET VNF packages information. Will return zero or more VNF package representations that match the attribute + * filter. These representations will be in a list. Section Number: 10.4.2 + * + * @return An Array of all VNF packages. Object: InlineResponse2001[] Response Code: 200 OK + */ + @GetMapping(value = "/vnf_packages", produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + public ResponseEntity<?> getVnfPackages() { + logger.info(LOG_REQUEST_RECEIVED, "getVnfPackages."); + final Optional<InlineResponse2001[]> response = etsiCatalogServiceProvider.getVnfPackages(); + if (response.isPresent()) { + logger.info(LOG_REQUEST_RECEIVED, "getVnfPackages Response: ", HttpStatus.OK); + return ResponseEntity.ok().body(response.get()); + } + final String errorMessage = "An error occurred, a null response was received by the\n" + + " Sol003PackageManagementController from the EtsiCatalogManager using the GET \"vnf_packages\" \n" + + "endpoint."; + logger.error(errorMessage); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ProblemDetails().detail(errorMessage)); + } + + /** + * GET VNF package information. Will return a specific VNF package representation that match the attribute filter. + * Section Number: 10.4.3 + * + * @param vnfPkgId The ID of the VNF Package that you want to query. + * @return A VNF package based on vnfPkgId. Object: VnfPkgInfo Response Code: 200 OK + */ + @GetMapping(value = "/vnf_packages/{vnfPkgId}", produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + public ResponseEntity<?> getVnfPackage(@PathVariable("vnfPkgId") final String vnfPkgId) { + logger.info(LOG_REQUEST_RECEIVED, "getVnfPackage: ", vnfPkgId); + final Optional<InlineResponse2001> response = etsiCatalogServiceProvider.getVnfPackage(vnfPkgId); + if (response.isPresent()) { + logger.info(LOG_REQUEST_RECEIVED, "getVnfPackage Response: ", HttpStatus.OK); + return ResponseEntity.ok().body(response.get()); + } + final String errorMessage = "An error occurred, a null response was received by the\n" + + " Sol003PackageManagementController from the EtsiCatalogManager using the GET \"vnf_packages\" by vnfPkgId: \"" + + vnfPkgId + "\" \n" + "endpoint."; + logger.error(errorMessage); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ProblemDetails().detail(errorMessage)); + } + + /** + * GET VNFD, from VNF package. Will return a copy of the file representing the VNFD or a ZIP file that contains the + * file/multiple files representing the VNFD specified. Section Number: 10.4.4 + * + * @param vnfPkgId The ID of the VNF Package that you want to retrieve the VNFD from. + * @return The VNFD of a VNF Package as a single file or within a ZIP file. Object: byte[] Response Code: 200 OK + */ + @GetMapping(value = "/vnf_packages/{vnfPkgId}/vnfd", + produces = {MediaType.TEXT_PLAIN, APPLICATION_ZIP, MediaType.APPLICATION_JSON}) + public ResponseEntity<?> getVnfPackageVnfd(@PathVariable("vnfPkgId") final String vnfPkgId) { + logger.info(LOG_REQUEST_RECEIVED, "getVnfPackageVnfd Endpoint Invoked with VNF Package ID: ", vnfPkgId); + final Optional<byte[]> response = etsiCatalogServiceProvider.getVnfPackageVnfd(vnfPkgId); + if (response.isPresent()) { + logger.info(LOG_REQUEST_RECEIVED, "getVnfPackageVnfd Response: ", HttpStatus.OK); + return new ResponseEntity<>(response.get(), HttpStatus.OK); + } + final String errorMessage = "An error occurred, a null response was received by the\n" + + " Sol003PackageManagementController from the EtsiCatalogManager using the GET \"vnfd\" \n" + + "endpoint."; + + logger.error(errorMessage); + return new ResponseEntity<>(new ProblemDetails().detail(errorMessage), HttpStatus.INTERNAL_SERVER_ERROR); + } + + /** + * GET Package Content, from VNF Package. Will return a copy of the VNF package file that you specified. Section + * Number: 10.4.5 + * + * @param vnfPkgId The ID of the VNF Package that you want to retrieve the "package_content" from. + * @return The Package Content of a VNF Package. Object: byte[] Response Code: 200 OK + */ + @GetMapping(value = "/vnf_packages/{vnfPkgId}/package_content", + produces = {MediaType.APPLICATION_JSON, APPLICATION_ZIP, MediaType.APPLICATION_OCTET_STREAM}) + public ResponseEntity<?> getVnfPackageContent(@PathVariable("vnfPkgId") final String vnfPkgId) { + logger.info(LOG_REQUEST_RECEIVED, "getVnfPackageContent Endpoint Invoked with VNF Package ID: ", vnfPkgId); + final Optional<byte[]> response = etsiCatalogServiceProvider.getVnfPackageContent(vnfPkgId); + if (response.isPresent()) { + logger.info(LOG_REQUEST_RECEIVED, "getVnfPackageContent Response: ", HttpStatus.OK); + return ResponseEntity.ok().body(response.get()); + } + final String errorMessage = "An error occurred, a null response was received by the\n" + + " Sol003PackageManagementController from the EtsiCatalogManager using the GET \"package_content\" \n" + + "endpoint."; + logger.error(errorMessage); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ProblemDetails().detail(errorMessage)); + } + + /** + * GET Artifact, from VNF Package Will return a the content of the artifact that you specified. Section Number: + * 10.4.6 + * + * @param vnfPkgId The ID of the VNF Package that you want to retrieve an artifact from. + * @param artifactPath The path of the artifact that you want to retrieve. + * @return An Artifact from a VNF Package. Object: byte[] Response Code: 200 OK + */ + @GetMapping(value = "/vnf_packages/{vnfPkgId}/artifacts/{artifactPath}", + produces = {MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON}) + public ResponseEntity<?> getVnfPackageArtifact(@PathVariable("vnfPkgId") final String vnfPkgId, + @PathVariable("artifactPath") final String artifactPath) { + logger.info(LOG_REQUEST_RECEIVED, "getVnfPackageArtifact: vnfPkgId= ", vnfPkgId, " artifactPath=", + artifactPath); + final Optional<byte[]> response = etsiCatalogServiceProvider.getVnfPackageArtifact(vnfPkgId, artifactPath); + if (response.isPresent()) { + logger.info(LOG_REQUEST_RECEIVED, "getVnfPackageArtifact Response: ", HttpStatus.OK); + return ResponseEntity.ok().body(response.get()); + } + final String errorMessage = "An error occurred, a null response was received by the\n" + + " Sol003PackageManagementController from the EtsiCatalogManager using the\n GET \"vnf_packages\" by vnfPkgId: \"" + + vnfPkgId + "\" for artifactPath: \"" + artifactPath + "\"\n" + "endpoint."; + logger.error(errorMessage); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ProblemDetails().detail(errorMessage)); + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementSubscriptionController.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementSubscriptionController.java new file mode 100644 index 0000000000..7314f6aa2e --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementSubscriptionController.java @@ -0,0 +1,172 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.rest; + +import static org.onap.so.adapters.etsi.sol003.adapter.common.CommonConstants.PACKAGE_MANAGEMENT_BASE_URL; +import static org.slf4j.LoggerFactory.getLogger; +import java.net.URI; +import java.security.GeneralSecurityException; +import java.util.List; +import java.util.Optional; +import javax.ws.rs.core.MediaType; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.ProblemDetails; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.InlineResponse201; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.PkgmSubscriptionRequest; +import org.onap.so.adapters.etsisol003adapter.pkgm.subscriptionmgmt.SubscriptionManager; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * Controller for handling the Subscription Management. The client can use this resource to subscribe to notifications + * related to the VNF package management, and to query its subscriptions. For further information please read: + * https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/003/02.05.01_60/gs_nfv-sol003v020501p.pdf Use the section number + * above each endpoint to find the corresponding section in the above document. + * + * @author Ronan Kenny (ronan.kenny@est.tech) + * @author Gareth Roper (gareth.roper@est.tech) + */ +@Controller +@RequestMapping(value = PACKAGE_MANAGEMENT_BASE_URL, produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}, + consumes = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) +public class Sol003PackageManagementSubscriptionController { + + private static final String LOG_REQUEST_RECEIVED = "Subscription Management Controller: {} {}"; + private static final Logger logger = getLogger(Sol003PackageManagementSubscriptionController.class); + private final SubscriptionManager subscriptionManager; + + @Autowired + public Sol003PackageManagementSubscriptionController(final SubscriptionManager subscriptionManager) { + this.subscriptionManager = subscriptionManager; + } + + /** + * POST Subscribe request. Will send request and respond with the subscription that you subscribed to, if + * successful. Section Number: 10.4.7 + * + * @param pkgmSubscriptionRequest This includes the details of the subscription to be created. + * @return The subscription requested, if successful. Object: InlineRespone2002 Response Code: 201 Created Response + * Code: 303 Duplicate Subscription + * @throws GeneralSecurityException + */ + @PostMapping(value = "/subscriptions") + public ResponseEntity<?> postSubscriptionRequest(@RequestBody final PkgmSubscriptionRequest pkgmSubscriptionRequest) + throws GeneralSecurityException { + logger.info(LOG_REQUEST_RECEIVED, " postSubscriptionRequest Endpoint Called", pkgmSubscriptionRequest); + + // Check if subscription exists already. + final Optional<String> exists = subscriptionManager.getSubscriptionId(pkgmSubscriptionRequest); + + if (exists.isPresent()) { + final URI subscriptionUri = subscriptionManager.getSubscriptionUri(exists.get()); + final HttpHeaders headers = createLocationHeader(subscriptionUri); + logger.info("PkgmSubscriptionRequest already exists with uri {} ", subscriptionUri); + return new ResponseEntity<>(headers, HttpStatus.SEE_OTHER); + } + + logger.debug("No duplicate Subscription exists, continuing with POST."); + final Optional<InlineResponse201> optionalInlineResponse = + subscriptionManager.createSubscription(pkgmSubscriptionRequest); + + if (optionalInlineResponse.isPresent()) { + InlineResponse201 inlineResponse = optionalInlineResponse.get(); + final URI subscriptionUri = subscriptionManager.getSubscriptionUri(inlineResponse.getId()); + final HttpHeaders headers = createLocationHeader(subscriptionUri); + logger.debug("Sending response with uri {} ", subscriptionUri); + return new ResponseEntity<>(inlineResponse, headers, HttpStatus.CREATED); + } + final String errorMessage = "A null response was received during the postSubscriptionRequest call."; + logger.error(errorMessage); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ProblemDetails().detail(errorMessage)); + } + + /** + * GET all subscriptions. Will return a list of all subscriptions currently active. Section Number: 10.4.7 + * + * @return All of the current active subscriptions. Object: List<InlineResponse2002> Response Code: 200 OK + */ + @GetMapping(value = "/subscriptions") + public ResponseEntity<List<InlineResponse201>> getSubscriptions() { + logger.info(LOG_REQUEST_RECEIVED, " getSubscriptions."); + List<InlineResponse201> subscriptionsList = subscriptionManager.getSubscriptions(); + return new ResponseEntity<>(subscriptionsList, HttpStatus.OK); + } + + /** + * GET a specific subscription, by subscriptionId. Section Number: 10.4.8 + * + * @param subscriptionId The ID of the subscription that you wish to retrieve. + * @return A subscription based on subscriptionId. Object: InlineResponse2002 Response Code: 200 OK + */ + @GetMapping(value = "/subscriptions/{subscriptionId}") + public ResponseEntity<?> getSubscription(@PathVariable("subscriptionId") final String subscriptionId) { + logger.info(LOG_REQUEST_RECEIVED, " Getting Subscription: ", subscriptionId); + final Optional<InlineResponse201> optional = subscriptionManager.getSubscription(subscriptionId); + if (optional.isPresent()) { + logger.debug("Return subscription with id {} and body {}", subscriptionId, optional); + return new ResponseEntity<>(optional.get(), HttpStatus.OK); + } + final String errorMessage = + "The requested subscription: " + subscriptionId + " was not found on call getSubscription"; + logger.error(errorMessage); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ProblemDetails().detail(errorMessage)); + } + + /** + * DELETE a specific subscription, by subscriptionId. Section Number: 10.4.8.3.5 + * + * @param subscriptionId The ID of the subscription that you wish to delete. + * @return Empty response if successful. Object: Void Response Code: 204 No Content + */ + @DeleteMapping(value = "/subscriptions/{subscriptionId}") + public ResponseEntity<?> deleteSubscription(@PathVariable("subscriptionId") final String subscriptionId) { + if (subscriptionManager.deleteSubscription(subscriptionId)) { + logger.debug("Successfully deleted subscription with id {}", subscriptionId); + return ResponseEntity.noContent().build(); + } + final String errorMessage = + "The requested subscription: " + subscriptionId + " was not found on call deleteSubscription"; + logger.error(errorMessage); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ProblemDetails().detail(errorMessage)); + } + + /** + * Method to set the Location in the header with the URI parameter + * + * @param subscriptionUri + * @return header with callbackUri in Location + */ + private HttpHeaders createLocationHeader(final URI subscriptionUri) { + final HttpHeaders headers = new HttpHeaders(); + headers.setLocation(subscriptionUri); + return headers; + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/AuthenticationTypeNotSupportedException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/AuthenticationTypeNotSupportedException.java new file mode 100644 index 0000000000..6e1330140f --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/AuthenticationTypeNotSupportedException.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Exception for an unsupported authentication type + * + * @author Andrew Lamb (andrew.a.lamb@est.tech) + */ +@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR) +public class AuthenticationTypeNotSupportedException extends RuntimeException { + + private static final long serialVersionUID = 2939423208362066902L; + + public AuthenticationTypeNotSupportedException(final String message) { + super(message); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/ConversionFailedException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/ConversionFailedException.java new file mode 100644 index 0000000000..9e9cb8e352 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/ConversionFailedException.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Exception for Conversion Failures + * + * @author Gareth Roper (gareth.roper@est.tech) + * @author Andrew Lamb (andrew.a.lamb@est.tech) + */ +@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR) +public class ConversionFailedException extends RuntimeException { + + private static final long serialVersionUID = 45898561453196895L; + + public ConversionFailedException(final String message) { + super(message); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiCatalogManagerBadRequestException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiCatalogManagerBadRequestException.java new file mode 100644 index 0000000000..7d9d5fc17a --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiCatalogManagerBadRequestException.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Exception for an ETSI Catalog Manager Bad Request Exception. + * + * @author Gareth Roper (gareth.roper@est.tech + */ +@ResponseStatus(code = HttpStatus.BAD_REQUEST) +public class EtsiCatalogManagerBadRequestException extends RuntimeException { + + private static final long serialVersionUID = 6571317418914258768L; + + public EtsiCatalogManagerBadRequestException(final String message) { + super(message); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiCatalogManagerRequestFailureException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiCatalogManagerRequestFailureException.java new file mode 100644 index 0000000000..a07732f3fa --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiCatalogManagerRequestFailureException.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Exception for an ETSI Catalog Manager Request Failure + * + * @author gareth.roper@est.tech + */ +@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR) +public class EtsiCatalogManagerRequestFailureException extends RuntimeException { + + private static final long serialVersionUID = 66862444537194516L; + + public EtsiCatalogManagerRequestFailureException(final String message) { + super(message); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiSubscriptionNotificationControllerExceptionHandler.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiSubscriptionNotificationControllerExceptionHandler.java new file mode 100644 index 0000000000..645ef96326 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/EtsiSubscriptionNotificationControllerExceptionHandler.java @@ -0,0 +1,112 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import static org.slf4j.LoggerFactory.getLogger; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.ProblemDetails; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.EtsiSubscriptionNotificationController; +import org.onap.so.rest.exceptions.HttpResouceNotFoundException; +import org.onap.so.rest.exceptions.InvalidRestRequestException; +import org.onap.so.rest.exceptions.RestProcessingException; +import org.slf4j.Logger; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +/** + * Exception Handler for the Etsi Subscription Notification Controller {@link EtsiSubscriptionNotificationController + * EtsiSubscriptionNotificationController} + * + * @author Andrew Lamb (andrew.a.lamb@est.tech) + */ +@ControllerAdvice(assignableTypes = EtsiSubscriptionNotificationController.class) +public class EtsiSubscriptionNotificationControllerExceptionHandler { + + private static final Logger logger = getLogger(EtsiSubscriptionNotificationControllerExceptionHandler.class); + + @ExceptionHandler(InvalidRestRequestException.class) + public ResponseEntity<ProblemDetails> handleInvalidRestRequestException( + final InvalidRestRequestException invalidRestRequestException) { + final String errorMessage = "An error occurred. Sending of notification to VNFM failed with response: " + + HttpStatus.BAD_REQUEST + ".\n" + invalidRestRequestException.getMessage(); + logger.error(errorMessage); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ProblemDetails().detail(errorMessage)); + } + + @ExceptionHandler(HttpResouceNotFoundException.class) + public ResponseEntity<ProblemDetails> handleHttpResourceNotFoundException( + final HttpResouceNotFoundException httpResourceNotFoundException) { + final String errorMessage = "An error occurred. Sending of notification to VNFM failed with response: " + + HttpStatus.NOT_FOUND + ".\n" + httpResourceNotFoundException.getMessage(); + logger.error(errorMessage); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ProblemDetails().detail(errorMessage)); + } + + @ExceptionHandler(RestProcessingException.class) + public ResponseEntity<ProblemDetails> handleRestProcessingException( + final RestProcessingException restProcessingException) { + final String errorMessage = "An error occurred. Sending of notification to VNFM failed with response: " + + restProcessingException.getStatusCode() + ".\n" + restProcessingException.getMessage(); + logger.error(errorMessage); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ProblemDetails().detail(errorMessage)); + } + + @ExceptionHandler(InternalServerErrorException.class) + public ResponseEntity<ProblemDetails> handleInternalServerErrorException( + final InternalServerErrorException internalServerErrorException) { + logger.error(internalServerErrorException.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ProblemDetails().detail(internalServerErrorException.getMessage())); + } + + @ExceptionHandler(AuthenticationTypeNotSupportedException.class) + public ResponseEntity<ProblemDetails> handleAuthenticationTypeNotSupportedException( + final AuthenticationTypeNotSupportedException authenticationTypeNotSupportedException) { + logger.error(authenticationTypeNotSupportedException.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ProblemDetails().detail(authenticationTypeNotSupportedException.getMessage())); + } + + @ExceptionHandler(ConversionFailedException.class) + public ResponseEntity<ProblemDetails> handleConversionFailedException( + final ConversionFailedException conversionFailedException) { + logger.error(conversionFailedException.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ProblemDetails().detail(conversionFailedException.getMessage())); + } + + @ExceptionHandler(NotificationTypeNotSupportedException.class) + public ResponseEntity<ProblemDetails> handleNotificationTypeNotSupportedException( + final NotificationTypeNotSupportedException notificationTypeNotSupportedException) { + logger.error(notificationTypeNotSupportedException.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ProblemDetails().detail(notificationTypeNotSupportedException.getMessage())); + } + + @ExceptionHandler(SubscriptionNotFoundException.class) + public ResponseEntity<ProblemDetails> handleSubscriptionNotFoundException( + final SubscriptionNotFoundException subscriptionNotFoundException) { + logger.error(subscriptionNotFoundException.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ProblemDetails().detail(subscriptionNotFoundException.getMessage())); + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/InternalServerErrorException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/InternalServerErrorException.java new file mode 100644 index 0000000000..9dd7f1b7b2 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/InternalServerErrorException.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Exception for an ETSI Catalog Manager Request Failure + * + * @author gareth.roper@est.tech + */ +@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR) +public class InternalServerErrorException extends RuntimeException { + + private static final long serialVersionUID = 66864561537194516L; + + public InternalServerErrorException(final String message) { + super(message); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/NotificationTypeNotSupportedException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/NotificationTypeNotSupportedException.java new file mode 100644 index 0000000000..7716037342 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/NotificationTypeNotSupportedException.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Exception for an unsupported notification type + * + * @author Andrew Lamb (andrew.a.lamb@est.tech) + */ +@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR) +public class NotificationTypeNotSupportedException extends RuntimeException { + + private static final long serialVersionUID = 2939423208362066902L; + + public NotificationTypeNotSupportedException(final String message) { + super(message); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/Sol003PackageManagementControllerExceptionHandler.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/Sol003PackageManagementControllerExceptionHandler.java new file mode 100644 index 0000000000..9f97b4ae02 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/Sol003PackageManagementControllerExceptionHandler.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.ProblemDetails; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.Sol003PackageManagementController; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +/** + * Exception Handler for the Package Management Controller {@link Sol003PackageManagementController Sol003Controller} + * + * @author gareth.roper@est.tech + */ +@ControllerAdvice(assignableTypes = Sol003PackageManagementController.class) + +public class Sol003PackageManagementControllerExceptionHandler { + + @ExceptionHandler(EtsiCatalogManagerRequestFailureException.class) + public ResponseEntity<ProblemDetails> handleEtsiCatalogManagerRequestFailureException( + final EtsiCatalogManagerRequestFailureException etsiCatalogManagerRequestFailureException) { + final ProblemDetails problemDetails = new ProblemDetails(); + problemDetails.setDetail(etsiCatalogManagerRequestFailureException.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(problemDetails); + } + + @ExceptionHandler(EtsiCatalogManagerBadRequestException.class) + public ResponseEntity<ProblemDetails> handleEtsiCatalogManagerBadRequestFailureException( + final EtsiCatalogManagerBadRequestException etsiCatalogManagerBadRequestException) { + final ProblemDetails problemDetails = new ProblemDetails(); + problemDetails.setDetail(etsiCatalogManagerBadRequestException.getMessage()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(problemDetails); + } + + @ExceptionHandler(SubscriptionNotFoundException.class) + public ResponseEntity<ProblemDetails> handleSubscriptionNotFoundException( + final SubscriptionNotFoundException subscriptionNotFoundException) { + final ProblemDetails problemDetails = new ProblemDetails(); + problemDetails.setDetail(subscriptionNotFoundException.getMessage()); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(problemDetails); + } + + @ExceptionHandler(ConversionFailedException.class) + public ResponseEntity<ProblemDetails> handleConversionFailedException( + final ConversionFailedException conversionFailedException) { + final ProblemDetails problemDetails = new ProblemDetails(); + problemDetails.setDetail(conversionFailedException.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(problemDetails); + } + + @ExceptionHandler(VnfPkgConflictException.class) + public ResponseEntity<ProblemDetails> handleVnfPkgConflictException( + final VnfPkgConflictException vnfPkgConflictException) { + final ProblemDetails problemDetails = new ProblemDetails(); + problemDetails.setDetail(vnfPkgConflictException.getMessage()); + return ResponseEntity.status(HttpStatus.CONFLICT).body(problemDetails); + } + + @ExceptionHandler(VnfPkgNotFoundException.class) + public ResponseEntity<ProblemDetails> handleVnfPkgNotFoundException( + final VnfPkgNotFoundException vnfPkgNotFoundException) { + final ProblemDetails problemDetails = new ProblemDetails(); + problemDetails.setDetail(vnfPkgNotFoundException.getMessage()); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(problemDetails); + } + + @ExceptionHandler(VnfPkgBadRequestException.class) + public ResponseEntity<ProblemDetails> handleVnfPkgBadRequestException( + final VnfPkgBadRequestException vnfPkgBadRequestException) { + final ProblemDetails problemDetails = new ProblemDetails(); + problemDetails.setDetail(vnfPkgBadRequestException.getMessage()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(problemDetails); + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/SubscriptionNotFoundException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/SubscriptionNotFoundException.java new file mode 100644 index 0000000000..af409e7399 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/SubscriptionNotFoundException.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Exception for an ETSI Catalog Manager Request Failure + * + * @author gareth.roper@est.tech + */ +@ResponseStatus(code = HttpStatus.NOT_FOUND) +public class SubscriptionNotFoundException extends RuntimeException { + + private static final long serialVersionUID = 85268561453194516L; + + public SubscriptionNotFoundException(final String message) { + super(message); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/VnfPkgBadRequestException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/VnfPkgBadRequestException.java new file mode 100644 index 0000000000..5c318da89f --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/VnfPkgBadRequestException.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Exception for a Vnfpkg Bad Request failure, due to state of resource. + * + * @author andrew.a.lamb@est.tech + */ +@ResponseStatus(code = HttpStatus.BAD_REQUEST) +public class VnfPkgBadRequestException extends RuntimeException { + + private static final long serialVersionUID = 3301317418914258411L; + + public VnfPkgBadRequestException(final String message) { + super(message); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/VnfPkgConflictException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/VnfPkgConflictException.java new file mode 100644 index 0000000000..7cb7a0c860 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/VnfPkgConflictException.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Exception for a VnfPkg Conflict failures, due to state of resource. + * + * @author gareth.roper@est.tech + */ +@ResponseStatus(code = HttpStatus.CONFLICT) +public class VnfPkgConflictException extends RuntimeException { + + private static final long serialVersionUID = 26862444537198441L; + + public VnfPkgConflictException(final String message) { + super(message); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/VnfPkgNotFoundException.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/VnfPkgNotFoundException.java new file mode 100644 index 0000000000..5ed4847173 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/exceptions/VnfPkgNotFoundException.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Exception for VnfPkg Not Found Failures + * + * @author gareth.roper@est.tech + */ +@ResponseStatus(code = HttpStatus.NOT_FOUND) +public class VnfPkgNotFoundException extends RuntimeException { + + private static final long serialVersionUID = 26862444537198441L; + + public VnfPkgNotFoundException(final String message) { + super(message); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/AbstractNotificationServiceProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/AbstractNotificationServiceProvider.java new file mode 100644 index 0000000000..b6ba1ede95 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/AbstractNotificationServiceProvider.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.subscriptionmgmt; + +import static org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.VnfmHttpServiceProviderConfiguration.VNFM_ADAPTER_HTTP_SERVICE_PROVIDER_BEAN; +import java.nio.charset.StandardCharsets; +import org.apache.commons.codec.binary.Base64; +import org.onap.so.configuration.rest.BasicHttpHeadersProvider; +import org.onap.so.rest.service.HttpRestServiceProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * A base class that can be extended by classes for providing notification services. Provides common methods that will + * be useful to those classes. + * + * @author Waqas Ikram (waqas.ikram@est.tech) + * @author Andrew Lamb (andrew.a.lamb@est.tech) + */ +public abstract class AbstractNotificationServiceProvider { + + @Autowired + @Qualifier(VNFM_ADAPTER_HTTP_SERVICE_PROVIDER_BEAN) + private HttpRestServiceProvider httpRestServiceProvider; + + protected HttpRestServiceProvider getHttpRestServiceProvider() { + return httpRestServiceProvider; + } + + protected BasicHttpHeadersProvider getBasicHttpHeadersProviderWithBasicAuth(final String username, + final String password) { + final byte[] encodedAuth = getBasicAuth(username, password); + final String authHeader = "Basic " + new String(encodedAuth); + return new BasicHttpHeadersProvider(authHeader); + } + + protected byte[] getBasicAuth(final String username, final String password) { + final String auth = username + ":" + password; + return Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1)); + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/BasicAuthNotificationServiceProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/BasicAuthNotificationServiceProvider.java new file mode 100644 index 0000000000..ffe8529c93 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/BasicAuthNotificationServiceProvider.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.subscriptionmgmt; + +import static org.slf4j.LoggerFactory.getLogger; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication.AuthTypeEnum; +import org.onap.so.configuration.rest.HttpHeadersProvider; +import org.onap.so.rest.service.HttpRestServiceProvider; +import org.slf4j.Logger; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +/** + * Implementation of a NotificationServiceProvider which supports Basic Authentication + * + * @author Waqas Ikram (waqas.ikram@est.tech) + * @author Andrew Lamb (andrew.a.lamb@est.tech) + */ +@Service +public class BasicAuthNotificationServiceProvider extends AbstractNotificationServiceProvider + implements NotificationServiceProvider { + + private static final Logger logger = getLogger(BasicAuthNotificationServiceProvider.class); + + @Override + public boolean send(final Object notification, final SubscriptionsAuthentication subscriptionsAuthentication, + final String callbackUri) { + logger.info("Sending notification to uri: {}", callbackUri); + final HttpHeadersProvider httpHeadersProvider = + getBasicHttpHeadersProviderWithBasicAuth(subscriptionsAuthentication.getParamsBasic().getUserName(), + subscriptionsAuthentication.getParamsBasic().getPassword()); + final HttpRestServiceProvider httpRestServiceProvider = getHttpRestServiceProvider(); + + final ResponseEntity<Void> responseEntity = httpRestServiceProvider.postHttpRequest(notification, callbackUri, + httpHeadersProvider.getHttpHeaders(), Void.class); + if (responseEntity.getStatusCode().is2xxSuccessful()) { + logger.info("Notification sent successfully."); + return true; + } + + logger.error("Failed to send notification."); + return false; + } + + @Override + public AuthTypeEnum getAuthType() { + return AuthTypeEnum.BASIC; + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/NotificationManager.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/NotificationManager.java new file mode 100644 index 0000000000..82b1a7d4c3 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/NotificationManager.java @@ -0,0 +1,137 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.subscriptionmgmt; + +import static org.slf4j.LoggerFactory.getLogger; +import java.util.List; +import java.util.Optional; +import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgChangeNotification; +import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgOnboardingNotification; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.model.VnfPackageChangeNotification; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.model.VnfPackageOnboardingNotification; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.PkgmSubscriptionRequest; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication.AuthTypeEnum; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.AuthenticationTypeNotSupportedException; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.ConversionFailedException; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.NotificationTypeNotSupportedException; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.SubscriptionNotFoundException; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.convert.ConversionService; +import org.springframework.stereotype.Service; + +/** + * Manages package management subscription notifications to the VNFMs + * + * @author Andrew Lamb (andrew.a.lamb@est.tech) + * + */ +@Service +public class NotificationManager { + + private static final Logger logger = getLogger(NotificationManager.class); + private final ConversionService conversionService; + private final SubscriptionManager subscriptionManager; + private final NotificationServiceProviderFactory notificationServiceProviderFactory; + + @Autowired + public NotificationManager(final SubscriptionManager subscriptionManager, final ConversionService conversionService, + final NotificationServiceProviderFactory notificationServiceProviderFactory) { + this.subscriptionManager = subscriptionManager; + this.conversionService = conversionService; + this.notificationServiceProviderFactory = notificationServiceProviderFactory; + } + + /** + * Process a subscription notification. Checks for a subscription request stored in the adapter and if there is, it + * sends the notification to the subscribed vnfm. + * + * @param notification the notification to send to the vnfm + * @param subscriptionId the id of the subscription request + * @return true if the notification is successfully sent + */ + public boolean processSubscriptionNotification(final Object notification, final String subscriptionId) { + final Optional<PkgmSubscriptionRequest> optionalSubscription = + subscriptionManager.getSubscriptionRequest(subscriptionId); + if (optionalSubscription.isPresent()) { + final PkgmSubscriptionRequest subscriptionRequest = optionalSubscription.get(); + return notifyVnfm(subscriptionRequest, notification); + } + final String errorMessage = "No subscription found with subscriptionId " + subscriptionId + + ". Unable to forward notification to subscriber."; + logger.error(errorMessage); + throw new SubscriptionNotFoundException(errorMessage); + } + + private boolean notifyVnfm(final PkgmSubscriptionRequest subscriptionRequest, final Object notification) { + if (!(notification instanceof PkgOnboardingNotification) && !(notification instanceof PkgChangeNotification)) { + final String errorMessage = + "An error occurred. Notification type not supported for: " + notification.getClass(); + logger.error(errorMessage); + throw new NotificationTypeNotSupportedException(errorMessage); + } + + final SubscriptionsAuthentication subscriptionsAuthentication = subscriptionRequest.getAuthentication(); + final AuthTypeEnum authType = getAuthType(subscriptionsAuthentication.getAuthType()); + final NotificationServiceProvider sender = notificationServiceProviderFactory.getNotificationSender(authType); + + final Object vnfmNotificationObject = convertEtsiCatalogNotification(notification); + + if (sender.send(vnfmNotificationObject, subscriptionsAuthentication, subscriptionRequest.getCallbackUri())) { + logger.info("Notification delivered successfully {}", notification); + return true; + } + + logger.error("Failed to deliver notification."); + return false; + } + + private SubscriptionsAuthentication.AuthTypeEnum getAuthType(final List<AuthTypeEnum> authTypes) { + if (authTypes.contains(SubscriptionsAuthentication.AuthTypeEnum.TLS_CERT)) { + return SubscriptionsAuthentication.AuthTypeEnum.TLS_CERT; + } + if (authTypes.contains(SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS)) { + return SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS; + } + if (authTypes.contains(SubscriptionsAuthentication.AuthTypeEnum.BASIC)) { + return SubscriptionsAuthentication.AuthTypeEnum.BASIC; + } + final String errorMessage = + "An error occurred. No supported authentication type provided in subscription request."; + logger.error(errorMessage); + throw new AuthenticationTypeNotSupportedException(errorMessage); + } + + private Object convertEtsiCatalogNotification(final Object etsiCatalogNotification) { + logger.info("Converting notification:\n {}", etsiCatalogNotification); + if (conversionService.canConvert(etsiCatalogNotification.getClass(), VnfPackageOnboardingNotification.class)) { + return conversionService.convert(etsiCatalogNotification, VnfPackageOnboardingNotification.class); + } else if (conversionService.canConvert(etsiCatalogNotification.getClass(), + VnfPackageChangeNotification.class)) { + return conversionService.convert(etsiCatalogNotification, VnfPackageChangeNotification.class); + } + final String errorMessage = "An error occurred. Unable to convert provided notification object."; + logger.error(errorMessage + "\n" + etsiCatalogNotification); + throw new ConversionFailedException(errorMessage); + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/NotificationServiceProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/NotificationServiceProvider.java new file mode 100644 index 0000000000..2fc7e19eb6 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/NotificationServiceProvider.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.subscriptionmgmt; + +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication.AuthTypeEnum; + +/** + * Interface which lays out requirements for a Notification Service Provider + * + * @author Waqas Ikram (waqas.ikram@est.tech) + * @author Andrew Lamb (andrew.a.lamb@est.tech) + */ +public interface NotificationServiceProvider { + + /** + * Method to send a notification to a uri, given the subscription authentication + * + * @param notification The notification to send + * @param subscriptionsAuthentication Object containing the authentication details + * @param callbackUri The uri to send the notification to + * @return true if notification is delivered successfully, otherwise false + */ + boolean send(final Object notification, final SubscriptionsAuthentication subscriptionsAuthentication, + final String callbackUri); + + /** + * Method to get the supported authorization type of the service provider + * + * @return the supported AuthTypeEnum + */ + AuthTypeEnum getAuthType(); + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/NotificationServiceProviderFactory.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/NotificationServiceProviderFactory.java new file mode 100644 index 0000000000..2b8e818c9c --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/NotificationServiceProviderFactory.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.subscriptionmgmt; + +import static org.slf4j.LoggerFactory.getLogger; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication.AuthTypeEnum; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.AuthenticationTypeNotSupportedException; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Factory to provide a notification services + * + * @author Waqas Ikram (waqas.ikram@est.tech) + * @author Andrew Lamb (andrew.a.lamb@est.tech) + */ +@Component +public class NotificationServiceProviderFactory { + + private static final Logger logger = getLogger(NotificationServiceProviderFactory.class); + private static final Map<AuthTypeEnum, NotificationServiceProvider> CACHE = new HashMap<>(); + + @Autowired + public NotificationServiceProviderFactory(final List<NotificationServiceProvider> services) { + for (final NotificationServiceProvider notificationServiceProvider : services) { + logger.debug("Adding {} of type {} to cache", notificationServiceProvider.getClass().getCanonicalName(), + notificationServiceProvider.getAuthType()); + CACHE.put(notificationServiceProvider.getAuthType(), notificationServiceProvider); + } + } + + /** + * Get a notification service for a given authorization type + * + * @param type the type of authentication required + * @return the notification service + */ + public NotificationServiceProvider getNotificationSender(final AuthTypeEnum type) { + final NotificationServiceProvider service = CACHE.get(type); + if (service == null) { + throw new AuthenticationTypeNotSupportedException("Unknown type: " + type); + } + return service; + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/OAuthNotificationServiceProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/OAuthNotificationServiceProvider.java new file mode 100644 index 0000000000..81dc743a22 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/OAuthNotificationServiceProvider.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.subscriptionmgmt; + +import static org.slf4j.LoggerFactory.getLogger; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication.AuthTypeEnum; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.InternalServerErrorException; +import org.onap.so.configuration.rest.BasicHttpHeadersProvider; +import org.onap.so.configuration.rest.HttpHeadersProvider; +import org.onap.so.rest.service.HttpRestServiceProvider; +import org.slf4j.Logger; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * @author Andrew Lamb (andrew.a.lamb@est.tech) + * + */ +@Service +public class OAuthNotificationServiceProvider extends AbstractNotificationServiceProvider + implements NotificationServiceProvider { + + private static final Logger logger = getLogger(OAuthNotificationServiceProvider.class); + + @Override + public boolean send(final Object notification, final SubscriptionsAuthentication subscriptionsAuthentication, + final String callbackUri) { + logger.info("Sending notification to uri: {}", callbackUri); + logger.info("Object: {}", notification); + final String token = getAccessToken(subscriptionsAuthentication); + + if (token == null) { + logger.error("Failed to get access token"); + return false; + } + + final HttpHeadersProvider httpHeadersProvider = getHttpHeadersProvider(token); + final HttpRestServiceProvider httpRestServiceProvider = getHttpRestServiceProvider(); + final ResponseEntity<Void> responseEntity = httpRestServiceProvider.postHttpRequest(notification, callbackUri, + httpHeadersProvider.getHttpHeaders(), Void.class); + if (responseEntity.getStatusCode().is2xxSuccessful()) { + logger.info("Notification sent successfully."); + return true; + } + + logger.error("Failed to send notification."); + return false; + } + + @Override + public AuthTypeEnum getAuthType() { + return AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS; + } + + private BasicHttpHeadersProvider getHttpHeadersProvider(final String token) { + final String authHeader = "Bearer " + token; + return new BasicHttpHeadersProvider(authHeader); + } + + private String getAccessToken(final SubscriptionsAuthentication subscriptionsAuthentication) { + logger.info("Requesting Access Token."); + + final String tokenEndpoint = subscriptionsAuthentication.getParamsOauth2ClientCredentials().getTokenEndpoint(); + + final HttpHeadersProvider httpHeadersProvider = getBasicHttpHeadersProviderWithBasicAuth( + subscriptionsAuthentication.getParamsOauth2ClientCredentials().getClientId(), + subscriptionsAuthentication.getParamsOauth2ClientCredentials().getClientPassword()); + + final HttpRestServiceProvider httpRestServiceProvider = getHttpRestServiceProvider(); + final ResponseEntity<OAuthTokenResponse> responseEntity = httpRestServiceProvider.postHttpRequest(null, + tokenEndpoint, httpHeadersProvider.getHttpHeaders(), OAuthTokenResponse.class); + if (responseEntity.getStatusCode().is2xxSuccessful()) { + if (responseEntity.getBody() != null) { + logger.info("Returning Access Token."); + return responseEntity.getBody().getAccessToken(); + } + } + + final String errorMessage = "An error occurred. Unable to retrieve OAuth Token from VNFM for notification."; + logger.error(errorMessage); + throw new InternalServerErrorException(errorMessage); + } + + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/OAuthTokenResponse.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/OAuthTokenResponse.java new file mode 100644 index 0000000000..3e6f7bde2b --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/OAuthTokenResponse.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.subscriptionmgmt; + +import java.io.Serializable; +import javax.xml.bind.annotation.XmlElement; +import com.google.gson.annotations.SerializedName; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * @author Andrew Lamb (andrew.a.lamb@est.tech) + */ +public class OAuthTokenResponse implements Serializable { + + private static final long serialVersionUID = -6455742984985959926L; + + @XmlElement(name = "access_token") + @SerializedName("access_token") + private String accessToken; + + /** + * Get the Accees Token + * + * @return the Access Token + */ + public String getAccessToken() { + return accessToken; + } + + /** + * Set the Access Token + * + * @param accessToken + */ + public void setAccessToken(final String accessToken) { + this.accessToken = accessToken; + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/SubscriptionManager.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/SubscriptionManager.java new file mode 100644 index 0000000000..edae41525e --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/SubscriptionManager.java @@ -0,0 +1,209 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.subscriptionmgmt; + +import static org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.SubscriptionAuthentication.AuthTypeEnum.BASIC; +import static org.slf4j.LoggerFactory.getLogger; +import java.net.URI; +import java.security.GeneralSecurityException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.onap.so.adapters.etsi.sol003.adapter.common.VnfmAdapterUrlProvider; +import org.onap.so.adapters.etsisol003adapter.pkgm.cache.PkgmCacheServiceProvider; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.EtsiCatalogServiceProvider; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.BasicAuth; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdmSubscription; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscription; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.InlineResponse201; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.PkgmSubscriptionRequest; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsLinks; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.VnfPackagesLinksSelf; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.ConversionFailedException; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.InternalServerErrorException; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.SubscriptionNotFoundException; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.convert.ConversionService; +import org.springframework.stereotype.Service; + +/** + * Manages package management subscriptions from the VNFMs + * + * @author Ronan Kenny (ronan.kenny@est.tech) + * @author Gareth Roper (gareth.roper@est.tech) + */ +@Service +public class SubscriptionManager { + + private static final Logger logger = getLogger(SubscriptionManager.class); + private final PkgmCacheServiceProvider packageManagementCacheServiceProvider; + private final ConversionService conversionService; + private final EtsiCatalogServiceProvider etsiCatalogServiceProvider; + private final VnfmAdapterUrlProvider vnfmAdapterUrlProvider; + + @Autowired + public SubscriptionManager(final PkgmCacheServiceProvider packageManagementCacheServiceProvider, + final ConversionService conversionService, final EtsiCatalogServiceProvider etsiCatalogServiceProvider, + final VnfmAdapterUrlProvider vnfmAdapterUrlProvider) { + this.packageManagementCacheServiceProvider = packageManagementCacheServiceProvider; + this.conversionService = conversionService; + this.etsiCatalogServiceProvider = etsiCatalogServiceProvider; + this.vnfmAdapterUrlProvider = vnfmAdapterUrlProvider; + } + + public Optional<InlineResponse201> createSubscription(final PkgmSubscriptionRequest pkgmSubscriptionRequest) + throws GeneralSecurityException { + + final org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest etsiCatalogManagerSubscriptionRequest = + buildEtsiCatalogManagerPkgmSubscriptionRequest(pkgmSubscriptionRequest); + + final Optional<PkgmSubscription> optionalEtsiCatalogManagerSubscription = + etsiCatalogServiceProvider.postSubscription(etsiCatalogManagerSubscriptionRequest); + + if (optionalEtsiCatalogManagerSubscription.isPresent()) { + final PkgmSubscription etsiCatalogManagerSubscription = optionalEtsiCatalogManagerSubscription.get(); + logger.debug("postPkgmSubscriptionRequest Response SubscriptionId: {}", + Objects.requireNonNull(etsiCatalogManagerSubscription.getId())); + final String subscriptionId = etsiCatalogManagerSubscription.getId(); + + packageManagementCacheServiceProvider.addSubscription(subscriptionId, pkgmSubscriptionRequest); + + final InlineResponse201 response = new InlineResponse201(); + response.setId(subscriptionId); + response.setFilter(pkgmSubscriptionRequest.getFilter()); + response.setCallbackUri(vnfmAdapterUrlProvider.getSubscriptionUriString(subscriptionId)); + response.setLinks(new SubscriptionsLinks() + .self(new VnfPackagesLinksSelf().href(getSubscriptionUri(subscriptionId).toString()))); + + return Optional.of(response); + } + throw new InternalServerErrorException( + "Received empty response from POST to ETSI Catalog Manager Subscription Endpoint."); + } + + public Optional<String> getSubscriptionId(final PkgmSubscriptionRequest pkgmSubscriptionRequest) { + return packageManagementCacheServiceProvider.getSubscriptionId(pkgmSubscriptionRequest); + } + + public Optional<InlineResponse201> getSubscription(final String subscriptionId) { + + logger.debug("Checking if subscrition with id: {} exists in ETSI Catalog Manager", subscriptionId); + final Optional<NsdmSubscription> etsiCatalogSubscriptionOption = + etsiCatalogServiceProvider.getSubscription(subscriptionId); + + if (!etsiCatalogSubscriptionOption.isPresent()) { + logger.debug("Unable to find subscription in ETSI Catalog Manager using id: {}", subscriptionId); + if (packageManagementCacheServiceProvider.getSubscription(subscriptionId).isPresent()) { + logger.debug("will remove subcription with id: {} from local cache", subscriptionId); + packageManagementCacheServiceProvider.deleteSubscription(subscriptionId); + } + } + + final Optional<PkgmSubscriptionRequest> optional = + packageManagementCacheServiceProvider.getSubscription(subscriptionId); + if (optional.isPresent()) { + final PkgmSubscriptionRequest subscription = optional.get(); + return Optional.of(getInlineResponse2002(subscriptionId, subscription)); + } + return Optional.empty(); + } + + public List<InlineResponse201> getSubscriptions() { + final Map<String, PkgmSubscriptionRequest> subscriptions = + packageManagementCacheServiceProvider.getSubscriptions(); + final List<InlineResponse201> response = new ArrayList<>(); + subscriptions.forEach((key, value) -> { + final Optional<InlineResponse201> optional = getSubscription(key); + if (optional.isPresent()) { + response.add(optional.get()); + } + }); + return response; + } + + public boolean deleteSubscription(final String subscriptionId) { + if (packageManagementCacheServiceProvider.getSubscription(subscriptionId).isPresent()) { + try { + if (etsiCatalogServiceProvider.deleteSubscription(subscriptionId)) { + return packageManagementCacheServiceProvider.deleteSubscription(subscriptionId); + } + } catch (final SubscriptionNotFoundException subscriptionNotFoundException) { + logger.error( + "Unable to find subscription in ETSI Catalog Manager using id: {} will delete it from local cache", + subscriptionId); + return packageManagementCacheServiceProvider.deleteSubscription(subscriptionId); + } + } + return false; + } + + public URI getSubscriptionUri(final String subscriptionId) { + return vnfmAdapterUrlProvider.getSubscriptionUri(subscriptionId); + } + + public Optional<PkgmSubscriptionRequest> getSubscriptionRequest(final String subscriptionId) { + return packageManagementCacheServiceProvider.getSubscription(subscriptionId); + } + + private InlineResponse201 getInlineResponse2002(final String id, final PkgmSubscriptionRequest subscription) { + return new InlineResponse201().id(id).filter(subscription.getFilter()) + .callbackUri(subscription.getCallbackUri()); + } + + private org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest buildEtsiCatalogManagerPkgmSubscriptionRequest( + final PkgmSubscriptionRequest pkgmSubscriptionRequest) throws GeneralSecurityException { + + final org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest etsiCatalogManagerSubscriptionRequest; + try { + etsiCatalogManagerSubscriptionRequest = conversionService.convert(pkgmSubscriptionRequest, + org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest.class); + } catch (final org.springframework.core.convert.ConversionException conversionException) { + logger.error(conversionException.getMessage()); + throw new ConversionFailedException( + "Could not convert Sol003 PkgmSubscriptionRequest to ETSI-Catalog Manager PkgmSubscriptionRequest"); + } catch (final Exception exception) { + logger.error(exception.getMessage()); + throw new InternalServerErrorException( + "Could not convert Sol003 PkgmSubscriptionRequest to ETSI-Catalog Manager PkgmSubscriptionRequest"); + } + + if (etsiCatalogManagerSubscriptionRequest != null) { + etsiCatalogManagerSubscriptionRequest + .setCallbackUri(vnfmAdapterUrlProvider.getEtsiSubscriptionNotificationBaseUrl()); + + final ImmutablePair<String, String> immutablePair = vnfmAdapterUrlProvider.getDecryptAuth(); + if (!immutablePair.equals(ImmutablePair.nullPair())) { + etsiCatalogManagerSubscriptionRequest.setAuthentication( + new org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.SubscriptionAuthentication() + .addAuthTypeItem(BASIC).paramsBasic(new BasicAuth().userName(immutablePair.getLeft()) + .password(immutablePair.getRight()))); + } + return etsiCatalogManagerSubscriptionRequest; + } + throw new ConversionFailedException( + "Failed to convert Sol003 PkgmSubscriptionRequest to ETSI-Catalog Manager PkgmSubscriptionRequest"); + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/TlsNotificationServiceProvider.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/TlsNotificationServiceProvider.java new file mode 100644 index 0000000000..69ff5da3ec --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/main/java/org/onap/so/adapters/etsisol003adapter/pkgm/subscriptionmgmt/TlsNotificationServiceProvider.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ +package org.onap.so.adapters.etsisol003adapter.pkgm.subscriptionmgmt; + +import static org.slf4j.LoggerFactory.getLogger; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication.AuthTypeEnum; +import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.AuthenticationTypeNotSupportedException; +import org.slf4j.Logger; +import org.springframework.stereotype.Service; + +/** + * + * @author Waqas Ikram (waqas.ikram@est.tech) + * @author Andrew Lamb (andrew.a.lamb@est.tech) + */ +@Service +public class TlsNotificationServiceProvider extends AbstractNotificationServiceProvider + implements NotificationServiceProvider { + + private static final Logger logger = getLogger(TlsNotificationServiceProvider.class); + + @Override + public boolean send(final Object notification, final SubscriptionsAuthentication subscriptionsAuthentication, + final String callbackUri) { + final String errorMessage = "An error occurred. Authentication type " + + subscriptionsAuthentication.getAuthType().toString() + " not currently supported."; + logger.error(errorMessage); + throw new AuthenticationTypeNotSupportedException(errorMessage); + } + + + @Override + public AuthTypeEnum getAuthType() { + return AuthTypeEnum.TLS_CERT; + } + + + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/EtsiSubscriptionNotificationControllerTest.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/EtsiSubscriptionNotificationControllerTest.java new file mode 100644 index 0000000000..efe6891f1e --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/EtsiSubscriptionNotificationControllerTest.java @@ -0,0 +1,591 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.rest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.onap.so.adapters.etsi.sol003.adapter.common.CommonConstants.ETSI_SUBSCRIPTION_NOTIFICATION_CONTROLLER_BASE_URL; +import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE; +import static org.springframework.test.annotation.DirtiesContext.ClassMode.BEFORE_CLASS; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.header; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.jsonPath; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; +import java.net.URI; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.NOTIFICATIONLINKSERIALIZER; +import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgChangeNotification; +import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgOnboardingNotification; +import org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model.PkgmLinks; +import org.onap.so.adapters.etsisol003adapter.pkgm.JSON; +import org.onap.so.adapters.etsisol003adapter.pkgm.PackageManagementConstants; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.ProblemDetails; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.model.VnfPackageChangeNotification; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.model.VnfPackageOnboardingNotification; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.PkgmSubscriptionRequest; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthenticationParamsBasic; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthenticationParamsOauth2ClientCredentials; +import org.onap.so.configuration.rest.BasicHttpHeadersProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestTemplate; +import com.google.gson.Gson; + +/** + * @author Andrew Lamb (andrew.a.lamb@est.tech) + * + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +@DirtiesContext(classMode = BEFORE_CLASS) +public class EtsiSubscriptionNotificationControllerTest { + + @LocalServerPort + private int port; + + private static final URI CALLBACK_URI = URI.create("http://test_callback_uri/notification"); + private static final String TOKEN_ENDPOINT = "http://test_token_endpoint_uri/"; + private static final String TOKEN = "dXNlcm5hbWU6cGFzc3dvcmQ=......"; + private static final String JSON_TOKEN = "{\"access_token\":\"" + TOKEN + "\"}"; + private static final String LOCALHOST_URL = "http://localhost:"; + private static final String NOTIFICATION_BASE_URL = + ETSI_SUBSCRIPTION_NOTIFICATION_CONTROLLER_BASE_URL + "/notification"; + private static final String USERNAME = "username"; + private static final String PASSWORD = "password"; + private static final String EXPECTED_BASIC_AUTHORIZATION = "Basic dXNlcm5hbWU6cGFzc3dvcmQ="; + private static final String EXPECTED_OAUTH_AUTHORIZATION = "Bearer " + TOKEN; + private static final String NOTIFICATION_ID = "NOTIFICATION_ID"; + private static final String SUBSCRIPTION_ID = "SUBSCRIPTION_ID"; + private static final String TIME_STAMP_STRING_EXPECTED_FROM_ETSI_CATALOG = "2020-01-01 01:01:01"; + private static final java.time.LocalDateTime TIMESTAMP = java.time.LocalDateTime.of(2020, 1, 1, 1, 1, 1, 1); + private static final String VNFPKG_ID = UUID.randomUUID().toString(); + private static final String VNFD_ID = UUID.randomUUID().toString(); + private static final String EXPECTED_VNF_PACKAGE_HREF = + "https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/vnfpkgm/v1/vnf_packages/" + VNFPKG_ID; + private static final String EXPECTED_SUBSCRIPTION_HREF = + "https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/vnfpkgm/v1/subscriptions/" + SUBSCRIPTION_ID; + + + private BasicHttpHeadersProvider basicHttpHeadersProvider; + + @Autowired + @Qualifier(CONFIGURABLE_REST_TEMPLATE) + private RestTemplate restTemplate; + private MockRestServiceServer mockRestServiceServer; + + private TestRestTemplate testRestTemplate; + + @Autowired + private CacheManager cacheServiceProvider; + private Cache cache; + + @Before + public void setUp() { + mockRestServiceServer = MockRestServiceServer.bindTo(restTemplate).build(); + basicHttpHeadersProvider = new BasicHttpHeadersProvider(); + cache = cacheServiceProvider.getCache(PackageManagementConstants.PACKAGE_MANAGEMENT_SUBSCRIPTION_CACHE); + cache.clear(); + + final Gson gson = JSON.createGson().registerTypeAdapter(LocalDateTime.class, + new EtsiSubscriptionNotificationController.LocalDateTimeTypeAdapter()).create(); + testRestTemplate = new TestRestTemplate( + new RestTemplateBuilder().additionalMessageConverters(new GsonHttpMessageConverter(gson))); + } + + + @After + public void tearDown() { + mockRestServiceServer.reset(); + cache.clear(); + } + + @Test + public void testSubscriptionNotificationEndPoint_ReturnsNoContent() { + final ResponseEntity<?> response = sendHttpGet(NOTIFICATION_BASE_URL); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); + } + + @Test + public void testOnboardingNotificationSentOnToVnfmCallbackUri_SubscriptionRequestInCache_Success() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgOnboardingNotification notification = buildPkgOnboardingNotification(); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andExpect(jsonPath("$.id").value(NOTIFICATION_ID)) + .andExpect(jsonPath("$.notificationType") + .value(VnfPackageOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION + .toString())) + .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID)) + .andExpect(jsonPath("$.timeStamp").value(TIME_STAMP_STRING_EXPECTED_FROM_ETSI_CATALOG)) + .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID)).andExpect(jsonPath("$.vnfdId").value(VNFD_ID)) + .andExpect(jsonPath("$._links") + .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF))) + .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess()); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); + } + + @Test + public void testOnboardingNotificationNotSentOnToVnfmCallbackUri_SubscriptionRequestNotInCache_Fail() { + final PkgOnboardingNotification notification = buildPkgOnboardingNotification(); + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "No subscription found with subscriptionId " + SUBSCRIPTION_ID + + ". Unable to forward notification to subscriber."; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + @Test + public void testOnboardingNotificationSentOnToVnfmCallbackUri_BadRequestResponseFromCallbackUri_Fail() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgOnboardingNotification notification = buildPkgOnboardingNotification(); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andRespond(withStatus(HttpStatus.BAD_REQUEST)); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "An error occurred. Sending of notification to VNFM failed with response: " + + HttpStatus.BAD_REQUEST + ".\n" + "No result found for given url: " + CALLBACK_URI; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + @Test + public void testOnboardingNotificationSentOnToVnfmCallbackUri_301MovedPermanentlyResponseFromCallbackUri_Fail() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgOnboardingNotification notification = buildPkgOnboardingNotification(); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andRespond(withStatus(HttpStatus.MOVED_PERMANENTLY)); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "An error occurred. Sending of notification to VNFM failed."; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + @Test + public void testOnboardingNotificationSentOnToVnfmCallbackUri_NotFoundResponseFromCallbackUri_Fail() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgOnboardingNotification notification = buildPkgOnboardingNotification(); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andRespond(withStatus(HttpStatus.NOT_FOUND)); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "An error occurred. Sending of notification to VNFM failed with response: " + + HttpStatus.NOT_FOUND + ".\n" + "No result found for given url: " + CALLBACK_URI; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + @Test + public void testOnboardingNotificationSentOnToVnfmCallbackUri_InternalServerErrorResponseFromCallbackUri_Fail() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgOnboardingNotification notification = buildPkgOnboardingNotification(); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "An error occurred. Sending of notification to VNFM failed with response: " + + HttpStatus.INTERNAL_SERVER_ERROR.value() + ".\n" + "Unable to invoke HTTP POST using URL: " + + CALLBACK_URI; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + @Test + public void testChangeNotificationSentOnToVnfmCallbackUri_SubscriptionRequestInCache_Success() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgChangeNotification notification = buildPkgChangeNotification(); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andExpect(jsonPath("$.id").value(NOTIFICATION_ID)) + .andExpect(jsonPath("$.notificationType").value( + VnfPackageChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.getValue())) + .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID)) + .andExpect(jsonPath("$.timeStamp").value(TIME_STAMP_STRING_EXPECTED_FROM_ETSI_CATALOG)) + .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID)).andExpect(jsonPath("$.vnfdId").value(VNFD_ID)) + .andExpect( + jsonPath("$.changeType").value(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE.toString())) + .andExpect(jsonPath("$.operationalState") + .value(PkgChangeNotification.OperationalStateEnum.ENABLED.toString())) + .andExpect(jsonPath("$._links") + .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF))) + .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess()); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); + } + + @Test + public void testChangeNotificationNotSentOnToVnfmCallbackUri_SubscriptionRequestNotInCache_Fail() { + final PkgChangeNotification notification = buildPkgChangeNotification(); + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "No subscription found with subscriptionId " + SUBSCRIPTION_ID + + ". Unable to forward notification to subscriber."; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + @Test + public void testChangeNotificationSentOnToVnfmCallbackUri_BadRequestResponseFromCallbackUri_Fail() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgChangeNotification notification = buildPkgChangeNotification(); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andRespond(withStatus(HttpStatus.BAD_REQUEST)); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "An error occurred. Sending of notification to VNFM failed with response: " + + HttpStatus.BAD_REQUEST + ".\n" + "No result found for given url: " + CALLBACK_URI; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + @Test + public void testChangeNotificationSentOnToVnfmCallbackUri_NotFoundResponseFromCallbackUri_Fail() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgChangeNotification notification = buildPkgChangeNotification(); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andRespond(withStatus(HttpStatus.NOT_FOUND)); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "An error occurred. Sending of notification to VNFM failed with response: " + + HttpStatus.NOT_FOUND + ".\n" + "No result found for given url: " + CALLBACK_URI; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + @Test + public void testChangeNotificationSentOnToVnfmCallbackUri_InternalServerErrorResponseFromCallbackUri_Fail() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgChangeNotification notification = buildPkgChangeNotification(); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "An error occurred. Sending of notification to VNFM failed with response: " + + HttpStatus.INTERNAL_SERVER_ERROR.value() + ".\n" + "Unable to invoke HTTP POST using URL: " + + CALLBACK_URI; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + @Test + public void testNotificationSentOnToVnfm_BasicAuthUserPasswordAuthorized_Success() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgOnboardingNotification notification = buildPkgOnboardingNotification(); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andExpect(jsonPath("$.id").value(NOTIFICATION_ID)) + .andExpect(jsonPath("$.notificationType") + .value(VnfPackageOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION + .toString())) + .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID)) + .andExpect(jsonPath("$.timeStamp").value(TIME_STAMP_STRING_EXPECTED_FROM_ETSI_CATALOG)) + .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID)).andExpect(jsonPath("$.vnfdId").value(VNFD_ID)) + .andExpect(jsonPath("$._links") + .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF))) + .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess()); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); + } + + @Test + public void testNotificationSentOnToVnfm_BasicAuthUserPasswordNotAuthorized_Fail() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.BASIC); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgChangeNotification notification = buildPkgChangeNotification(); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)) + .andRespond(withStatus(HttpStatus.UNAUTHORIZED)); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "An error occurred. Sending of notification to VNFM failed with response: " + + HttpStatus.UNAUTHORIZED.value() + ".\n" + "Unable to invoke HTTP POST using URL: " + CALLBACK_URI; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + @Test + public void testNotificationSentOnToVnfm_OAuthAuthorized_Success() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgChangeNotification notification = buildPkgChangeNotification(); + + mockRestServiceServer.expect(requestTo(TOKEN_ENDPOINT)).andExpect(method(HttpMethod.POST)) + .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)) + .andRespond(withSuccess(JSON_TOKEN, MediaType.APPLICATION_JSON)); + + mockRestServiceServer.expect(requestTo(CALLBACK_URI)).andExpect(method(HttpMethod.POST)) + .andExpect(header("Authorization", EXPECTED_OAUTH_AUTHORIZATION)) + .andExpect(jsonPath("$.id").value(NOTIFICATION_ID)) + .andExpect(jsonPath("$.notificationType").value( + VnfPackageChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.toString())) + .andExpect(jsonPath("$.subscriptionId").value(SUBSCRIPTION_ID)) + .andExpect(jsonPath("$.timeStamp").value(TIME_STAMP_STRING_EXPECTED_FROM_ETSI_CATALOG)) + .andExpect(jsonPath("$.vnfPkgId").value(VNFPKG_ID)).andExpect(jsonPath("$.vnfdId").value(VNFD_ID)) + .andExpect( + jsonPath("$.changeType").value(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE.toString())) + .andExpect(jsonPath("$.operationalState") + .value(PkgChangeNotification.OperationalStateEnum.ENABLED.toString())) + .andExpect(jsonPath("$._links") + .value(buildPkgmLinks(EXPECTED_VNF_PACKAGE_HREF, EXPECTED_SUBSCRIPTION_HREF))) + .andRespond(withSuccess()); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); + } + + @Test + public void testNotificationSentOnToVnfm_OAuthTokenNotReceived_Fail() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgChangeNotification notification = buildPkgChangeNotification(); + + mockRestServiceServer.expect(requestTo(TOKEN_ENDPOINT)).andExpect(method(HttpMethod.POST)) + .andExpect(header("Authorization", EXPECTED_BASIC_AUTHORIZATION)).andRespond(withSuccess()); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "An error occurred. Unable to retrieve OAuth Token from VNFM for notification."; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + @Test + public void testNotificationSentOnToVnfm_TLSCertNotYetSupported_Fail() { + final PkgmSubscriptionRequest subscriptionRequest = + buildPkgmSubscriptionRequest(SubscriptionsAuthentication.AuthTypeEnum.TLS_CERT); + cache.put(SUBSCRIPTION_ID, subscriptionRequest); + final PkgChangeNotification notification = buildPkgChangeNotification(); + + final ResponseEntity<?> response = sendHttpPost(notification); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + + final ProblemDetails problemDetails = (ProblemDetails) response.getBody(); + final String errorMessage = "An error occurred. Authentication type " + + subscriptionRequest.getAuthentication().getAuthType().toString() + " not currently supported."; + + assertEquals(errorMessage, problemDetails.getDetail()); + } + + private PkgOnboardingNotification buildPkgOnboardingNotification() { + final PkgOnboardingNotification notification = new PkgOnboardingNotification(); + notification.setId(NOTIFICATION_ID); + notification + .setNotificationType(PkgOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION); + notification.setSubscriptionId(SUBSCRIPTION_ID); + notification.setTimeStamp(TIMESTAMP); + notification.setVnfPkgId(VNFPKG_ID); + notification.setVnfdId(VNFD_ID); + notification.setLinks(buildPkgmLinks()); + return notification; + } + + private PkgChangeNotification buildPkgChangeNotification() { + final PkgChangeNotification notification = new PkgChangeNotification(); + notification.setId(NOTIFICATION_ID); + notification.setNotificationType(PkgChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION); + notification.setSubscriptionId(SUBSCRIPTION_ID); + notification.setTimeStamp(TIMESTAMP); + notification.setVnfPkgId(VNFPKG_ID); + notification.setVnfdId(VNFD_ID); + notification.setChangeType(PkgChangeNotification.ChangeTypeEnum.OP_STATE_CHANGE); + notification.setOperationalState(PkgChangeNotification.OperationalStateEnum.ENABLED); + notification.setLinks(buildPkgmLinks()); + return notification; + } + + private PkgmLinks buildPkgmLinks() { + return buildPkgmLinks("vnf_package_href", "subscription_href"); + } + + private PkgmLinks buildPkgmLinks(final String vnfPkgHref, final String subscriptionHref) { + return new PkgmLinks().vnfPackage(new NOTIFICATIONLINKSERIALIZER().href(vnfPkgHref)) + .subscription(new NOTIFICATIONLINKSERIALIZER().href(subscriptionHref)); + } + + private PkgmSubscriptionRequest buildPkgmSubscriptionRequest( + final SubscriptionsAuthentication.AuthTypeEnum authTypeEnum) { + final PkgmSubscriptionRequest subscriptionRequest = new PkgmSubscriptionRequest(); + subscriptionRequest.setCallbackUri(CALLBACK_URI.toString()); + subscriptionRequest.setAuthentication(buildSubscriptionsAuthentication(authTypeEnum)); + return subscriptionRequest; + } + + // TODO update for auth types other than basicAuth + private SubscriptionsAuthentication buildSubscriptionsAuthentication( + final SubscriptionsAuthentication.AuthTypeEnum authTypeEnum) { + final SubscriptionsAuthentication subscriptionsAuthentication = new SubscriptionsAuthentication(); + final List<SubscriptionsAuthentication.AuthTypeEnum> authTypes = new ArrayList<>(); + authTypes.add(authTypeEnum); + subscriptionsAuthentication.setAuthType(authTypes); + if (authTypeEnum == SubscriptionsAuthentication.AuthTypeEnum.TLS_CERT) { + // TODO: remove basic params and code for TLS + final SubscriptionsAuthenticationParamsBasic basicParams = + new SubscriptionsAuthenticationParamsBasic().userName(USERNAME).password(PASSWORD); + subscriptionsAuthentication.setParamsBasic(basicParams); + } else if (authTypeEnum == SubscriptionsAuthentication.AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS) { + final SubscriptionsAuthenticationParamsOauth2ClientCredentials oathParams = + new SubscriptionsAuthenticationParamsOauth2ClientCredentials().clientId(USERNAME) + .clientPassword(PASSWORD).tokenEndpoint(TOKEN_ENDPOINT); + subscriptionsAuthentication.setParamsOauth2ClientCredentials(oathParams); + } else { + final SubscriptionsAuthenticationParamsBasic basicParams = + new SubscriptionsAuthenticationParamsBasic().userName(USERNAME).password(PASSWORD); + subscriptionsAuthentication.setParamsBasic(basicParams); + } + + return subscriptionsAuthentication; + } + + private <T> ResponseEntity<ProblemDetails> sendHttpPost(final T notification) { + final String testURL = LOCALHOST_URL + port + NOTIFICATION_BASE_URL; + final HttpEntity<?> request = new HttpEntity<>(notification, basicHttpHeadersProvider.getHttpHeaders()); + return testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.POST, request, + ProblemDetails.class); + } + + private ResponseEntity<Void> sendHttpGet(final String url) { + final String testURL = LOCALHOST_URL + port + url; + final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders()); + return testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.GET, request, Void.class); + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementControllerTest.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementControllerTest.java new file mode 100644 index 0000000000..10e4ea3a58 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementControllerTest.java @@ -0,0 +1,677 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.rest; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.onap.so.adapters.etsi.sol003.adapter.common.CommonConstants.PACKAGE_MANAGEMENT_BASE_URL; +import static org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_REST_TEMPLATE_BEAN; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.Checksum; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.ProblemDetails; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.UriLink; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VNFPKGMLinkSerializer; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPackageArtifactInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPackageSoftwareImageInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.InlineResponse2001; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.VnfPackagesLinks; +import org.onap.so.configuration.rest.BasicHttpHeadersProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestTemplate; +import com.google.gson.Gson; + +/** + * @author gareth.roper@est.tech + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +public class Sol003PackageManagementControllerTest { + + @LocalServerPort + private int port; + + @Autowired + @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) + private RestTemplate restTemplate; + + @Autowired + private TestRestTemplate testRestTemplate; + + private static final String VNF_PACKAGE_ID = "myVnfPackageId"; + private static final String ARTIFACT_PATH = "myArtifactPath"; + private static final String MSB_BASE_URL = "http://msb-iag.onap:80/api/vnfpkgm/v1/vnf_packages"; + private static final String VNFPKGM_BASE_URL = PACKAGE_MANAGEMENT_BASE_URL + "/vnf_packages"; + private static final String localhostUrl = "http://localhost:"; + private static final String GET_VNF_PACKAGES_URL = ""; + private static final String GET_VNF_PACKAGE_BY_ID_URL = "/" + VNF_PACKAGE_ID; + private static final String VNFD_ID = "vnfdId"; + private static final String VNF_PROVIDER = "vnfProvider"; + private static final String VNF_PRODUCT_NAME = "vnfProductName"; + private static final String VNF_SOFTWARE_VERSION = "vnfSoftwareVersion"; + private static final String VNFD_VERSION = "vnfdVersion"; + private static final String ALGORITHM = "algorithm"; + private static final String HASH = "hash"; + private static final String EXPECTED_BASE_URL = + "https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/vnfpkgm/v1/vnf_packages/"; + private static final String EXPECTED_SELF_HREF = EXPECTED_BASE_URL + VNF_PACKAGE_ID; + private static final String EXPECTED_VNFD_HREF = EXPECTED_BASE_URL + VNF_PACKAGE_ID + "/vnfd"; + private static final String EXPECTED_PACKAGE_CONTENT_HREF = EXPECTED_BASE_URL + VNF_PACKAGE_ID + "/package_content"; + + private MockRestServiceServer mockRestServiceServer; + private BasicHttpHeadersProvider basicHttpHeadersProvider; + private final Gson gson = new Gson(); + + public Sol003PackageManagementControllerTest() {} + + @Before + public void setUp() { + final MockRestServiceServer.MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(restTemplate); + builder.ignoreExpectOrder(true); + mockRestServiceServer = builder.build(); + basicHttpHeadersProvider = new BasicHttpHeadersProvider(); + } + + @After + public void after() { + mockRestServiceServer.reset(); + } + + @Test + public void testGetPackageContent_ValidArray_Success() { + final byte[] responseArray = buildByteArrayWithRandomData(10); + + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/package_content")) + .andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(responseArray, MediaType.APPLICATION_OCTET_STREAM)); + + final String testURL = "http://localhost:" + port + PACKAGE_MANAGEMENT_BASE_URL + "/vnf_packages/" + + VNF_PACKAGE_ID + "/package_content"; + final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders()); + final ResponseEntity<byte[]> responseEntity = + testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.GET, request, byte[].class); + + assertEquals(byte[].class, responseEntity.getBody().getClass()); + assertArrayEquals(responseEntity.getBody(), responseArray); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageContent_Conflict_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/package_content")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.CONFLICT)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/package_content"); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.CONFLICT, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageContent_NotFound_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/package_content")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.NOT_FOUND)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/package_content"); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageContent_UnauthorizedClient_Fail() { + final String testURL = "http://localhost:" + port + PACKAGE_MANAGEMENT_BASE_URL + "/vnf_packages/" + + VNF_PACKAGE_ID + "/package_content"; + + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/package_content")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.UNAUTHORIZED)); + + final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders()); + + + final ResponseEntity<ProblemDetails> responseEntity = + testRestTemplate.exchange(testURL, HttpMethod.GET, request, ProblemDetails.class); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageContent_InternalServerError_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/package_content")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/package_content"); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageContent_BadRequest_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/package_content")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.BAD_REQUEST)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/package_content"); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageContent_UnauthorizedServer_InternalError_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/package_content")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.UNAUTHORIZED)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/package_content"); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testGetPackageContent_SuccessResponseFromServerWithNullPackage_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/package_content")) + .andExpect(method(HttpMethod.GET)).andRespond(withSuccess()); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/package_content"); + + assertEquals(ProblemDetails.class, responseEntity.getBody().getClass()); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testGetPackageArtifact_ValidArray_Success() { + final byte[] responseArray = buildByteArrayWithRandomData(10); + + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH)) + .andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(responseArray, MediaType.APPLICATION_OCTET_STREAM)); + + final String testURL = "http://localhost:" + port + PACKAGE_MANAGEMENT_BASE_URL + "/vnf_packages/" + + VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH; + final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders()); + final ResponseEntity<byte[]> responseEntity = + testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.GET, request, byte[].class); + + assertEquals(byte[].class, responseEntity.getBody().getClass()); + assertArrayEquals(responseEntity.getBody(), responseArray); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageArtifact_Conflict_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH)) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.CONFLICT)); + + final ResponseEntity<ProblemDetails> responseEntity = + sendHttpRequest(VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH); + + assertNotNull(responseEntity.getBody()); + assertEquals(HttpStatus.CONFLICT, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageArtifact_NotFound_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH)) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.NOT_FOUND)); + + final ResponseEntity<ProblemDetails> responseEntity = + sendHttpRequest(VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH); + + assertNotNull(responseEntity.getBody()); + assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageArtifact_UnauthorizedClient_Fail() { + final String testURL = "http://localhost:" + port + PACKAGE_MANAGEMENT_BASE_URL + "/vnf_packages/" + + VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH; + + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH)) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.UNAUTHORIZED)); + + final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders()); + final ResponseEntity<ProblemDetails> responseEntity = + testRestTemplate.exchange(testURL, HttpMethod.GET, request, ProblemDetails.class); + + assertNotNull(responseEntity.getBody()); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageArtifact_InternalServerError_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH)) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)); + + final ResponseEntity<ProblemDetails> responseEntity = + sendHttpRequest(VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH); + + assertNotNull(responseEntity.getBody()); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageArtifact_BadRequest_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH)) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.BAD_REQUEST)); + + final ResponseEntity<ProblemDetails> responseEntity = + sendHttpRequest(VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH); + + assertNotNull(responseEntity.getBody()); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageArtifact_UnauthorizedServer_InternalError_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH)) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.UNAUTHORIZED)); + + final ResponseEntity<ProblemDetails> responseEntity = + sendHttpRequest(VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH); + + assertNotNull(responseEntity.getBody()); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testGetPackageArtifact_SuccessResponseFromServerWithNullPackage_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH)) + .andExpect(method(HttpMethod.GET)).andRespond(withSuccess()); + + final ResponseEntity<ProblemDetails> responseEntity = + sendHttpRequest(VNF_PACKAGE_ID + "/artifacts/" + ARTIFACT_PATH); + + assertNotNull(responseEntity.getBody()); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testVnfPackagesReceivedAsInlineResponse2001ListIfGetVnfPackagesSuccessful() { + final VnfPkgInfo[] responses = createVnfPkgArray(); + + mockRestServiceServer.expect(requestTo(MSB_BASE_URL)).andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(gson.toJson(responses), MediaType.APPLICATION_JSON)); + + final String testURL = localhostUrl + port + VNFPKGM_BASE_URL; + final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders()); + + final ResponseEntity<InlineResponse2001[]> responseEntity = testRestTemplate.withBasicAuth("test", "test") + .exchange(testURL, HttpMethod.GET, request, InlineResponse2001[].class); + + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertNotNull(responseEntity.getBody()); + final InlineResponse2001[] inlineResponse2001array = responseEntity.getBody(); + final InlineResponse2001 inlineResponse2001 = inlineResponse2001array[0]; + assertEquals(VNF_PACKAGE_ID, inlineResponse2001.getId()); + assertEquals(VNFD_ID, inlineResponse2001.getVnfdId()); + assertEquals(VNFD_ID, inlineResponse2001.getSoftwareImages().get(0).getId()); + assertEquals(VNF_PRODUCT_NAME, inlineResponse2001.getSoftwareImages().get(0).getName()); + assertEquals(ALGORITHM, inlineResponse2001.getChecksum().getAlgorithm()); + assertEquals(HASH, inlineResponse2001.getChecksum().getHash()); + assertEquals(ARTIFACT_PATH, inlineResponse2001.getAdditionalArtifacts().get(0).getArtifactPath()); + assertEquals(ALGORITHM, inlineResponse2001.getAdditionalArtifacts().get(0).getChecksum().getAlgorithm()); + assertEquals(HASH, inlineResponse2001.getAdditionalArtifacts().get(0).getChecksum().getHash()); + final VnfPackagesLinks links = inlineResponse2001.getLinks(); + assertNotNull(links); + assertEquals(EXPECTED_SELF_HREF, links.getSelf().getHref()); + assertEquals(EXPECTED_VNFD_HREF, links.getVnfd().getHref()); + assertEquals(EXPECTED_PACKAGE_CONTENT_HREF, links.getPackageContent().getHref()); + } + + @Test + public void test400BadRequestInfoReceivedAsProblemDetailsIfGetVnfPackagesIs400BadRequest() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL)).andExpect(method(HttpMethod.GET)) + .andRespond(withStatus(HttpStatus.BAD_REQUEST)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(GET_VNF_PACKAGES_URL); + assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + + assertNotNull(responseEntity.getBody()); + final ProblemDetails problemDetails = responseEntity.getBody(); + assertEquals("Error: Bad Request Received", problemDetails.getDetail()); + } + + @Test + public void test404NotFoundInfoReceivedAsProblemDetailsIfGetVnfPackagesIs404NotFound() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL)).andExpect(method(HttpMethod.GET)) + .andRespond(withStatus(HttpStatus.NOT_FOUND)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(GET_VNF_PACKAGES_URL); + assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode()); + + assertNotNull(responseEntity.getBody()); + final ProblemDetails problemDetails = responseEntity.getBody(); + assertEquals("No Vnf Packages found", problemDetails.getDetail()); + } + + @Test + public void test500InternalServerErrorProblemDetailsReceivedIfGetVnfPackagesReturns500InternalServerError() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL)).andExpect(method(HttpMethod.GET)) + .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(GET_VNF_PACKAGES_URL); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + + assertNotNull(responseEntity.getBody()); + final ProblemDetails problemDetails = responseEntity.getBody(); + assertEquals("Internal Server Error Occurred.", problemDetails.getDetail()); + } + + @Test + public void test500InternalServerErrorProblemDetailsReceivedIfGetVnfPackagesReturnsANullPackage() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL)).andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess()); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(GET_VNF_PACKAGES_URL); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + + assertNotNull(responseEntity.getBody()); + final ProblemDetails problemDetails = responseEntity.getBody(); + assertEquals("An error occurred, a null response was received by the\n" + + " Sol003PackageManagementController from the EtsiCatalogManager using the GET \"vnf_packages\" \n" + + "endpoint.", problemDetails.getDetail()); + } + + @Test + public void testVnfPackageReceivedAsInlineResponse2001IfGetVnfPackageByIdSuccessful() { + final VnfPkgInfo response = createVnfPkgInfo(VNF_PACKAGE_ID); + + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID)).andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(gson.toJson(response), MediaType.APPLICATION_JSON)); + + final String testURL = localhostUrl + port + VNFPKGM_BASE_URL + "/" + VNF_PACKAGE_ID; + final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders()); + final ResponseEntity<InlineResponse2001> responseEntity = testRestTemplate.withBasicAuth("test", "test") + .exchange(testURL, HttpMethod.GET, request, InlineResponse2001.class); + + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertNotNull(responseEntity.getBody()); + final InlineResponse2001 inlineResponse2001 = responseEntity.getBody(); + assertEquals(VNF_PACKAGE_ID, inlineResponse2001.getId()); + assertEquals(VNFD_ID, inlineResponse2001.getVnfdId()); + assertEquals(VNFD_ID, inlineResponse2001.getSoftwareImages().get(0).getId()); + assertEquals(VNF_PRODUCT_NAME, inlineResponse2001.getSoftwareImages().get(0).getName()); + assertEquals(ALGORITHM, inlineResponse2001.getChecksum().getAlgorithm()); + assertEquals(HASH, inlineResponse2001.getChecksum().getHash()); + assertEquals(ARTIFACT_PATH, inlineResponse2001.getAdditionalArtifacts().get(0).getArtifactPath()); + assertEquals(ALGORITHM, inlineResponse2001.getAdditionalArtifacts().get(0).getChecksum().getAlgorithm()); + assertEquals(HASH, inlineResponse2001.getAdditionalArtifacts().get(0).getChecksum().getHash()); + final VnfPackagesLinks links = inlineResponse2001.getLinks(); + assertNotNull(links); + assertEquals(EXPECTED_SELF_HREF, links.getSelf().getHref()); + assertEquals(EXPECTED_VNFD_HREF, links.getVnfd().getHref()); + assertEquals(EXPECTED_PACKAGE_CONTENT_HREF, links.getPackageContent().getHref()); + + } + + @Test + public void test400BadRequestInfoReceivedAsProblemDetailsIfGetVnfPackageByIdIs400BadRequest() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID)).andExpect(method(HttpMethod.GET)) + .andRespond(withStatus(HttpStatus.BAD_REQUEST)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(GET_VNF_PACKAGE_BY_ID_URL); + + assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + assertNotNull(responseEntity.getBody()); + final ProblemDetails problemDetails = responseEntity.getBody(); + assertEquals("Error: Bad Request Received", problemDetails.getDetail()); + } + + @Test + public void test404NotFoundInfoReceivedAsProblemDetailsIfGetVnfPackageByIdIs404NotFound() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID)).andExpect(method(HttpMethod.GET)) + .andRespond(withStatus(HttpStatus.NOT_FOUND)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(GET_VNF_PACKAGE_BY_ID_URL); + + assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode()); + assertNotNull(responseEntity.getBody()); + final ProblemDetails problemDetails = responseEntity.getBody(); + assertEquals("No Vnf Package found with vnfPkgId: " + VNF_PACKAGE_ID, problemDetails.getDetail()); + } + + @Test + public void test500InternalServerErrorProblemDetailsReceivedIfGetVnfPackageByIdReturns500InternalServerError() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID)).andExpect(method(HttpMethod.GET)) + .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(GET_VNF_PACKAGE_BY_ID_URL); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + assertNotNull(responseEntity.getBody()); + final ProblemDetails problemDetails = responseEntity.getBody(); + assertEquals("Internal Server Error Occurred.", problemDetails.getDetail()); + } + + @Test + public void test500InternalServerErrorProblemDetailsReceivedIfGetVnfPackageByIdReturnsANullPackage() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID)).andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess()); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(GET_VNF_PACKAGE_BY_ID_URL); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + + assertNotNull(responseEntity.getBody()); + final ProblemDetails problemDetails = responseEntity.getBody(); + assertEquals("An error occurred, a null response was received by the\n" + + " Sol003PackageManagementController from the EtsiCatalogManager using the GET \"vnf_packages\" by vnfPkgId: \"" + + VNF_PACKAGE_ID + "\" \n" + "endpoint.", problemDetails.getDetail()); + } + + // The below test method is here to improve code coverage and provide a foundation for writing + // future tests + @Test + public void testGetPackageVnfd_ValidArray_Success() { + final byte[] responseArray = buildByteArrayWithRandomData(10); + + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/vnfd")) + .andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(responseArray, MediaType.APPLICATION_OCTET_STREAM)); + + final String testURL = + "http://localhost:" + port + PACKAGE_MANAGEMENT_BASE_URL + "/vnf_packages/" + VNF_PACKAGE_ID + "/vnfd"; + final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders()); + final ResponseEntity<byte[]> responseEntity = + testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.GET, request, byte[].class); + + assertEquals(byte[].class, responseEntity.getBody().getClass()); + assertArrayEquals(responseEntity.getBody(), responseArray); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageVnfd_Conflict_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/vnfd")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.CONFLICT)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/vnfd"); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.CONFLICT, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageVnfd_NotFound_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/vnfd")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.NOT_FOUND)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/vnfd"); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageVnfd_UnauthorizedClient_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/vnfd")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.UNAUTHORIZED)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/vnfd"); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageVnfd_InternalServerError_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/vnfd")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/vnfd"); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageVnfd_BadRequest_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/vnfd")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.BAD_REQUEST)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/vnfd"); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testOnGetPackageVnfd_UnauthorizedServer_InternalError_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/vnfd")) + .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.UNAUTHORIZED)); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/vnfd"); + + assertTrue(responseEntity.getBody() instanceof ProblemDetails); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + @Test + public void testGetPackageVnfd_SuccessResponseFromServerWithNullPackage_Fail() { + mockRestServiceServer.expect(requestTo(MSB_BASE_URL + "/" + VNF_PACKAGE_ID + "/vnfd")) + .andExpect(method(HttpMethod.GET)).andRespond(withSuccess()); + + final ResponseEntity<ProblemDetails> responseEntity = sendHttpRequest(VNF_PACKAGE_ID + "/vnfd"); + + assertEquals(ProblemDetails.class, responseEntity.getBody().getClass()); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + } + + // Simply returns a byte array filled with random data, for use in the tests. + private byte[] buildByteArrayWithRandomData(final int sizeInKb) { + final Random rnd = new Random(); + final byte[] b = new byte[sizeInKb * 1024]; // converting kb to byte + rnd.nextBytes(b); + return b; + } + + private ResponseEntity<ProblemDetails> sendHttpRequest(final String url) { + final String testURL = localhostUrl + port + VNFPKGM_BASE_URL + "/" + url; + final HttpEntity<?> request = new HttpEntity<>(basicHttpHeadersProvider.getHttpHeaders()); + return testRestTemplate.withBasicAuth("test", "test").exchange(testURL, HttpMethod.GET, request, + ProblemDetails.class); + } + + private VnfPkgInfo[] createVnfPkgArray() { + final VnfPkgInfo[] vnfPkgInfoArray = new VnfPkgInfo[1]; + final VnfPkgInfo vnfPkgInfo = createVnfPkgInfo(VNF_PACKAGE_ID); + vnfPkgInfoArray[0] = vnfPkgInfo; + return vnfPkgInfoArray; + } + + private VnfPkgInfo createVnfPkgInfo(final String vnfPackageId) { + final VnfPkgInfo vnfPkgInfo = new VnfPkgInfo(); + vnfPkgInfo.setId(vnfPackageId); + vnfPkgInfo.setVnfdId(VNFD_ID); + vnfPkgInfo.setVnfProvider(VNF_PROVIDER); + vnfPkgInfo.setVnfProductName(VNF_PRODUCT_NAME); + vnfPkgInfo.setVnfSoftwareVersion(VNF_SOFTWARE_VERSION); + vnfPkgInfo.setVnfdVersion(VNFD_VERSION); + vnfPkgInfo.setChecksum(createVnfPkgChecksum()); + vnfPkgInfo.setSoftwareImages(createSoftwareImages()); + vnfPkgInfo.setAdditionalArtifacts(createAdditionalArtifacts()); + vnfPkgInfo.setLinks(createVNFPKGMLinkSerializerLinks()); + return vnfPkgInfo; + } + + private Checksum createVnfPkgChecksum() { + final Checksum checksum = new Checksum(); + checksum.setAlgorithm(ALGORITHM); + checksum.setHash(HASH); + return checksum; + } + + private List<VnfPackageSoftwareImageInfo> createSoftwareImages() { + final List<VnfPackageSoftwareImageInfo> softwareImages = new ArrayList<>(); + final VnfPackageSoftwareImageInfo vnfPackageSoftwareImageInfo = new VnfPackageSoftwareImageInfo(); + vnfPackageSoftwareImageInfo.setId(VNFD_ID); + vnfPackageSoftwareImageInfo.setName(VNF_PRODUCT_NAME); + vnfPackageSoftwareImageInfo.setProvider(""); + vnfPackageSoftwareImageInfo.setVersion(""); + vnfPackageSoftwareImageInfo.setChecksum(createVnfPkgChecksum()); + vnfPackageSoftwareImageInfo + .setContainerFormat(VnfPackageSoftwareImageInfo.ContainerFormatEnum.fromValue("AKI")); + softwareImages.add(vnfPackageSoftwareImageInfo); + return softwareImages; + } + + private List<VnfPackageArtifactInfo> createAdditionalArtifacts() { + final List<VnfPackageArtifactInfo> vnfPackageArtifactInfos = new ArrayList<>(); + final VnfPackageArtifactInfo vnfPackageArtifactInfo = + new VnfPackageArtifactInfo().artifactPath(ARTIFACT_PATH).checksum(createVnfPkgChecksum()); + vnfPackageArtifactInfos.add(vnfPackageArtifactInfo); + return vnfPackageArtifactInfos; + } + + private VNFPKGMLinkSerializer createVNFPKGMLinkSerializerLinks() { + final String baseUrl = "http://msb-iag:443/api/vnfpkgm/v1/vnf_packages"; + return new VNFPKGMLinkSerializer().self(new UriLink().href(baseUrl + "/myVnfPackageId")) + .vnfd(new UriLink().href(baseUrl + "/myVnfPackageId/vnfd")) + .packageContent(new UriLink().href(baseUrl + "/myVnfPackageId/package_content")); + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementSubscriptionControllerTest.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementSubscriptionControllerTest.java new file mode 100644 index 0000000000..65be6a87f0 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/Sol003PackageManagementSubscriptionControllerTest.java @@ -0,0 +1,403 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.rest; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.onap.so.adapters.etsi.sol003.adapter.common.CommonConstants.ETSI_SUBSCRIPTION_NOTIFICATION_BASE_URL; +import static org.onap.so.adapters.etsi.sol003.adapter.common.CommonConstants.PACKAGE_MANAGEMENT_BASE_URL; +import static org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.EtsiCatalogServiceProviderConfiguration.ETSI_CATALOG_REST_TEMPLATE_BEAN; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.GeneralSecurityException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.so.adapters.etsisol003adapter.pkgm.PackageManagementConstants; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.BasicAuth; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.LinkSelf; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdmSubscription; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmNotificationsFilter; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscription; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.ProblemDetails; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.SubscriptionAuthentication; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.Version; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfProducts; +import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfProductsProviders; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.InlineResponse2002; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.InlineResponse201; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.PkgmSubscriptionRequest; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsAuthentication; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsFilter1; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsFilterVnfProductsFromProviders; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.SubscriptionsLinks; +import org.onap.so.adapters.etsisol003adapter.pkgm.model.VnfPackagesLinksSelf; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.test.web.client.match.MockRestRequestMatchers; +import org.springframework.web.client.RestTemplate; +import com.google.gson.Gson; + +/** + * @author Ronan Kenny (ronan.kenny@est.tech) + * @author Gareth Roper (gareth.roper@est.tech) + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +public class Sol003PackageManagementSubscriptionControllerTest { + + private final Gson gson = new Gson(); + private final URI msbEndpoint = URI.create("http://msb-iag.onap:80/api/vnfpkgm/v1/subscriptions"); + private static final String _NOTIFICATION_CALLBACK_URI = + "https://so-vnfm-adapter.onap:30406" + ETSI_SUBSCRIPTION_NOTIFICATION_BASE_URL; + private static final String LOCALHOST_URL = "http://localhost:"; + + @Autowired + @Qualifier(ETSI_CATALOG_REST_TEMPLATE_BEAN) + private RestTemplate restTemplate; + private MockRestServiceServer mockRestServiceServer; + @Autowired + private CacheManager cacheServiceProvider; + @Autowired + private Sol003PackageManagementSubscriptionController sol003PackageManagementSubscriptionController; + + @Autowired + private TestRestTemplate testRestTemplate; + + @LocalServerPort + private int port; + + private static final String ID = UUID.randomUUID().toString(); + + @Before + public void setUp() { + mockRestServiceServer = MockRestServiceServer.bindTo(restTemplate).build(); + final Cache cache = + cacheServiceProvider.getCache(PackageManagementConstants.PACKAGE_MANAGEMENT_SUBSCRIPTION_CACHE); + cache.clear(); + } + + @After + public void after() { + mockRestServiceServer.reset(); + } + + @Test + public void testSuccessPostSubscription() throws GeneralSecurityException, URISyntaxException { + final PkgmSubscriptionRequest pkgmSubscriptionRequest = postSubscriptionForTest(); + final ResponseEntity<InlineResponse201> response = + (ResponseEntity<InlineResponse201>) sol003PackageManagementSubscriptionController + .postSubscriptionRequest(pkgmSubscriptionRequest); + + final HttpHeaders headers = buildHttpHeaders(Objects.requireNonNull(response.getBody()).getCallbackUri()); + + final SubscriptionsLinks subscriptionsLinks = new SubscriptionsLinks(); + final VnfPackagesLinksSelf vnfPackagesLinksSelf = new VnfPackagesLinksSelf(); + vnfPackagesLinksSelf.setHref("https://so-vnfm-adapter.onap:30406" + PACKAGE_MANAGEMENT_BASE_URL + + "/subscriptions/" + response.getBody().getId()); + subscriptionsLinks.setSelf(vnfPackagesLinksSelf); + + assertEquals(pkgmSubscriptionRequest.getFilter(), response.getBody().getFilter()); + assertEquals(subscriptionsLinks, response.getBody().getLinks()); + assertEquals(response.getBody().getFilter(), pkgmSubscriptionRequest.getFilter()); + assert (response.getHeaders().equals(headers)); + assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); + assertNotNull(response.getBody().getCallbackUri()); + } + + @Test + public void testFailPostSubscriptionAlreadyExists() throws GeneralSecurityException { + final PkgmSubscriptionRequest pkgmSubscriptionRequest = postSubscriptionForTest(); + + final ResponseEntity<InlineResponse2002> response = + (ResponseEntity<InlineResponse2002>) sol003PackageManagementSubscriptionController + .postSubscriptionRequest(pkgmSubscriptionRequest); + + // Create duplicate entry + final PkgmSubscriptionRequest pkgmSubscriptionRequest2 = buildPkgmSubscriptionRequest(); + + final ResponseEntity<InlineResponse2002> response2002 = + (ResponseEntity<InlineResponse2002>) sol003PackageManagementSubscriptionController + .postSubscriptionRequest(pkgmSubscriptionRequest2); + + assertEquals(HttpStatus.SEE_OTHER, response2002.getStatusCode()); + } + + @Test + public void testSuccessGetSubscriptionWithSubscriptionId() throws GeneralSecurityException, URISyntaxException { + + final PkgmSubscriptionRequest pkgmSubscriptionRequest = postSubscriptionForTest(); + + mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + ID)).andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(gson.toJson(new NsdmSubscription().id(ID)), MediaType.APPLICATION_JSON)); + + final ResponseEntity<InlineResponse201> response = + (ResponseEntity<InlineResponse201>) sol003PackageManagementSubscriptionController + .postSubscriptionRequest(pkgmSubscriptionRequest); + final String subscriptionId = response.getBody().getId(); + + + + final ResponseEntity<InlineResponse201> responseEntity = + (ResponseEntity<InlineResponse201>) sol003PackageManagementSubscriptionController + .getSubscription(subscriptionId); + + final HttpHeaders headers = buildHttpHeaders(response.getBody().getCallbackUri()); + + assertEquals(response.getBody().getFilter(), pkgmSubscriptionRequest.getFilter()); + assertEquals(response.getHeaders(), headers); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertEquals(pkgmSubscriptionRequest.getFilter(), response.getBody().getFilter()); + // Ensure CallBackUri is set to new URI + assertNotEquals(pkgmSubscriptionRequest.getCallbackUri(), response.getBody().getCallbackUri()); + } + + @Test + public void testFailGetSubscriptionWithInvalidSubscriptionId() { + final String invalidId = "invalidSubscriptionId"; + mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + invalidId)).andExpect(method(HttpMethod.GET)) + .andRespond(withStatus(HttpStatus.NOT_FOUND)); + final ResponseEntity<?> response = sol003PackageManagementSubscriptionController.getSubscription(invalidId); + assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); + assertTrue(response.getBody() instanceof ProblemDetails); + } + + @Test + public void testSuccessGetSubscriptions() throws GeneralSecurityException { + final PkgmSubscription pkgmSubscription = buildPkgmSubscription(); + final PkgmSubscriptionRequest pkgmSubscriptionRequest = buildPkgmSubscriptionRequest(); + + mockRestServiceServer.expect(requestTo(msbEndpoint)).andExpect(method(HttpMethod.POST)) + .andRespond(withSuccess(gson.toJson(pkgmSubscription), MediaType.APPLICATION_JSON)); + mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + ID)).andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(gson.toJson(new NsdmSubscription().id(ID)), MediaType.APPLICATION_JSON)); + + sol003PackageManagementSubscriptionController.postSubscriptionRequest(pkgmSubscriptionRequest); + final ResponseEntity<List<InlineResponse201>> response = + sol003PackageManagementSubscriptionController.getSubscriptions(); + + final List<InlineResponse201> subscriptionsList = response.getBody(); + + assertEquals(Objects.requireNonNull(response.getBody()).get(0).getFilter(), + pkgmSubscriptionRequest.getFilter()); + assertNotNull(subscriptionsList != null); + assertNotEquals('0', subscriptionsList.size()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + } + + @Test + public void testSuccessDeleteSubscriptionWithSubscriptionId() throws GeneralSecurityException { + final PkgmSubscriptionRequest pkgmSubscriptionRequest = buildPkgmSubscriptionRequest(); + final PkgmSubscription pkgmSubscription = buildPkgmSubscription(); + final String subscriptionId = pkgmSubscription.getId(); + + mockRestServiceServer.expect(requestTo(msbEndpoint)).andExpect(method(HttpMethod.POST)) + .andRespond(withSuccess(gson.toJson(pkgmSubscription), MediaType.APPLICATION_JSON)); + + mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + subscriptionId)).andExpect(method(HttpMethod.DELETE)) + .andRespond(withStatus(HttpStatus.NO_CONTENT)); + mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + subscriptionId)).andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess(gson.toJson(new NsdmSubscription().id(subscriptionId)), + MediaType.APPLICATION_JSON)); + + final ResponseEntity<InlineResponse2002> responsePost = + (ResponseEntity<InlineResponse2002>) sol003PackageManagementSubscriptionController + .postSubscriptionRequest(pkgmSubscriptionRequest); + + final ResponseEntity responseDelete = + sol003PackageManagementSubscriptionController.deleteSubscription(subscriptionId); + + // Attempt to retrieve the subscription after delete + final ResponseEntity<InlineResponse2002> responseGetSubscription = + (ResponseEntity<InlineResponse2002>) sol003PackageManagementSubscriptionController + .getSubscription(subscriptionId); + + assertEquals(HttpStatus.NOT_FOUND, responseGetSubscription.getStatusCode()); + assertEquals(HttpStatus.NO_CONTENT, responseDelete.getStatusCode()); + } + + @Test + public void testDeleteSubscription_SubscripitonNotFoundInEtsiCatalogManager_SubscriptionDeletedFromLocalCache() + throws GeneralSecurityException { + final PkgmSubscriptionRequest pkgmSubscriptionRequest = buildPkgmSubscriptionRequest(); + final PkgmSubscription pkgmSubscription = buildPkgmSubscription(); + + mockRestServiceServer.expect(requestTo(msbEndpoint)).andExpect(method(HttpMethod.POST)) + .andRespond(withSuccess(gson.toJson(pkgmSubscription), MediaType.APPLICATION_JSON)); + + mockRestServiceServer.expect(requestTo(msbEndpoint + "/" + ID)).andExpect(method(HttpMethod.DELETE)) + .andRespond(withStatus(HttpStatus.NOT_FOUND)); + + final ResponseEntity<InlineResponse2002> responsePost = + (ResponseEntity<InlineResponse2002>) sol003PackageManagementSubscriptionController + .postSubscriptionRequest(pkgmSubscriptionRequest); + + final Cache cache = + cacheServiceProvider.getCache(PackageManagementConstants.PACKAGE_MANAGEMENT_SUBSCRIPTION_CACHE); + assertNotNull(cache.get(ID)); + + final ResponseEntity responseDelete = sol003PackageManagementSubscriptionController.deleteSubscription(ID); + + assertEquals(HttpStatus.NO_CONTENT, responseDelete.getStatusCode()); + assertNull(cache.get(ID)); + + } + + @Test + public void testFailDeleteSubscriptionWithInvalidSubscriptionId() throws URISyntaxException, InterruptedException { + final ResponseEntity<Void> responseDelete = (ResponseEntity<Void>) sol003PackageManagementSubscriptionController + .deleteSubscription("invalidSubscriptionId"); + assertEquals(HttpStatus.NOT_FOUND, responseDelete.getStatusCode()); + } + + + @Test + public void testSuccessPostSubscriptionWithValidNotificationTypes() throws Exception { + + final String file = getAbsolutePath("src/test/resources/requests/SubscriptionRequest.json"); + final String json = new String(Files.readAllBytes(Paths.get(file))); + final PkgmSubscriptionRequest request = gson.fromJson(json, PkgmSubscriptionRequest.class); + + mockRestServiceServer.expect(requestTo(msbEndpoint)).andExpect(method(HttpMethod.POST)) + .andExpect(MockRestRequestMatchers.content().json(gson.toJson(getEtsiCatalogPkgmSubscriptionRequest()))) + .andRespond(withSuccess(gson.toJson(buildPkgmSubscription()), MediaType.APPLICATION_JSON)); + + + final ResponseEntity<InlineResponse201> responseEntity = + testRestTemplate.postForEntity(LOCALHOST_URL + port + PACKAGE_MANAGEMENT_BASE_URL + "/subscriptions", + request, InlineResponse201.class); + + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); + assertTrue(responseEntity.hasBody()); + final InlineResponse201 actual = responseEntity.getBody(); + assertEquals(ID, actual.getId()); + + + } + + private org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest getEtsiCatalogPkgmSubscriptionRequest() { + return new org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.PkgmSubscriptionRequest() + .filter(new PkgmNotificationsFilter() + .addNotificationTypesItem( + PkgmNotificationsFilter.NotificationTypesEnum.VNFPACKAGEONBOARDINGNOTIFICATION) + .addVnfdIdItem("VNFDID").addVnfPkgIdItem("VNFPKGID") + .addOperationalStateItem(PkgmNotificationsFilter.OperationalStateEnum.ENABLED) + .addVnfProductsFromProvidersItem(new VnfProductsProviders().vnfProvider("EST") + .addVnfProductsItem(new VnfProducts().vnfProductName("VnfProducts") + .addVersionsItem(new Version().vnfSoftwareVersion("vnfSoftwareVersion") + .addVnfdVersionsItem("version1"))))) + .callbackUri(_NOTIFICATION_CALLBACK_URI).authentication( + new SubscriptionAuthentication().addAuthTypeItem(SubscriptionAuthentication.AuthTypeEnum.BASIC) + .paramsBasic(new BasicAuth().userName("vnfm").password("password1$"))); + } + + private PkgmSubscriptionRequest buildPkgmSubscriptionRequest() { + final PkgmSubscriptionRequest pkgmSubscriptionRequest = new PkgmSubscriptionRequest(); + final SubscriptionsFilter1 sub = buildSubscriptionsFilter(); + final SubscriptionsAuthentication auth = new SubscriptionsAuthentication(); + pkgmSubscriptionRequest.setFilter(sub); + pkgmSubscriptionRequest.setCallbackUri(msbEndpoint.toString()); + pkgmSubscriptionRequest.setAuthentication(auth); + return pkgmSubscriptionRequest; + } + + private SubscriptionsFilter1 buildSubscriptionsFilter() { + final SubscriptionsFilter1 sub = new SubscriptionsFilter1(); + final List<String> vnfdIdList = new ArrayList<>(); + final List<String> vnfPkgIdList = new ArrayList<>(); + final List<SubscriptionsFilter1.NotificationTypesEnum> notificationTypes = new ArrayList<>(); + final SubscriptionsFilterVnfProductsFromProviders subscriptionsFilterVnfProductsFromProviders = + new SubscriptionsFilterVnfProductsFromProviders(); + final List<SubscriptionsFilterVnfProductsFromProviders> vnfProductsFromProviders = new ArrayList<>(); + + vnfProductsFromProviders.add(subscriptionsFilterVnfProductsFromProviders); + sub.setVnfdId(vnfdIdList); + sub.setNotificationTypes(notificationTypes); + sub.setVnfPkgId(vnfPkgIdList); + sub.setVnfProductsFromProviders(vnfProductsFromProviders); + return sub; + } + + private PkgmSubscription buildPkgmSubscription() { + final PkgmSubscription pkgmSubscription = new PkgmSubscription(); + final PkgmNotificationsFilter pkgmNotificationsFilter = new PkgmNotificationsFilter(); + final LinkSelf linkSelf = new LinkSelf(); + + pkgmSubscription.setId(ID); + pkgmSubscription.setCallbackUri(msbEndpoint + "/" + pkgmSubscription.getId().toString()); + pkgmSubscription.setFilter(pkgmNotificationsFilter); + pkgmSubscription.setLinks(linkSelf); + return pkgmSubscription; + } + + private PkgmSubscriptionRequest postSubscriptionForTest() { + final PkgmSubscriptionRequest pkgmSubscriptionRequest = buildPkgmSubscriptionRequest(); + final PkgmSubscription pkgmSubscription = buildPkgmSubscription(); + + mockRestServiceServer.expect(requestTo(msbEndpoint)).andExpect(method(HttpMethod.POST)) + .andRespond(withSuccess(gson.toJson(pkgmSubscription), MediaType.APPLICATION_JSON)); + return pkgmSubscriptionRequest; + } + + private HttpHeaders buildHttpHeaders(final String uri) throws URISyntaxException { + final HttpHeaders headers = new HttpHeaders(); + final URI myUri = new URI(uri); + headers.setLocation(myUri); + return headers; + } + + private String getAbsolutePath(final String path) { + final File file = new File(path); + return file.getAbsolutePath(); + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/TestApplication.java b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/TestApplication.java new file mode 100755 index 0000000000..33535523d6 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/java/org/onap/so/adapters/etsisol003adapter/pkgm/rest/TestApplication.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.etsisol003adapter.pkgm.rest; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.cache.annotation.EnableCaching; + +@EnableCaching +@SpringBootApplication(scanBasePackages = {"org.onap.so"}) +@EnableAutoConfiguration(exclude = {JacksonAutoConfiguration.class}) +public class TestApplication { + + public static void main(final String[] args) { + new SpringApplication(TestApplication.class).run(args); + } + +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/resources/application.yaml b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/resources/application.yaml new file mode 100644 index 0000000000..cdb6662191 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/resources/application.yaml @@ -0,0 +1,61 @@ +# Copyright © 2019 Nordix Foundation +# +# 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. +spring: + security: + usercredentials: + - username: test + password: '$2a$12$Zi3AuYcZoZO/gBQyUtST2.F5N6HqcTtaNci2Et.ufsQhski56srIu' + role: BPEL-Client + - username: vnfm + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPEL-Client + main: + allow-bean-definition-overriding: true + +mso: + key: 07a7159d3bf51a0e53be7a8f89699be7 + +aai: + auth: 2A11B07DB6214A839394AA1EC5844695F5114FC407FF5422625FB00175A3DCB8A1FF745F22867EFA72D5369D599BBD88DA8BED4233CF5586 + endpoint: https://aai.onap:8443 + version: v15 + +sdc: + username: sdcUser + password: sdcPassword + key: adadadadad + endpoint: http://sdc.onap/1234A + + +vnfmadapter: + endpoint: https://so-vnfm-adapter.onap:30406 + + +#Actuator +management: + endpoints: + web: + base-path: /manage + exposure: + include: "*" + metrics: + se-global-registry: false + export: + prometheus: + enabled: true # Whether exporting of metrics to Prometheus is enabled. + step: 1m # Step size (i.e. reporting frequency) to use. + +etsi-catalog-manager: + vnfpkgm: + endpoint: http://msb-iag.onap:80/api/vnfpkgm/v1 diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/resources/requests/SubscriptionRequest.json b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/resources/requests/SubscriptionRequest.json new file mode 100644 index 0000000000..c38466f8e5 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-adapter/src/test/resources/requests/SubscriptionRequest.json @@ -0,0 +1,45 @@ +{ + "filter": + { + "notificationTypes": [ + "VnfPackageOnboardingNotification" + ], + "vnfProductsFromProviders": [ + { + "vnfProvider": "EST", + "vnfProducts": [ + { + "vnfProductName": "VnfProducts", + "versions": [ + { + "vnfSoftwareVersion": "vnfSoftwareVersion", + "vnfdVersions": [ + "version1" + ] + } + ] + } + ] + } + ], + "vnfdId": [ + "VNFDID" + ], + "vnfPkgId": [ + "VNFPKGID" + ], + "operationalState": ["ENABLED"] + }, + "callbackUri": "http://so-vnfm-adapter:9093/api/vnfpkgm/v1/subscriptions", + "authentication": + { + "authType": [ + "BASIC" + ], + "paramsBasic": + { + "userName": "vnfm", + "password": "vnfm" + } + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-api/pom.xml b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-api/pom.xml new file mode 100644 index 0000000000..884419c550 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-api/pom.xml @@ -0,0 +1,196 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.so.adapters</groupId> + <artifactId>etsi-sol003-pkgm</artifactId> + <version>1.6.0-SNAPSHOT</version> + </parent> + <artifactId>etsi-sol003-pkgm-api</artifactId> + <name>ETSI SOL003 VNF Package Management Adapter API</name> + <build> + <plugins> + <plugin> + <groupId>io.swagger</groupId> + <artifactId>swagger-codegen-maven-plugin</artifactId> + <version>${version-swagger-codegen}</version> + <executions> + <execution> + <id>etsicatalog-notification-api</id> + <goals> + <goal>generate</goal> + </goals> + <configuration> + <inputSpec>${basedir}/src/main/resources/ETSI-Catalog-Notification-API.json</inputSpec> + <language>java</language> + <library>okhttp-gson</library> + <output>${project.build.directory}/generated-sources/etsicatalog/notification</output> + <apiPackage>org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.api</apiPackage> + <modelPackage>org.onap.so.adapters.etsisol003adapter.etsicatalog.notification.model</modelPackage> + <generateApiTests>false</generateApiTests> + <generateModelTests>false</generateModelTests> + <configOptions> + <sourceFolder>src/gen/java/main</sourceFolder> + <withXml>true</withXml> + <useRxJava2>true</useRxJava2> + <serializableModel>true</serializableModel> + <dateLibrary>java8-localdatetime</dateLibrary> + </configOptions> + </configuration> + </execution> + <execution> + <id>sol003-vnf-packagemanagement-api</id> + <goals> + <goal>generate</goal> + </goals> + <configuration> + <inputSpec>${basedir}/src/main/resources/SOL003-VNFPackageManagement-API.json</inputSpec> + <language>java</language> + <library>okhttp-gson</library> + <output>${project.build.directory}/generated-sources/sol003-vnf-packagemanagement</output> + <apiPackage>org.onap.so.adapters.etsisol003adapter.pkgm.api</apiPackage> + <modelPackage>org.onap.so.adapters.etsisol003adapter.pkgm.model</modelPackage> + <generateApiTests>false</generateApiTests> + <generateModelTests>false</generateModelTests> + <configOptions> + <sourceFolder>src/gen/java/main</sourceFolder> + <withXml>true</withXml> + <useRxJava2>true</useRxJava2> + <serializableModel>true</serializableModel> + </configOptions> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>add-source</id> + <phase>generate-sources</phase> + <goals> + <goal>add-source</goal> + </goals> + <configuration> + <sources> + <source>${project.basedir}/target/generated-sources/etsicatalog/notification/src/gen/java/main</source> + <source>${project.basedir}/target/generated-sources/sol003-vnf-packagemanagement/src/gen/java/main</source> + </sources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.eclipse.m2e</groupId> + <artifactId>lifecycle-mapping</artifactId> + <version>1.0.0</version> + <configuration> + <lifecycleMappingMetadata> + <pluginExecutions> + <pluginExecution> + <pluginExecutionFilter> + <groupId>io.swagger</groupId> + <artifactId>swagger-codegen-maven-plugin</artifactId> + <goals> + <goal>generate</goal> + </goals> + <versionRange>[2.2.0,)</versionRange> + </pluginExecutionFilter> + <action> + <execute> + <runOnIncremental>false</runOnIncremental> + </execute> + </action> + </pluginExecution> + </pluginExecutions> + </lifecycleMappingMetadata> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + <dependencies> + <dependency> + <groupId>io.swagger</groupId> + <artifactId>swagger-annotations</artifactId> + <version>${swagger-core-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.retrofit2</groupId> + <artifactId>converter-gson</artifactId> + <version>${retrofit-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.retrofit2</groupId> + <artifactId>retrofit</artifactId> + <version>${retrofit-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.retrofit2</groupId> + <artifactId>converter-scalars</artifactId> + <version>${retrofit-version}</version> + </dependency> + <dependency> + <groupId>org.apache.oltu.oauth2</groupId> + <artifactId>org.apache.oltu.oauth2.client</artifactId> + <version>${oltu-version}</version> + </dependency> + <dependency> + <groupId>io.gsonfire</groupId> + <artifactId>gson-fire</artifactId> + <version>${gson-fire-version}</version> + </dependency> + <dependency> + <groupId>org.threeten</groupId> + <artifactId>threetenbp</artifactId> + <version>${threetenbp-version}</version> + </dependency> + <dependency> + <groupId>io.reactivex.rxjava2</groupId> + <artifactId>rxjava</artifactId> + </dependency> + <dependency> + <groupId>com.squareup.retrofit2</groupId> + <artifactId>adapter-rxjava2</artifactId> + <version>${retrofit-version}</version> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + <dependency> + <groupId>com.squareup.okio</groupId> + <artifactId>okio</artifactId> + <version>${okio-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp3</groupId> + <artifactId>okhttp</artifactId> + <version>${okhttp3-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp3</groupId> + <artifactId>logging-interceptor</artifactId> + <version>${okhttp3-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp</groupId> + <artifactId>logging-interceptor</artifactId> + <version>${okhttp-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp</groupId> + <artifactId>okhttp</artifactId> + <version>${okhttp-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp</groupId> + <artifactId>logging-interceptor</artifactId> + <version>${okhttp-version}</version> + </dependency> + </dependencies> +</project> diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-api/src/main/resources/ETSI-Catalog-Notification-API.json b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-api/src/main/resources/ETSI-Catalog-Notification-API.json new file mode 100644 index 0000000000..6db54435d2 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-api/src/main/resources/ETSI-Catalog-Notification-API.json @@ -0,0 +1,279 @@ +{ + "swagger": "2.0", + "info": { + "title": "Modeling etsicatalog API", + "description": "\n\nThe `swagger-ui` view can be found [here](/api/catalog/v1/swagger).\nThe `ReDoc` view can be found [here](/api/catalog/v1/redoc).\nThe swagger YAML document can be found [here](/api/catalog/v1/swagger.yaml).\nThe swagger JSON document can be found [here](/api/catalog/v1/swagger.json).", + "version": "v1" + }, + "host": "127.0.0.1:8000", + "schemes": [ + "http" + ], + "basePath": "/", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "securityDefinitions": { + "Basic": { + "type": "basic" + } + }, + "security": [ + { + "Basic": [] + } + ], + "paths": { + "/URI-is-provided-by-the-client-when-creating-the-subscription-VnfPackageChangeNotification": { + "get": { + "operationId": "URI-is-provided-by-the-client-when-creating-the-subscription-VnfPackageChangeNotification_list", + "description": "", + "parameters": [], + "responses": { + "204": { + "description": "" + }, + "500": { + "description": "error message", + "schema": { + "type": "string" + } + } + }, + "tags": [ + "VNF Package Management interface" + ] + }, + "post": { + "operationId": "URI-is-provided-by-the-client-when-creating-the-subscription-VnfPackageChangeNotification_create", + "description": "", + "parameters": [ + { + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PkgChangeNotification" + } + } + ], + "responses": { + "204": { + "description": "" + } + }, + "tags": [ + "VNF Package Management interface" + ] + }, + "parameters": [] + }, + "/URI-is-provided-by-the-client-when-creating-the-subscription-VnfPackageOnboardingNotification": { + "get": { + "operationId": "URI-is-provided-by-the-client-when-creating-the-subscription-VnfPackageOnboardingNotification_list", + "description": "", + "parameters": [], + "responses": { + "204": { + "description": "" + }, + "500": { + "description": "error message", + "schema": { + "type": "string" + } + } + }, + "tags": [ + "VNF Package Management interface" + ] + }, + "post": { + "operationId": "URI-is-provided-by-the-client-when-creating-the-subscription-VnfPackageOnboardingNotification_create", + "description": "", + "parameters": [ + { + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PkgOnboardingNotification" + } + } + ], + "responses": { + "204": { + "description": "" + } + }, + "tags": [ + "VNF Package Management interface" + ] + }, + "parameters": [] + } + }, + "definitions": { + "NOTIFICATION_LINKSERIALIZER": { + "title": "Vnfpackage", + "description": "Link to the resource representing the VNF package to which the notified change applies.", + "required": [ + "href" + ], + "type": "object", + "properties": { + "href": { + "title": "Href", + "description": "URI of the referenced resource.", + "type": "string", + "minLength": 1 + } + } + }, + "PkgmLinks": { + "title": " links", + "description": "Links to resources related to this resource.", + "type": "object", + "properties": { + "vnfPackage": { + "$ref": "#/definitions/NOTIFICATION_LINKSERIALIZER" + }, + "subscription": { + "$ref": "#/definitions/NOTIFICATION_LINKSERIALIZER" + } + } + }, + "PkgChangeNotification": { + "required": [ + "id", + "notificationType", + "timeStamp", + "subscriptionId", + "vnfPkgId", + "changeType", + "vnfdId", + "_links" + ], + "type": "object", + "properties": { + "id": { + "title": "Id", + "description": "Identifier of this notification.", + "type": "string", + "minLength": 1 + }, + "notificationType": { + "title": "Notificationtype", + "description": "Discriminator for the different notification types.", + "type": "string", + "enum": [ + "VnfPackageChangeNotification" + ] + }, + "timeStamp": { + "title": "Timestamp", + "description": "Date-time of the generation of the notification.", + "type": "string", + "format": "date-time" + }, + "subscriptionId": { + "title": "Subscriptionid", + "description": "Identifier of the subscription that this notification relates to.", + "type": "string", + "minLength": 1 + }, + "vnfPkgId": { + "title": "Vnfpkgid", + "description": "Identifier of the VNF package.", + "type": "string", + "minLength": 1 + }, + "changeType": { + "title": "Changetype", + "description": "The type of change of the VNF package.", + "type": "string", + "enum": [ + "OP_STATE_CHANGE", + "PKG_DELETE" + ] + }, + "operationalState": { + "title": "Operationalstate", + "description": "New operational state of the VNF package.", + "type": "string", + "enum": [ + "ENABLED", + "DISABLED" + ] + }, + "vnfdId": { + "title": "Vnfdid", + "description": "This identifier, which is managed by the VNF provider, identifies the VNF package and the VNFD in a globally unique way.", + "type": "string", + "minLength": 1 + }, + "_links": { + "$ref": "#/definitions/PkgmLinks" + } + } + }, + "PkgOnboardingNotification": { + "required": [ + "id", + "notificationType", + "subscriptionId", + "timeStamp", + "vnfPkgId", + "vnfdId", + "_links" + ], + "type": "object", + "properties": { + "id": { + "title": "Id", + "description": "Identifier of this notification.", + "type": "string", + "minLength": 1 + }, + "notificationType": { + "title": "Notificationtype", + "description": "Discriminator for the different notification types.", + "type": "string", + "enum": [ + "VnfPackageOnboardingNotification" + ] + }, + "subscriptionId": { + "title": "Subscriptionid", + "description": "Identifier of the subscription that this notification relates to.", + "type": "string", + "minLength": 1 + }, + "timeStamp": { + "title": "Timestamp", + "description": "Date-time of the generation of the notification.", + "type": "string", + "format": "date-time" + }, + "vnfPkgId": { + "title": "Vnfpkgid", + "description": "Identifier of the VNF package.", + "type": "string", + "minLength": 1 + }, + "vnfdId": { + "title": "Vnfdid", + "description": "This identifier, which is managed by the VNF provider, identifies the VNF package and the VNFD in a globally unique way.", + "type": "string", + "minLength": 1 + }, + "_links": { + "$ref": "#/definitions/PkgmLinks" + } + } + } + } +} diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-api/src/main/resources/SOL003-VNFPackageManagement-API.json b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-api/src/main/resources/SOL003-VNFPackageManagement-API.json new file mode 100644 index 0000000000..17d81f44c1 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-api/src/main/resources/SOL003-VNFPackageManagement-API.json @@ -0,0 +1,7352 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.2.0-impl:etsi.org:ETSI_NFV_OpenAPI:1", + "title": "SOL003 - VNF Package Management interface", + "description": "SOL003 - VNF Package Management interface\n\nIMPORTANT: Please note that this file might be not aligned to the current version of the ETSI Group Specification it refers to. In case of discrepancies the published ETSI Group Specification takes precedence.\n\nIn clause 4.3.2 of ETSI GS NFV-SOL 003 v2.4.1, an attribute-based filtering mechanism is defined. This mechanism is currently not included in the corresponding OpenAPI design for this GS version. Changes to the attribute-based filtering mechanism are being considered in v2.5.1 of this GS for inclusion in the corresponding future ETSI NFV OpenAPI design.\nPlease report bugs to https://forge.etsi.org/bugzilla/buglist.cgi?component=Nfv-Openapis&list_id=61&product=NFV&resolution=\n", + "license": { + "name": "ETSI Forge copyright notice", + "url": "https://forge.etsi.org/etsi-forge-copyright-notice.txt" + } + }, + "externalDocs": { + "description": "ETSI GS NFV-SOL 003 V2.5.1", + "url": "https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/003/02.05.01_60/gs_nfv-sol003v020501p.pdf" + }, + "basePath": "/vnfpkgm/v1", + "schemes": [ + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/api-versions": { + "parameters": [ + { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": false, + "type": "string" + } + ], + "get": { + "summary": "Retrieve API version information", + "description": "The GET method reads API version information. This method shall follow the provisions specified in table 4.6.3.3.3.2-1 for request and response data structures, and response codes. URI query parameters are not supported.\n", + "responses": { + "200": { + "description": "200 OK\nAPI version information was read successfully. The response body shall contain 4.4 API version information, as defined in clause 4.4.1.13.\n", + "schema": { + "description": "This type represents API version information. It shall comply with the provisions defined in table 4.4.1.13-1 (SOL003).\n", + "type": "object", + "required": [ + "uriPrefix", + "apiVersions" + ], + "properties": { + "uriPrefix": { + "description": "Specifies the URI prefix for the API, in the following form {apiRoot}/{apiName}/{apiMajorVersion}/\n", + "type": "string" + }, + "apiVersions": { + "description": "Version(s) supported for the API signaled by the uriPrefix attribute.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "version" + ], + "properties": { + "version": { + "description": "Identifies a supported version. The value of the version attribute shall be a version identifier as specified in clause 4.6.1.\n", + "type": "string" + }, + "isDeprecated": { + "description": "If such information is available, this attribute indicates whether use of the version signaled by the version attribute is deprecated (true) or not (false). A deprecated version is still supported by the API producer but is recommended not to be used any longer. When a version is no longer supported, it does not appear in the response body.\n", + "type": "boolean" + }, + "retirementDate": { + "description": "Date-time stamp. Representation: String formatted according to IETF RFC 3339.\n", + "type": "string", + "format": "date-time" + } + } + } + } + } + }, + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "Version": { + "description": "The used API version.", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "405": { + "description": "405 METHOD NOT ALLOWED\nIf a particular HTTP method is not supported for a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "413": { + "description": "413 PAYLOAD TOO LARGE\nIf the payload body of a request is larger than the amount of data the API producer is willing or able to process, it shall respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for closing the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "414": { + "description": "414 URI TOO LONG\nIf the request URI of a request is longer than the API producer is willing or able to process, it shall respond with this response code. This condition can e.g. be caused by passing long queries in the request URI of a GET request. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "416": { + "description": "416 RANGE NOT SATISFIABLE\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "422": { + "description": "422 UNPROCESSABLE ENTITY\nIf the payload body of a request contains syntactically correct data (e.g. well-formed JSON) but the data cannot be processed (e.g. because it fails validation against a schema), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nThis error response code is only applicable for methods that have a request body.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "429": { + "description": "429 TOO MANY REQUESTS\nIf the API consumer has sent too many requests in a defined period of time and the API producer is able to detect that condition (\"rate limiting\"), the API producer shall respond with this response code, following the provisions in IETF RFC 6585 [17] for the use of the \"Retry-After\" HTTP header. The \"ProblemDetails\" structure shall be provided and shall include in the \"detail\" attribute more information about the source of the problem.\nThe period of time and allowed number of requests are configured within the API producer by means outside the scope of the present document.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "504": { + "description": "504 GATEWAY TIMEOUT\nIf the API producer encounters a timeout while waiting for a response from an upstream server (i.e. a server that the API producer communicates with when fulfilling a request), it should respond with this response code.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + } + }, + "/vnf_packages": { + "get": { + "description": "Query VNF Package Info\n\nThe GET method queries the information of the VNF packages matching the filter.\n", + "parameters": [ + { + "name": "Accept", + "description": "Content-Types that are acceptable for the response. Reference: IETF RFC 7231\n", + "in": "header", + "required": true, + "type": "string" + }, + { + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, + { + "name": "filter", + "description": "Attribute-based filtering expression according to clause 4.3.2. The VNFM shall support receiving this parameter as part of the URI query string. The NFVO may supply this parameter. All attribute names that appear in the VnfPkgInfo and in data types referenced from it shall be supported by the VNFM in the filter expression.\n", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "all_fields", + "description": "Include all complex attributes in the response. See clause 4.3.3 for details. The VNFM shall support this parameter.\n", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fields", + "description": "Complex attributes to be included into the response. See clause 4.3.3 for details. The VNFM should support this parameter.\n", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "exclude_fields", + "description": "Complex attributes to be excluded from the response. See clause 4.3.3 for details. The VNFM should support this parameter.\n", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "exclude_default", + "description": "Indicates to exclude the following complex attributes from the response. See clause 4.3.3 for details. The VNFM shall support this parameter. The following attributes shall be excluded from the VnfPkgInfo structure in the response body if this parameter is provided, or none of the parameters \"all_fields,\" \"fields\", \"exclude_fields\", \"exclude_default\" are provided: -\tsoftwareImages -\tadditionalArtifacts -\tuserDefinedData.\n", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "nextpage_opaque_marker", + "description": "Marker to obtain the next page of a paged response. Shall be supported by the VNFM if the VNFM supports alternative 2 (paging) according to clause 4.7.2.1 for this resource.\n", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "200 OK\nInformation about zero or more VNF packages was queried successfully. The response body shall contain in an array the VNF package info representations that match the attribute filter, i.e. zero or more VNF package representations as defined in clause 10.5.2.2. If the VNFM supports alternative 2 (paging) according to clause 4.7.2.1 for this resource, inclusion of the Link HTTP header in this response shall follow the provisions in clause 4.7.2.3.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "Link": { + "description": "Reference to other resources. Used for paging in the present document, see clause 4.7.2.1.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + } + }, + "schema": { + "type": "array", + "items": { + "description": "This type represents the information of an VNF package.\n", + "type": "object", + "required": [ + "id", + "operationalState", + "usageState", + "_links" + ], + "properties": { + "id": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "vnfdId": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "vnfProvider": { + "description": "Provider of the VNF package and the VNFD. This information is copied from the VNFD.\n", + "type": "string" + }, + "vnfProductName": { + "description": "Name to identify the VNF product. Invariant for the VNF product lifetime. This information is copied from the VNFD. It shall be present after the VNF package content has been on-boarded and absent otherwise.\n", + "type": "string" + }, + "vnfSoftwareVersion": { + "description": "A Version.\n", + "type": "string" + }, + "vnfdVersion": { + "description": "A Version.\n", + "type": "string" + }, + "checksum": { + "description": "This type represents the checksum of a VNF package or an artifact file.\n", + "type": "object", + "required": [ + "algorithm", + "hash" + ], + "properties": { + "algorithm": { + "description": "Name of the algorithm used to generate the checksum, as defined in ETSI GS NFV-SOL 004. For example, SHA-256, SHA-512.\n", + "type": "string" + }, + "hash": { + "description": "The hexadecimal value of the checksum.\n", + "type": "string" + } + } + }, + "softwareImages": { + "description": "Information about VNF package artifacts that are software images. This attribute shall not be present before the VNF package content is on-boarded. Otherwise, this attribute shall be present unless it has been requested to be excluded per attribute selector.\n", + "type": "array", + "items": { + "description": "This type represents an artifact contained in a VNF package which represents a software image.\n", + "type": "object", + "required": [ + "id", + "name", + "provider", + "version", + "checksum", + "containerFormat", + "diskFormat", + "createdAt", + "minDisk", + "minRam", + "size", + "imagePath" + ], + "properties": { + "id": { + "description": "An identifier that is unique within a VNF descriptor.\n", + "type": "string" + }, + "name": { + "description": "Name of the software image.\n", + "type": "string" + }, + "provider": { + "description": "Provider of the software image.\n", + "type": "string" + }, + "version": { + "description": "A Version.\n", + "type": "string" + }, + "checksum": { + "description": "This type represents the checksum of a VNF package or an artifact file.\n", + "type": "object", + "required": [ + "algorithm", + "hash" + ], + "properties": { + "algorithm": { + "description": "Name of the algorithm used to generate the checksum, as defined in ETSI GS NFV-SOL 004. For example, SHA-256, SHA-512.\n", + "type": "string" + }, + "hash": { + "description": "The hexadecimal value of the checksum.\n", + "type": "string" + } + } + }, + "containerFormat": { + "description": "Container format indicates whether the software image is in a file format that also contains metadata about the actual software. Permitted values: - AKI: a kernel image format - AMI: a machine image format - ARI: a ramdisk image format - BARE: the image does not have a container or metadata envelope - DOCKER: docker container format - OVA: OVF package in a tarfile - OVF: OVF container format The list of permitted values was taken from \"Container formats\" in http://docs.openstack.org/image-guide/image-formats.html\n", + "type": "string", + "enum": [ + "AKI", + "AMI", + "ARI", + "BARE", + "DOCKER", + "OVA", + "OVF" + ] + }, + "diskFormat": { + "description": "Disk format of a software image is the format of the underlying disk image. Permitted values: - AKI: a kernel image format - AMI: a machine image format - ARI: a ramdisk image format - ISO: an archive format for the data contents of an optical disc, such as CD-ROM\n- QCOW2: a common disk image format, which can expand dynamically and supports copy on write\n- RAW: an unstructured disk image format - VDI: a common disk image format - VHD: a common disk image format - VHDX: enhanced version of VHD format - VMDK: a common disk image format The list of permitted values was adapted from \"Disk formats\" in http://docs.openstack.org/image-guide/image-formats.html\n", + "type": "string", + "enum": [ + "AKI", + "AMI", + "ISO", + "QCOW2", + "RAW", + "VDI", + "VHD", + "VHDX", + "VMDK" + ] + }, + "createdAt": { + "description": "Date-time stamp. Representation: String formatted according to IETF RFC 3339.\n", + "type": "string", + "format": "date-time" + }, + "minDisk": { + "description": "The minimal disk for this software image in bytes.\n", + "type": "integer" + }, + "minRam": { + "description": "The minimal RAM for this software image in bytes.\n", + "type": "integer" + }, + "size": { + "description": "Size of this software image in bytes.\n", + "type": "integer" + }, + "userMetadata": { + "description": "This type represents a list of key-value pairs. The order of the pairs in the list is not significant. In JSON, a set of key- value pairs is represented as an object. It shall comply with the provisions defined in clause 4 of IETF RFC 7159.\n", + "type": "object" + }, + "imagePath": { + "description": "Path in the VNF package, which identifies the image artifact and also allows to access a copy of the image artifact.\n", + "type": "string" + } + } + } + }, + "additionalArtifacts": { + "description": "Information about VNF package artifacts contained in the VNF package that are not software images. This attribute shall not be present before the VNF package content is on-boarded. Otherwise, this attribute shall be present if the VNF package contains additional artifacts.\n", + "type": "array", + "items": { + "description": "This type represents an artifact other than a software image which is contained in a VNF package.\n", + "type": "object", + "required": [ + "artifactPath", + "checksum" + ], + "properties": { + "artifactPath": { + "description": "Path in the VNF package, which identifies the artifact and also allows to access a copy of the artifact.\n", + "type": "string" + }, + "checksum": { + "description": "This type represents the checksum of a VNF package or an artifact file.\n", + "type": "object", + "required": [ + "algorithm", + "hash" + ], + "properties": { + "algorithm": { + "description": "Name of the algorithm used to generate the checksum, as defined in ETSI GS NFV-SOL 004. For example, SHA-256, SHA-512.\n", + "type": "string" + }, + "hash": { + "description": "The hexadecimal value of the checksum.\n", + "type": "string" + } + } + }, + "metadata": { + "description": "This type represents a list of key-value pairs. The order of the pairs in the list is not significant. In JSON, a set of key- value pairs is represented as an object. It shall comply with the provisions defined in clause 4 of IETF RFC 7159.\n", + "type": "object" + } + } + } + }, + "onboardingState": { + "description": "CREATED: The VNF package resource has been created. UPLOADING: The associated VNF package content is being uploaded. PROCESSING: The associated VNF package content is being processed, e.g., validation.\nONBOARDED: The associated VNF package content has been successfully on-boarded.\n", + "type": "string", + "enum": [ + "CREATED", + "UPLOADING", + "PROCESSING", + "ONBOARDED" + ] + }, + "operationalState": { + "description": "- ENABLED: The VNF package is enabled, i.e. it can be used for instantiation of new VNF instances.\n- DISABLED: The VNF package is disabled, i.e. it cannot be used for further VNF instantiation requests (unless and until the VNF package\n is re-enabled).\n", + "type": "string", + "enum": [ + "ENABLED", + "DISABLED" + ] + }, + "usageState": + { + "description": "- IN_USE: VNF instances instantiated from this VNF package exist. - NOT_IN_USE: No existing VNF instance is instantiated from this VNF package.\n", + "type": "string", + "enum": [ + "IN_USE", + "NOT_IN_USE" + ] + }, + "userDefinedData": { + "description": "This type represents a list of key-value pairs. The order of the pairs in the list is not significant. In JSON, a set of key- value pairs is represented as an object. It shall comply with the provisions defined in clause 4 of IETF RFC 7159.\n", + "type": "object" + }, + "_links": { + "description": "Links to resources related to this resource.\n", + "type": "object", + "required": [ + "self", + "packageContent" + ], + "properties": { + "self": { + "description": "This type represents a link to a resource using an absolute URI. It shall comply with the provisions defined in table 4.4.1.3-1.\n", + "type": "object", + "required": [ + "href" + ], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + }, + "vnfd": { + "description": "This type represents a link to a resource using an absolute URI. It shall comply with the provisions defined in table 4.4.1.3-1.\n", + "type": "object", + "required": [ + "href" + ], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + }, + "packageContent": { + "description": "This type represents a link to a resource using an absolute URI. It shall comply with the provisions defined in table 4.4.1.3-1.\n", + "type": "object", + "required": [ + "href" + ], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + } + } + } + } + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "405": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "416": { + "description": "416 RANGE NOT SATISFIABLE\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + } + }, + "/vnf_packages/{vnfPkgId}": { + "parameters": [ + { + "name": "vnfPkgId", + "description": "Identifier of the VNF package. The identifier is allocated by the NFVO. This identifier can be retrieved from the \"vnfPkgId\" attribute in the VnfPackageOnboardingNotification or VnfPackageChangeNotification.\n", + "in": "path", + "type": "string", + "required": true + } + ], + "get": { + "description": "Query VNF Package Info\n\nThe GET method reads the information of an individual VNF package.\n", + "parameters": [ + { + "name": "Accept", + "description": "Content-Types that are acceptable for the response. Reference: IETF RFC 7231\n", + "in": "header", + "required": true, + "type": "string" + }, + { + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, + { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "200 OK\nInformation of the selected VNF packages.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "This type represents the information of an VNF package.\n", + "type": "object", + "required": [ + "id", + "operationalState", + "usageState", + "_links" + ], + "properties": { + "id": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "vnfdId": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "vnfProvider": { + "description": "Provider of the VNF package and the VNFD. This information is copied from the VNFD.\n", + "type": "string" + }, + "vnfProductName": { + "description": "Name to identify the VNF product. Invariant for the VNF product lifetime. This information is copied from the VNFD. It shall be present after the VNF package content has been on-boarded and absent otherwise.\n", + "type": "string" + }, + "vnfSoftwareVersion": { + "description": "A Version.\n", + "type": "string" + }, + "vnfdVersion": { + "description": "A Version.\n", + "type": "string" + }, + "checksum": { + "description": "This type represents the checksum of a VNF package or an artifact file.\n", + "type": "object", + "required": [ + "algorithm", + "hash" + ], + "properties": { + "algorithm": { + "description": "Name of the algorithm used to generate the checksum, as defined in ETSI GS NFV-SOL 004. For example, SHA-256, SHA-512.\n", + "type": "string" + }, + "hash": { + "description": "The hexadecimal value of the checksum.\n", + "type": "string" + } + } + }, + "softwareImages": { + "description": "Information about VNF package artifacts that are software images. This attribute shall not be present before the VNF package content is on-boarded. Otherwise, this attribute shall be present unless it has been requested to be excluded per attribute selector.\n", + "type": "array", + "items": { + "description": "This type represents an artifact contained in a VNF package which represents a software image.\n", + "type": "object", + "required": [ + "id", + "name", + "provider", + "version", + "checksum", + "containerFormat", + "diskFormat", + "createdAt", + "minDisk", + "minRam", + "size", + "imagePath" + ], + "properties": { + "id": { + "description": "An identifier that is unique within a VNF descriptor.\n", + "type": "string" + }, + "name": { + "description": "Name of the software image.\n", + "type": "string" + }, + "provider": { + "description": "Provider of the software image.\n", + "type": "string" + }, + "version": { + "description": "A Version.\n", + "type": "string" + }, + "checksum": { + "description": "This type represents the checksum of a VNF package or an artifact file.\n", + "type": "object", + "required": [ + "algorithm", + "hash" + ], + "properties": { + "algorithm": { + "description": "Name of the algorithm used to generate the checksum, as defined in ETSI GS NFV-SOL 004. For example, SHA-256, SHA-512.\n", + "type": "string" + }, + "hash": { + "description": "The hexadecimal value of the checksum.\n", + "type": "string" + } + } + }, + "containerFormat": { + "description": "Container format indicates whether the software image is in a file format that also contains metadata about the actual software. Permitted values: - AKI: a kernel image format - AMI: a machine image format - ARI: a ramdisk image format - BARE: the image does not have a container or metadata envelope - DOCKER: docker container format - OVA: OVF package in a tarfile - OVF: OVF container format The list of permitted values was taken from \"Container formats\" in http://docs.openstack.org/image-guide/image-formats.html\n", + "type": "string", + "enum": [ + "AKI", + "AMI", + "ARI", + "BARE", + "DOCKER", + "OVA", + "OVF" + ] + }, + "diskFormat": { + "description": "Disk format of a software image is the format of the underlying disk image. Permitted values: - AKI: a kernel image format - AMI: a machine image format - ARI: a ramdisk image format - ISO: an archive format for the data contents of an optical disc, such as CD-ROM\n- QCOW2: a common disk image format, which can expand dynamically and supports copy on write\n- RAW: an unstructured disk image format - VDI: a common disk image format - VHD: a common disk image format - VHDX: enhanced version of VHD format - VMDK: a common disk image format The list of permitted values was adapted from \"Disk formats\" in http://docs.openstack.org/image-guide/image-formats.html\n", + "type": "string", + "enum": [ + "AKI", + "AMI", + "ISO", + "QCOW2", + "RAW", + "VDI", + "VHD", + "VHDX", + "VMDK" + ] + }, + "createdAt": { + "description": "Date-time stamp. Representation: String formatted according to IETF RFC 3339.\n", + "type": "string", + "format": "date-time" + }, + "minDisk": { + "description": "The minimal disk for this software image in bytes.\n", + "type": "integer" + }, + "minRam": { + "description": "The minimal RAM for this software image in bytes.\n", + "type": "integer" + }, + "size": { + "description": "Size of this software image in bytes.\n", + "type": "integer" + }, + "userMetadata": { + "description": "This type represents a list of key-value pairs. The order of the pairs in the list is not significant. In JSON, a set of key- value pairs is represented as an object. It shall comply with the provisions defined in clause 4 of IETF RFC 7159.\n", + "type": "object" + }, + "imagePath": { + "description": "Path in the VNF package, which identifies the image artifact and also allows to access a copy of the image artifact.\n", + "type": "string" + } + } + } + }, + "additionalArtifacts": { + "description": "Information about VNF package artifacts contained in the VNF package that are not software images. This attribute shall not be present before the VNF package content is on-boarded. Otherwise, this attribute shall be present if the VNF package contains additional artifacts.\n", + "type": "array", + "items": { + "description": "This type represents an artifact other than a software image which is contained in a VNF package.\n", + "type": "object", + "required": [ + "artifactPath", + "checksum" + ], + "properties": { + "artifactPath": { + "description": "Path in the VNF package, which identifies the artifact and also allows to access a copy of the artifact.\n", + "type": "string" + }, + "checksum": { + "description": "This type represents the checksum of a VNF package or an artifact file.\n", + "type": "object", + "required": [ + "algorithm", + "hash" + ], + "properties": { + "algorithm": { + "description": "Name of the algorithm used to generate the checksum, as defined in ETSI GS NFV-SOL 004. For example, SHA-256, SHA-512.\n", + "type": "string" + }, + "hash": { + "description": "The hexadecimal value of the checksum.\n", + "type": "string" + } + } + }, + "metadata": { + "description": "This type represents a list of key-value pairs. The order of the pairs in the list is not significant. In JSON, a set of key- value pairs is represented as an object. It shall comply with the provisions defined in clause 4 of IETF RFC 7159.\n", + "type": "object" + } + } + } + }, + "onboardingState": { + "description": "CREATED: The VNF package resource has been created. UPLOADING: The associated VNF package content is being uploaded. PROCESSING: The associated VNF package content is being processed, e.g., validation.\nONBOARDED: The associated VNF package content has been successfully on-boarded.\n", + "type": "string", + "enum": [ + "CREATED", + "UPLOADING", + "PROCESSING", + "ONBOARDED" + ] + }, + "operationalState": { + "description": "- ENABLED: The VNF package is enabled, i.e. it can be used for instantiation of new VNF instances.\n- DISABLED: The VNF package is disabled, i.e. it cannot be used for further VNF instantiation requests (unless and until the VNF package\n is re-enabled).\n", + "type": "string", + "enum": [ + "ENABLED", + "DISABLED" + ] + }, + "usageState": + { + "description": "- IN_USE: VNF instances instantiated from this VNF package exist. - NOT_IN_USE: No existing VNF instance is instantiated from this VNF package.\n", + "type": "string", + "enum": [ + "IN_USE", + "NOT_IN_USE" + ] + }, + "userDefinedData": { + "description": "This type represents a list of key-value pairs. The order of the pairs in the list is not significant. In JSON, a set of key- value pairs is represented as an object. It shall comply with the provisions defined in clause 4 of IETF RFC 7159.\n", + "type": "object" + }, + "_links": { + "description": "Links to resources related to this resource.\n", + "type": "object", + "required": [ + "self", + "packageContent" + ], + "properties": { + "self": { + "description": "This type represents a link to a resource using an absolute URI. It shall comply with the provisions defined in table 4.4.1.3-1.\n", + "type": "object", + "required": [ + "href" + ], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + }, + "vnfd": { + "description": "This type represents a link to a resource using an absolute URI. It shall comply with the provisions defined in table 4.4.1.3-1.\n", + "type": "object", + "required": [ + "href" + ], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + }, + "packageContent": { + "description": "This type represents a link to a resource using an absolute URI. It shall comply with the provisions defined in table 4.4.1.3-1.\n", + "type": "object", + "required": [ + "href" + ], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + } + } + } + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "405": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "416": { + "description": "416 RANGE NOT SATISFIABLE\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + } + }, + "/vnf_packages/{vnfPkgId}/vnfd": { + "parameters": [ + { + "name": "vnfPkgId", + "description": "Identifier of the on-boarded VNF package. The identifier is allocated by the NFVO. This identifier can be retrieved from the \"vnfPkgId\" attribute in the VnfPackageOnboardingNotification or VnfPackageChangeNotification.\n", + "in": "path", + "type": "string", + "required": true + } + ], + "get": { + "description": "Query VNF Package Info\n\nThe GET method reads the content of the VNFD within a VNF package. The VNFD can be implemented as a single file or as a collection of multiple files. If the VNFD is implemented in the form of multiple files, a ZIP file embedding these files shall be returned. If the VNFD is implemented as a single file, either that file or a ZIP file embedding that file shall be returned. The selection of the format is controlled by the \"Accept\" HTTP header passed in the GET request. * If the \"Accept\" header contains only \"text/plain\" and the VNFD is implemented as a single file, the file shall be returned;\n otherwise, an error message shall be returned.\n* If the \"Accept\" header contains only \"application/zip\", the single file or the multiple files that make up the VNFD shall be returned\n embedded in a ZIP file.\n* If the \"Accept\" header contains both \"text/plain\" and \"application/zip\", it is up to the NFVO to choose the format to\n return for a single-file VNFD; for a multi-file VNFD, a ZIP file\n shall be returned.\nThe default format of the ZIP file shall be the one specified in ETSI GS NFV-SOL 004 where only the YAML files representing the VNFD, and information needed to navigate the ZIP file and to identify the file that is the entry point for parsing the VNFD (such as TOSCA-meta or manifest files or naming conventions) are included.\n", + "parameters": [ + { + "name": "Accept", + "description": "Content-Types that are acceptable for the response. Permitted values: \"text/plain\" and/or \"application/zip\" Reference: IETF RFC 7231\n", + "in": "header", + "required": true, + "type": "string", + "enum": [ + "text/plain", + "application/zip", + "text/plain+application/zip" + ] + }, + { + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, + { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "200 OK\nOn success, the content of the VNFD is returned. The payload body shall contain a copy of the file representing the VNFD or a ZIP file that contains the file or multiple files representing the VNFD, as specified above. The \"Content-Type\" HTTP header shall be set according to the format of the returned file, i.e. to \"text/plain\" for a YAML file or to \"application/zip\" for a ZIP file.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "enum": [ + "text/plain", + "application/zip" + ], + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "405": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "Not Acceptable\nIf the \"Accept\" header does not contain at least one name of a content type for which the NFVO can provide a representation of the VNFD, the NFVO shall respond with this response code. The \"ProblemDetails\" structure may be included with the \"detail\" attribute providing more information about the error.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "409": { + "description": "Conflict\nError: The operation cannot be executed currently, due to a conflict with the state of the resource. Typically, this is due to the fact that \"onboardingState\" of the VNF package has a value different from \"ONBOARDED\". The response body shall contain a ProblemDetails structure, in which the \"detail\" attribute shall convey more information about the error.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "416": { + "description": "416 RANGE NOT SATISFIABLE\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + } + }, + "/vnf_packages/{vnfPkgId}/package_content": { + "parameters": [ + { + "name": "vnfPkgId", + "description": "Identifier of the VNF package. The identifier is allocated by the NFVO. This identifier can be retrieved from the \"vnfPkgId\" attribute in the VnfPackageOnboardingNotification or VnfPackageChangeNotification.\n", + "in": "path", + "type": "string", + "required": true + } + ], + "get": { + "description": "Fetch VNF Package\n\nThe GET method fetches the content of a VNF package identified by the VNF package identifier allocated by the NFVO.\n", + "parameters": [ + { + "name": "Accept", + "description": "Content-Types that are acceptable for the response.\n", + "in": "header", + "required": true, + "type": "string", + "enum": [ + "text/plain", + "application/zip" + ] + }, + { + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, + { + "name": "Range", + "description": "The request may contain a \"Range\" HTTP header to obtain single range of bytes from the VNF package file. This can be used to continue an aborted transmission. If the NFVO does not support range requests, it should return the whole file with a 200 OK response instead.\n", + "in": "header", + "type": "string" + }, + { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "200 OK\nOn success, a copy of the VNF package file is returned. The response body shall include a copy of the VNF package file. The \"Content-Type HTTP\" header shall be set according to the type of the file, i.e. to \"application/zip\" for a VNF Package as defined in ETSI GS NFV-SOL 004.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "206": { + "description": "206 PARTIAL CONTENT\nOn success, if the NFVO supports range requests, a single consecutive byte range from the content of the VNF package file is returned. The response body shall contain the requested part of the VNF package file. The \"Content-Range\" HTTP header shall be provided according to IETF RFC 7233. The \"Content-Type\" HTTP header shall be set as defined above for the \"200 OK\" response.\n", + "headers": { + "Content-Range": { + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "405": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "409": { + "description": "Conflict\nError: The operation cannot be executed currently, due to a conflict with the state of the resource. Typically, this is due to the fact that \"onboardingState\" of the VNF package has a value different from \"ONBOARDED\". The response body shall contain a ProblemDetails structure, in which the \"detail\" attribute shall convey more information about the error.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "416": { + "description": "Requested Range Not Satisfiable\nThe byte range passed in the \"Range\" header did not match any available byte range in the VNF package file (e.g. \"access after end of file\"). The response body may contain a ProblemDetails structure.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + } + }, + "/vnf_packages/{vnfPkgId}/artifacts/{artifactPath}": { + "parameters": [ + { + "name": "artifactPath", + "description": "Sequence of one or more path segments representing the path of the artifact within the VNF package. EXAMPLE: foo/bar/run.sh This identifier can be retrieved from the \"artifactPath\" attribute of the applicable \"additionalArtifacts\" entry in the body of the response to a GET request querying the \"Individual VNF package\" or the \"VNF packages\" resource.\n", + "in": "path", + "type": "string", + "required": true + }, + { + "name": "vnfPkgId", + "description": "Identifier of the VNF package. The identifier is allocated by the NFVO. This identifier can be retrieved from the \"vnfPkgId\" attribute in the VnfPackageOnboardingNotification or VnfPackageChangeNotification.\n", + "in": "path", + "type": "string", + "required": true + } + ], + "get": { + "description": "Fetch VNF Package Artifacts\n\nThe GET method fetches the content of an artifact within a VNF package.\n", + "parameters": [ + { + "name": "Accept", + "description": "Content-Types that are acceptable for the response.\n", + "in": "header", + "required": true, + "type": "string" + }, + { + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, + { + "name": "Range", + "description": "The request may contain a \"Range\" HTTP header to obtain single range of bytes from the VNF package file. This can be used to continue an aborted transmission. If the NFVO does not support range requests, it should return the whole file with a 200 OK response instead.\n", + "in": "header", + "type": "string" + }, + { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "200 OK\nOn success, the content of the artifact is returned. The payload body shall contain a copy of the artifact file from the VNF package, as defined by ETSI GS NFV-SOL 004. The \"Content-Type\" HTTP header shall be set according to the content type of the artifact file. If the content type cannot be determined, the header shall be set to the value \"application/octet-stream\".\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response. The \"Content-Type\" HTTP header shall be set according to the content type of the artifact file. If the content type cannot be determined, the header shall be set to the value \"application/octet-stream\".\n", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "206": { + "description": "206 PARTIAL CONTENT\nOn success, if the NFVO supports range requests, a single consecutive byte range from the content of the VNF package file is returned. The response body shall contain the requested part of the VNF package file. The \"Content-Range\" HTTP header shall be provided according to IETF RFC 7233. The \"Content-Type\" HTTP header shall be set as defined above for the \"200 OK\" response.\n", + "headers": { + "Content-Range": { + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "405": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "409": { + "description": "Conflict\nError: The operation cannot be executed currently, due to a conflict with the state of the resource. Typically, this is due to the fact that \"onboardingState\" of the VNF package has a value different from \"ONBOARDED\". The response body shall contain a ProblemDetails structure, in which the \"detail\" attribute shall convey more information about the error.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "416": { + "description": "Requested Range Not Satisfiable\nThe byte range passed in the \"Range\" header did not match any available byte range in the VNF package file (e.g. \"access after end of file\"). The response body may contain a ProblemDetails structure.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + } + }, + "/subscriptions": { + "post": { + "description": "Subscribe\n\nThe POST method creates a new subscription. Creation of two subscription resources with the same callbackURI and the same filter can result in performance degradation and will provide duplicates of notifications to the VNFM, and might make sense only in very rare use cases. Consequently, the NFVO may either allow creating a subscription resource if another subscription resource with the same filter and callbackUri already exists (in which case it shall return the “201 Created” response code), or may decide to not create a duplicate subscription resource (in which case it shall return a “303 See Other” response code referencing the existing subscription resource with the same filter and callbackUri).\n", + "parameters": [ + { + "name": "PkgmSubscriptionRequest", + "description": "Representation of the created subscription resource. The HTTP response shall include a \"Location\" HTTP header that points to the created subscription resource.\n", + "in": "body", + "required": true, + "schema": { + "description": "This type represents a subscription request related to VNF package management notifications about VNF package on-boarding or changes.\n", + "type": "object", + "required": [ + "callbackUri" + ], + "properties": { + "filter": { + "description": "This type represents a subscription filter related to notifications related to VNF package management. At a particular nesting level in the filter structure, the following applies: All attributes shall match in order for the filter to match (logical \"and\" between different filter attributes). If an attribute is an array, the attribute shall match if at least one of the values in the array matches (logical \"or\" between the values of one filter attribute).\n", + "type": "object", + "properties": { + "notificationTypes": { + "description": "Match particular notification types. Permitted values: - VnfPackageOnboardingNotification - VnfPackageChangeNotification The permitted values of the \"notificationTypes\" attribute are spelled exactly as the names of the notification types to facilitate automated code generation systems.\n", + "type": "array", + "items": { + "type": "string", + "enum": [ + "VnfPackageOnboardingNotification", + "VnfPackageChangeNotification" + ] + } + }, + "vnfProductsFromProviders": { + "description": "If present, match VNF packages that contain VNF products from certain providers. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfProvider" + ], + "properties": { + "vnfProvider": { + "description": "Name of the VNF provider to match.\n", + "type": "string" + }, + "vnfProducts": { + "description": "If present, match VNF packages that contain VNF products with certain product names, from one particular provider.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfProductName" + ], + "properties": { + "vnfProductName": { + "description": "Name of the VNF product to match.\n", + "type": "string" + }, + "versions": { + "description": "If present, match VNF packages that contain VNF products with certain versions and a certain product name, from one particular provider.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfSoftwareVersion" + ], + "properties": { + "vnfSoftwareVersion": { + "description": "A Version.\n", + "type": "string" + }, + "vnfdVersions": { + "description": "If present, match VNF packages that contain VNF products with certain VNFD versions, a certain software version and a certain product name, from one particular provider.\n", + "type": "array", + "items": { + "description": "A Version.\n", + "type": "string" + } + } + } + } + } + } + } + } + } + } + }, + "vnfdId": { + "description": "Match VNF packages with a VNFD identifier listed in the attribute. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + } + }, + "vnfPkgId": { + "description": "Match VNF packages with a package identifier listed in the attribute. May be present if the \"notificationTypes\" attribute contains the value \"VnfPackageChangeNotification\", and shall be absent otherwise. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + } + }, + "operationalState": + { + "description": "- ENABLED: The VNF package is enabled, i.e. it can be used for instantiation of new VNF instances.\n- DISABLED: The VNF package is disabled, i.e. it cannot be used for further VNF instantiation requests (unless and until the VNF package\n is re-enabled).\n", + "type": "array", + "items": + { + "type": "string", + "enum": [ + "ENABLED", + "DISABLED" + ] + } + }, + "usageState": + { + "description": "- IN_USE: VNF instances instantiated from this VNF package exist. - NOT_IN_USE: No existing VNF instance is instantiated from this VNF package.\n", + "type": "array", + "items": + { + "type": "string", + "enum": [ + "IN_USE", + "NOT_IN_USE" + ] + } + } + } + }, + "callbackUri": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + }, + "authentication": { + "type": "object", + "required": [ + "authType" + ], + "properties": { + "authType": { + "description": "Defines the types of Authentication / Authorization which the API consumer is willing to accept when receiving a notification. Permitted values: * BASIC: In every HTTP request to the notification endpoint, use HTTP Basic authentication with the client credentials. \n* OAUTH2_CLIENT_CREDENTIALS: In every HTTP request to the notification endpoint, use an OAuth 2.0 Bearer token, obtained\n using the client credentials grant type.\n* TLS_CERT: Every HTTP request to the notification endpoint is sent over a mutually authenticated TLS session, i.e. not only the\n server is authenticated, but also the client is authenticated\n during the TLS tunnel setup.\n", + "type": "array", + "items": { + "type": "string", + "enum": [ + "BASIC", + "OAUTH2_CLIENT_CREDENTIALS", + "TLS_CERT" + ] + } + }, + "paramsBasic": { + "description": "Parameters for authentication/authorization using BASIC. Shall be present if authType is \"BASIC\" and the contained information has not been provisioned out of band. Shall be absent otherwise.\n", + "type": "object", + "properties": { + "userName": { + "description": "Username to be used in HTTP Basic authentication. Shall be present if it has not been provisioned out of band.\n", + "type": "string" + }, + "password": { + "description": "Password to be used in HTTP Basic authentication. Shall be present if it has not been provisioned out of band.\n", + "type": "string" + } + } + }, + "paramsOauth2ClientCredentials": { + "description": "Parameters for authentication/authorization using OAUTH2_CLIENT_CREDENTIALS. Shall be present if authType is \"OAUTH2_CLIENT_CREDENTIALS\" and the contained information has not been provisioned out of band. Shall be absent otherwise.\n", + "type": "object", + "properties": { + "clientId": { + "description": "Client identifier to be used in the access token request of the OAuth 2.0 client credentials grant type. Shall be present if it has not been provisioned out of band. The clientId and clientPassword passed in a subscription shall not be the same as the clientId and clientPassword that are used to obtain authorization for API requests. Client credentials may differ between subscriptions. The value of clientPassword should be generated by a random process.\n", + "type": "string" + }, + "clientPassword": { + "description": "Client password to be used in the access token request of the OAuth 2.0 client credentials grant type. Shall be present if it has not been provisioned out of band. The clientId and clientPassword passed in a subscription shall not be the same as the clientId and clientPassword that are used to obtain authorization for API requests. Client credentials may differ between subscriptions. The value of clientPassword should be generated by a random process.\n", + "type": "string" + }, + "tokenEndpoint": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + } + } + } + } + } + }, + { + "name": "Accept", + "description": "Content-Types that are acceptable for the response. Reference: IETF RFC 7231\n", + "in": "header", + "required": true, + "type": "string" + }, + { + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, + { + "name": "Content-Type", + "description": "The MIME type of the body of the request. Reference: IETF RFC 7231\n", + "in": "header", + "required": true, + "type": "string" + }, + { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + } + ], + "responses": { + "201": { + "description": "201 CREATED\nRepresentation of the created subscription resource. The HTTP response shall include a \"Location\" HTTP header that points to the created subscription resource.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "Location": { + "description": "The resource URI of the created VNF instance", + "type": "string", + "format": "url" + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "type": "array", + "items": { + "description": "This type represents a subscription related to notifications about VNF package management.\n", + "type": "object", + "required": [ + "id", + "callbackUri", + "_links" + ], + "properties": { + "id": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "filter": { + "description": "This type represents a subscription filter related to notifications related to VNF package management. At a particular nesting level in the filter structure, the following applies: All attributes shall match in order for the filter to match (logical \"and\" between different filter attributes). If an attribute is an array, the attribute shall match if at least one of the values in the array matches (logical \"or\" between the values of one filter attribute).\n", + "type": "object", + "properties": { + "notificationTypes": { + "description": "Match particular notification types. Permitted values: - VnfPackageOnboardingNotification - VnfPackageChangeNotification The permitted values of the \"notificationTypes\" attribute are spelled exactly as the names of the notification types to facilitate automated code generation systems.\n", + "type": "array", + "items": { + "type": "string", + "enum": [ + "VnfPackageOnboardingNotification", + "VnfPackageChangeNotification" + ] + } + }, + "vnfProductsFromProviders": { + "description": "If present, match VNF packages that contain VNF products from certain providers. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfProvider" + ], + "properties": { + "vnfProvider": { + "description": "Name of the VNF provider to match.\n", + "type": "string" + }, + "vnfProducts": { + "description": "If present, match VNF packages that contain VNF products with certain product names, from one particular provider.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfProductName" + ], + "properties": { + "vnfProductName": { + "description": "Name of the VNF product to match.\n", + "type": "string" + }, + "versions": { + "description": "If present, match VNF packages that contain VNF products with certain versions and a certain product name, from one particular provider.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfSoftwareVersion" + ], + "properties": { + "vnfSoftwareVersion": { + "description": "A Version.\n", + "type": "string" + }, + "vnfdVersions": { + "description": "If present, match VNF packages that contain VNF products with certain VNFD versions, a certain software version and a certain product name, from one particular provider.\n", + "type": "array", + "items": { + "description": "A Version.\n", + "type": "string" + } + } + } + } + } + } + } + } + } + } + }, + "vnfdId": { + "description": "Match VNF packages with a VNFD identifier listed in the attribute. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + } + }, + "vnfPkgId": { + "description": "Match VNF packages with a package identifier listed in the attribute. May be present if the \"notificationTypes\" attribute contains the value \"VnfPackageChangeNotification\", and shall be absent otherwise. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + } + }, + "operationalState": + { + "description": "- ENABLED: The VNF package is enabled, i.e. it can be used for instantiation of new VNF instances.\n- DISABLED: The VNF package is disabled, i.e. it cannot be used for further VNF instantiation requests (unless and until the VNF package\n is re-enabled).\n", + "type": "array", + "items": + { + "type": "string", + "enum": [ + "ENABLED", + "DISABLED" + ] + } + }, + "usageState": + { + "description": "- IN_USE: VNF instances instantiated from this VNF package exist. - NOT_IN_USE: No existing VNF instance is instantiated from this VNF package.\n", + "type": "array", + "items": + { + "type": "string", + "enum": [ + "IN_USE", + "NOT_IN_USE" + ] + } + } } + }, + "callbackUri": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + }, + "_links": { + "description": "Links to resources related to this resource.\n", + "type": "object", + "required": [ + "self" + ], + "properties": { + "self": { + "description": "This type represents a link to a resource using an absolute URI. It shall comply with the provisions defined in table 4.4.1.3-1.\n", + "type": "object", + "required": [ + "href" + ], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + } + } + } + } + } + } + }, + "303": { + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "405": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "416": { + "description": "416 RANGE NOT SATISFIABLE\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + }, + "get": { + "description": "Query Subscription Information\n\nThe GET method queries the list of active subscriptions of the functional block that invokes the method. It can be used e.g. for resynchronization after error situations.\n", + "parameters": [ + { + "name": "Accept", + "description": "Content-Types that are acceptable for the response. Reference: IETF RFC 7231\n", + "in": "header", + "required": true, + "type": "string" + }, + { + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, + { + "name": "filter", + "description": "Attribute-based filtering expression according to clause 4.3.2. The VNFM shall support receiving this parameter as part of the URI query string. The NFVO may supply this parameter. All attribute names that appear in the PkgmSubscription and in data types referenced from it shall be supported by the VNFM in the filter expression.\n", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "nextpage_opaque_marker", + "description": "Marker to obtain the next page of a paged response. Shall be supported by the VNFM if the VNFM supports alternative 2 (paging) according to clause 4.7.2.1 for this resource.\n", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "200 OK\nThe list of subscriptions was queried successfully. The representations body shall contain in an array the representations of all active subscriptions of the functional block that invokes the method , i.e. zero or more representations of VNF package Management subscriptions as defined in clause 10.5.2.4. If the VNFM supports alternative 2 (paging) according to clause 4.7.2.1 for this resource, inclusion of the Link HTTP header in this response shall follow the provisions in clause 4.7.2.3.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "Link": { + "description": "Reference to other resources. Used for paging in the present document, see clause 4.7.2.1.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + } + }, + "schema": { + "type": "array", + "items": { + "description": "This type represents a subscription related to notifications about VNF package management.\n", + "type": "object", + "required": [ + "id", + "callbackUri", + "_links" + ], + "properties": { + "id": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "filter": { + "description": "This type represents a subscription filter related to notifications related to VNF package management. At a particular nesting level in the filter structure, the following applies: All attributes shall match in order for the filter to match (logical \"and\" between different filter attributes). If an attribute is an array, the attribute shall match if at least one of the values in the array matches (logical \"or\" between the values of one filter attribute).\n", + "type": "object", + "properties": { + "notificationTypes": { + "description": "Match particular notification types. Permitted values: - VnfPackageOnboardingNotification - VnfPackageChangeNotification The permitted values of the \"notificationTypes\" attribute are spelled exactly as the names of the notification types to facilitate automated code generation systems.\n", + "type": "array", + "items": { + "type": "string", + "enum": [ + "VnfPackageOnboardingNotification", + "VnfPackageChangeNotification" + ] + } + }, + "vnfProductsFromProviders": { + "description": "If present, match VNF packages that contain VNF products from certain providers. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfProvider" + ], + "properties": { + "vnfProvider": { + "description": "Name of the VNF provider to match.\n", + "type": "string" + }, + "vnfProducts": { + "description": "If present, match VNF packages that contain VNF products with certain product names, from one particular provider.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfProductName" + ], + "properties": { + "vnfProductName": { + "description": "Name of the VNF product to match.\n", + "type": "string" + }, + "versions": { + "description": "If present, match VNF packages that contain VNF products with certain versions and a certain product name, from one particular provider.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfSoftwareVersion" + ], + "properties": { + "vnfSoftwareVersion": { + "description": "A Version.\n", + "type": "string" + }, + "vnfdVersions": { + "description": "If present, match VNF packages that contain VNF products with certain VNFD versions, a certain software version and a certain product name, from one particular provider.\n", + "type": "array", + "items": { + "description": "A Version.\n", + "type": "string" + } + } + } + } + } + } + } + } + } + } + }, + "vnfdId": { + "description": "Match VNF packages with a VNFD identifier listed in the attribute. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + } + }, + "vnfPkgId": { + "description": "Match VNF packages with a package identifier listed in the attribute. May be present if the \"notificationTypes\" attribute contains the value \"VnfPackageChangeNotification\", and shall be absent otherwise. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + } + }, + "operationalState": { + "description": "- ENABLED: The VNF package is enabled, i.e. it can be used for instantiation of new VNF instances.\n- DISABLED: The VNF package is disabled, i.e. it cannot be used for further VNF instantiation requests (unless and until the VNF package\n is re-enabled).\n", + "type": "string", + "enum": [ + "ENABLED", + "DISABLED" + ] + }, + "usageState": { + "description": "- IN_USE: VNF instances instantiated from this VNF package exist. - NOT_IN_USE: No existing VNF instance is instantiated from this VNF package.\n" + } + } + }, + "callbackUri": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + }, + "_links": { + "description": "Links to resources related to this resource.\n", + "type": "object", + "required": [ + "self" + ], + "properties": { + "self": { + "description": "This type represents a link to a resource using an absolute URI. It shall comply with the provisions defined in table 4.4.1.3-1.\n", + "type": "object", + "required": [ + "href" + ], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + } + } + } + } + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "405": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "416": { + "description": "416 RANGE NOT SATISFIABLE\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + } + }, + "/subscriptions/{subscriptionId}": { + "parameters": [ + { + "name": "subscriptionId", + "description": "Identifier of this subscription. This identifier can be retrieved from the resource referenced by the \"Location\" HTTP header in the response to a POST request creating a new subscription resource. It can also be retrieved from the \"id\" attribute in the payload body of that response.\n", + "in": "path", + "type": "string", + "required": true + } + ], + "get": { + "description": "Query Subscription Information\n\nThe GET method reads an individual subscription.\n", + "parameters": [ + { + "name": "Accept", + "description": "Content-Types that are acceptable for the response. Reference: IETF RFC 7231\n", + "in": "header", + "required": true, + "type": "string" + }, + { + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, + { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "200 OK\nRepresentation of the subscription resource.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "This type represents a subscription related to notifications about VNF package management.\n", + "type": "object", + "required": [ + "id", + "callbackUri", + "_links" + ], + "properties": { + "id": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "filter": { + "description": "This type represents a subscription filter related to notifications related to VNF package management. At a particular nesting level in the filter structure, the following applies: All attributes shall match in order for the filter to match (logical \"and\" between different filter attributes). If an attribute is an array, the attribute shall match if at least one of the values in the array matches (logical \"or\" between the values of one filter attribute).\n", + "type": "object", + "properties": { + "notificationTypes": { + "description": "Match particular notification types. Permitted values: - VnfPackageOnboardingNotification - VnfPackageChangeNotification The permitted values of the \"notificationTypes\" attribute are spelled exactly as the names of the notification types to facilitate automated code generation systems.\n", + "type": "array", + "items": { + "type": "string", + "enum": [ + "VnfPackageOnboardingNotification", + "VnfPackageChangeNotification" + ] + } + }, + "vnfProductsFromProviders": { + "description": "If present, match VNF packages that contain VNF products from certain providers. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfProvider" + ], + "properties": { + "vnfProvider": { + "description": "Name of the VNF provider to match.\n", + "type": "string" + }, + "vnfProducts": { + "description": "If present, match VNF packages that contain VNF products with certain product names, from one particular provider.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfProductName" + ], + "properties": { + "vnfProductName": { + "description": "Name of the VNF product to match.\n", + "type": "string" + }, + "versions": { + "description": "If present, match VNF packages that contain VNF products with certain versions and a certain product name, from one particular provider.\n", + "type": "array", + "items": { + "type": "object", + "required": [ + "vnfSoftwareVersion" + ], + "properties": { + "vnfSoftwareVersion": { + "description": "A Version.\n", + "type": "string" + }, + "vnfdVersions": { + "description": "If present, match VNF packages that contain VNF products with certain VNFD versions, a certain software version and a certain product name, from one particular provider.\n", + "type": "array", + "items": { + "description": "A Version.\n", + "type": "string" + } + } + } + } + } + } + } + } + } + } + }, + "vnfdId": { + "description": "Match VNF packages with a VNFD identifier listed in the attribute. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + } + }, + "vnfPkgId": { + "description": "Match VNF packages with a package identifier listed in the attribute. May be present if the \"notificationTypes\" attribute contains the value \"VnfPackageChangeNotification\", and shall be absent otherwise. The attributes \"vnfProductsFromProviders\", \"vnfdId\" and \"vnfPkgId\" are alternatives to reference to particular VNF packages in a filter. They should not be used both in the same filter instance, but one alternative should be chosen.\n", + "type": "array", + "items": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + } + }, + "operationalState": { + "description": "- ENABLED: The VNF package is enabled, i.e. it can be used for instantiation of new VNF instances.\n- DISABLED: The VNF package is disabled, i.e. it cannot be used for further VNF instantiation requests (unless and until the VNF package\n is re-enabled).\n", + "type": "string", + "enum": [ + "ENABLED", + "DISABLED" + ] + }, + "usageState": { + "description": "- IN_USE: VNF instances instantiated from this VNF package exist. - NOT_IN_USE: No existing VNF instance is instantiated from this VNF package.\n" + } + } + }, + "callbackUri": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + }, + "_links": { + "description": "Links to resources related to this resource.\n", + "type": "object", + "required": [ + "self" + ], + "properties": { + "self": { + "description": "This type represents a link to a resource using an absolute URI. It shall comply with the provisions defined in table 4.4.1.3-1.\n", + "type": "object", + "required": [ + "href" + ], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + } + } + } + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "405": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "416": { + "description": "416 RANGE NOT SATISFIABLE\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + }, + "delete": { + "description": "Terminate subscription\n\nThe DELETE method terminates an individual subscription.\n", + "parameters": [ + { + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, + { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + } + ], + "responses": { + "204": { + "description": "204 NO CONTENT\nThe subscription resource was deleted successfully.\n", + "headers": { + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "405": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "416": { + "description": "416 RANGE NOT SATISFIABLE\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": [ + "status", + "detail" + ], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + } + } + } +}
\ No newline at end of file diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-ext-clients/pom.xml b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-ext-clients/pom.xml new file mode 100644 index 0000000000..6e6de84b5f --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-ext-clients/pom.xml @@ -0,0 +1,197 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.so.adapters</groupId> + <artifactId>etsi-sol003-pkgm</artifactId> + <version>1.6.0-SNAPSHOT</version> + </parent> + <artifactId>etsi-sol003-pkgm-ext-clients</artifactId> + <name>ETSI SOL003 VNF Package Management Adapter Ext Clients</name> + <build> + <plugins> + <plugin> + <groupId>io.swagger</groupId> + <artifactId>swagger-codegen-maven-plugin</artifactId> + <version>${version-swagger-codegen}</version> + <executions> + <execution> + <id>etsicatalog-api</id> + <goals> + <goal>generate</goal> + </goals> + <configuration> + <inputSpec>${basedir}/src/main/resources/ETSI-Catalog-API.json</inputSpec> + <language>java</language> + <library>okhttp-gson</library> + <output>${project.build.directory}/generated-sources/etsicatalog</output> + <apiPackage>org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.api</apiPackage> + <modelPackage>org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model</modelPackage> + <generateApiTests>false</generateApiTests> + <generateModelTests>false</generateModelTests> + <configOptions> + <sourceFolder>src/gen/java/main</sourceFolder> + <withXml>true</withXml> + <useRxJava2>true</useRxJava2> + <serializableModel>true</serializableModel> + </configOptions> + </configuration> + </execution> + <execution> + <id>sol003-packagemanagement-notification-api</id> + <goals> + <goal>generate</goal> + </goals> + <configuration> + <inputSpec>${basedir}/src/main/resources/SOL003-VNFPackageManagement-Notification-API.json</inputSpec> + <language>java</language> + <library>okhttp-gson</library> + <output>${project.build.directory}/generated-sources/sol003-vnf-packagemanagement/notification</output> + <apiPackage>org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.api</apiPackage> + <modelPackage>org.onap.so.adapters.etsisol003adapter.pkgm.extclients.vnfm.notification.model</modelPackage> + <generateApiTests>false</generateApiTests> + <generateModelTests>false</generateModelTests> + <configOptions> + <sourceFolder>src/gen/java/main</sourceFolder> + <withXml>true</withXml> + <useRxJava2>true</useRxJava2> + <serializableModel>true</serializableModel> + <dateLibrary>java8-localdatetime</dateLibrary> + </configOptions> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>add-source</id> + <phase>generate-sources</phase> + <goals> + <goal>add-source</goal> + </goals> + <configuration> + <sources> + <source>${project.basedir}/target/generated-sources/sol003-vnf-packagemanagement/notification/src/gen/java/main</source> + <source>${project.basedir}/target/generated-sources/etsicatalog/src/gen/java/main</source> + </sources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.eclipse.m2e</groupId> + <artifactId>lifecycle-mapping</artifactId> + <version>1.0.0</version> + <configuration> + <lifecycleMappingMetadata> + <pluginExecutions> + <pluginExecution> + <pluginExecutionFilter> + <groupId>io.swagger</groupId> + <artifactId>swagger-codegen-maven-plugin</artifactId> + <goals> + <goal>generate</goal> + </goals> + <versionRange>[2.2.0,)</versionRange> + </pluginExecutionFilter> + <action> + <execute> + <runOnIncremental>false</runOnIncremental> + </execute> + </action> + </pluginExecution> + </pluginExecutions> + </lifecycleMappingMetadata> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + <dependencies> + <dependency> + <groupId>io.swagger</groupId> + <artifactId>swagger-annotations</artifactId> + <version>${swagger-core-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.retrofit2</groupId> + <artifactId>converter-gson</artifactId> + <version>${retrofit-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.retrofit2</groupId> + <artifactId>retrofit</artifactId> + <version>${retrofit-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.retrofit2</groupId> + <artifactId>converter-scalars</artifactId> + <version>${retrofit-version}</version> + </dependency> + <dependency> + <groupId>org.apache.oltu.oauth2</groupId> + <artifactId>org.apache.oltu.oauth2.client</artifactId> + <version>${oltu-version}</version> + </dependency> + <dependency> + <groupId>io.gsonfire</groupId> + <artifactId>gson-fire</artifactId> + <version>${gson-fire-version}</version> + </dependency> + <dependency> + <groupId>org.threeten</groupId> + <artifactId>threetenbp</artifactId> + <version>${threetenbp-version}</version> + </dependency> + <dependency> + <groupId>io.reactivex.rxjava2</groupId> + <artifactId>rxjava</artifactId> + </dependency> + <dependency> + <groupId>com.squareup.retrofit2</groupId> + <artifactId>adapter-rxjava2</artifactId> + <version>${retrofit-version}</version> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + <dependency> + <groupId>com.squareup.okio</groupId> + <artifactId>okio</artifactId> + <version>${okio-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp3</groupId> + <artifactId>okhttp</artifactId> + <version>${okhttp3-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp3</groupId> + <artifactId>logging-interceptor</artifactId> + <version>${okhttp3-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp</groupId> + <artifactId>logging-interceptor</artifactId> + <version>${okhttp-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp</groupId> + <artifactId>okhttp</artifactId> + <version>${okhttp-version}</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp</groupId> + <artifactId>logging-interceptor</artifactId> + <version>${okhttp-version}</version> + </dependency> + </dependencies> + +</project> diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-ext-clients/src/main/resources/ETSI-Catalog-API.json b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-ext-clients/src/main/resources/ETSI-Catalog-API.json new file mode 100644 index 0000000000..35a8c2bd3d --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-ext-clients/src/main/resources/ETSI-Catalog-API.json @@ -0,0 +1,3121 @@ +{ + "swagger": "2.0", + "info": { + "title": "Modeling etsicatalog API", + "description": "\n\nThe `swagger-ui` view can be found [here](/api/catalog/v1/swagger).\nThe `ReDoc` view can be found [here](/api/catalog/v1/redoc).\nThe swagger YAML document can be found [here](/api/catalog/v1/swagger.yaml).\nThe swagger JSON document can be found [here](/api/catalog/v1/swagger.json).", + "version": "v1" + }, + "host": "127.0.0.1:8806", + "schemes": ["http"], + "basePath": "/", + "consumes": ["application/json"], + "produces": ["application/json"], + "securityDefinitions": { + "Basic": { + "type": "basic" + } + }, + "security": [{ + "Basic": [] + }], + "paths": { + "/api/catalog/v1/callback_sample": { + "get": { + "operationId": "api_catalog_v1_callback_sample_list", + "description": "Callback Sample.", + "parameters": [], + "responses": { + "200": { + "description": "" + } + }, + "tags": ["Sample interface"] + }, + "parameters": [] + }, + "/api/catalog/v1/health_check": { + "get": { + "operationId": "api_catalog_v1_health_check_list", + "description": "", + "parameters": [], + "responses": { + "200": { + "description": "Active" + } + }, + "tags": ["Health Check interface"] + }, + "parameters": [] + }, + "/api/catalog/v1/jobs/{job_id}": { + "get": { + "operationId": "api_catalog_v1_jobs_read", + "description": "Get job status", + "parameters": [{ + "name": "job_id", + "in": "query", + "description": "job id", + "type": "string" + }, { + "name": "responseId", + "in": "query", + "description": "response id", + "type": "string" + }], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/GetJobResponse" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/PostJobResponseResult" + } + } + }, + "tags": ["Catalog interface"] + }, + "post": { + "operationId": "api_catalog_v1_jobs_create", + "description": "Update job status", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PostJobRequest" + } + }, { + "name": "job_id", + "in": "query", + "description": "job id", + "type": "string" + }], + "responses": { + "202": { + "description": "", + "schema": { + "$ref": "#/definitions/PostJobResponseResult" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/PostJobResponseResult" + } + } + }, + "tags": ["Catalog interface"] + }, + "parameters": [{ + "name": "job_id", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/catalog/v1/mandb/{modelName}": { + "get": { + "operationId": "api_catalog_v1_mandb_read", + "description": "", + "parameters": [], + "responses": { + "200": { + "description": "" + } + }, + "tags": ["Sample interface"] + }, + "delete": { + "operationId": "api_catalog_v1_mandb_delete", + "description": "", + "parameters": [], + "responses": { + "204": { + "description": "" + } + }, + "tags": ["Sample interface"] + }, + "parameters": [{ + "name": "modelName", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/catalog/v1/nspackages": { + "get": { + "operationId": "api_catalog_v1_nspackages_list", + "description": "Query NS packages", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/NsPackage" + } + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Catalog interface"] + }, + "post": { + "operationId": "api_catalog_v1_nspackages_create", + "description": "On distribute NS package", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/NsPackageDistributeRequest" + } + }], + "responses": { + "202": { + "description": "", + "schema": { + "$ref": "#/definitions/NsPackageDistributeResponse" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Catalog interface"] + }, + "parameters": [] + }, + "/api/catalog/v1/nspackages/{csarId}": { + "get": { + "operationId": "api_catalog_v1_nspackages_read", + "description": "Query one NS package", + "parameters": [{ + "name": "csarId", + "in": "query", + "description": "csarId", + "type": "string" + }], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/NsPackage" + } + }, + "500": { + "description": "error message", + "schema": { + "type": "string" + } + } + }, + "tags": ["Catalog interface"] + }, + "delete": { + "operationId": "api_catalog_v1_nspackages_delete", + "description": "Delete one NS package", + "parameters": [{ + "name": "csarId", + "in": "query", + "description": "csarId", + "type": "string" + }], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/NsPackageDistributeResponse" + } + }, + "500": { + "description": "error message", + "schema": { + "type": "string" + } + } + }, + "tags": ["Catalog interface"] + }, + "parameters": [{ + "name": "csarId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/catalog/v1/service_packages": { + "get": { + "operationId": "api_catalog_v1_service_packages_list", + "description": "Query Service packages", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/ServicePackage" + } + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Catalog interface"] + }, + "post": { + "operationId": "api_catalog_v1_service_packages_create", + "description": "On distribute Service package", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ServicePackageDistributeRequest" + } + }], + "responses": { + "202": { + "description": "" + }, + "400": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Catalog interface"] + }, + "parameters": [] + }, + "/api/catalog/v1/service_packages/{csarId}": { + "get": { + "operationId": "api_catalog_v1_service_packages_read", + "description": "Query one Service package", + "parameters": [{ + "name": "csarId", + "in": "query", + "description": "csarId", + "type": "string" + }], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/ServicePackage" + } + }, + "404": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Catalog interface"] + }, + "delete": { + "operationId": "api_catalog_v1_service_packages_delete", + "description": "Delete one Service package", + "parameters": [{ + "name": "csarId", + "in": "query", + "description": "csarId", + "type": "string" + }], + "responses": { + "204": { + "description": "" + }, + "404": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Catalog interface"] + }, + "parameters": [{ + "name": "csarId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/catalog/v1/vnfpackages": { + "get": { + "operationId": "api_catalog_v1_vnfpackages_list", + "description": "Query Nf packages", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/NfPackage" + } + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Catalog interface"] + }, + "post": { + "operationId": "api_catalog_v1_vnfpackages_create", + "description": "On distribute Nf package", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/NfPackageDistributeRequest" + } + }], + "responses": { + "202": { + "description": "", + "schema": { + "$ref": "#/definitions/PostJobResponse" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Catalog interface"] + }, + "parameters": [] + }, + "/api/catalog/v1/vnfpackages/{csarId}": { + "get": { + "operationId": "api_catalog_v1_vnfpackages_read", + "description": "Query one Nf package", + "parameters": [{ + "name": "csarId", + "in": "query", + "description": "csarId", + "type": "string" + }], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/NfPackage" + } + }, + "500": { + "description": "error message", + "schema": { + "type": "string" + } + } + }, + "tags": ["Catalog interface"] + }, + "delete": { + "operationId": "api_catalog_v1_vnfpackages_delete", + "description": "Delete one Nf package", + "parameters": [{ + "name": "csarId", + "in": "query", + "description": "csarId", + "type": "string" + }], + "responses": { + "202": { + "description": "", + "schema": { + "$ref": "#/definitions/PostJobResponse" + } + }, + "500": { + "description": "error message", + "schema": { + "type": "string" + } + } + }, + "tags": ["Catalog interface"] + }, + "parameters": [{ + "name": "csarId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/nsd/v1/health_check": { + "get": { + "operationId": "api_nsd_v1_health_check_list", + "description": "", + "parameters": [], + "responses": { + "200": { + "description": "Active" + } + }, + "tags": ["Health Check interface"] + }, + "parameters": [] + }, + "/api/nsd/v1/ns_descriptors": { + "get": { + "operationId": "api_nsd_v1_ns_descriptors_list", + "description": "Query multiple NSDs", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/NsdInfo" + } + } + }, + "500": { + "description": "Internal error" + } + }, + "tags": ["NSD Management interface"] + }, + "post": { + "operationId": "api_nsd_v1_ns_descriptors_create", + "description": "Create a NSD", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateNsdInfoRequest" + } + }], + "responses": { + "201": { + "description": "", + "schema": { + "$ref": "#/definitions/NsdInfo" + } + }, + "500": { + "description": "Internal error" + } + }, + "tags": ["NSD Management interface"] + }, + "parameters": [] + }, + "/api/nsd/v1/ns_descriptors/{nsdInfoId}": { + "get": { + "operationId": "api_nsd_v1_ns_descriptors_read", + "description": "Query a NSD", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/NsdInfo" + } + }, + "404": { + "description": "NSDs do not exist" + }, + "500": { + "description": "Internal error" + } + }, + "tags": ["NSD Management interface"] + }, + "delete": { + "operationId": "api_nsd_v1_ns_descriptors_delete", + "description": "Delete a NSD", + "parameters": [], + "responses": { + "204": { + "description": "No content" + }, + "500": { + "description": "Internal error" + } + }, + "tags": ["NSD Management interface"] + }, + "parameters": [{ + "name": "nsdInfoId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/nsd/v1/ns_descriptors/{nsdInfoId}/nsd_content": { + "get": { + "operationId": "api_nsd_v1_ns_descriptors_nsd_content_list", + "description": "Download NSD content", + "parameters": [], + "responses": { + "204": { + "description": "No content" + }, + "404": { + "description": "NSD does not exist." + }, + "500": { + "description": "Internal error" + } + }, + "tags": ["NSD Management interface"] + }, + "put": { + "operationId": "api_nsd_v1_ns_descriptors_nsd_content_update", + "description": "Upload NSD content", + "parameters": [], + "responses": { + "204": { + "description": "PNFD file" + }, + "500": { + "description": "Internal error" + } + }, + "tags": ["NSD Management interface"] + }, + "parameters": [{ + "name": "nsdInfoId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/nsd/v1/pnf_descriptors": { + "get": { + "operationId": "api_nsd_v1_pnf_descriptors_list", + "description": "Query multiple PNFDs", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PnfdInfo" + } + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["NSD Management interface"] + }, + "post": { + "operationId": "api_nsd_v1_pnf_descriptors_create", + "description": "Create a PNFD", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreatePnfdInfoRequest" + } + }], + "responses": { + "201": { + "description": "", + "schema": { + "$ref": "#/definitions/PnfdInfo" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["NSD Management interface"] + }, + "parameters": [] + }, + "/api/nsd/v1/pnf_descriptors/{pnfdInfoId}": { + "get": { + "operationId": "api_nsd_v1_pnf_descriptors_read", + "description": "Query a PNFD", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/PnfdInfo" + } + }, + "404": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["NSD Management interface"] + }, + "delete": { + "operationId": "api_nsd_v1_pnf_descriptors_delete", + "description": "Delete a PNFD", + "parameters": [], + "responses": { + "204": { + "description": "No content" + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["NSD Management interface"] + }, + "parameters": [{ + "name": "pnfdInfoId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/nsd/v1/pnf_descriptors/{pnfdInfoId}/pnfd_content": { + "get": { + "operationId": "Fetch PNFD content", + "description": "Fetch PNFD content", + "parameters": [], + "responses": { + "200": { + "description": "PNFD file", + "schema": { + "type": "string", + "format": "binary" + } + }, + "404": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "produces": ["application/octet-stream", "application/json"], + "tags": ["NSD Management interface"] + }, + "put": { + "operationId": "api_nsd_v1_pnf_descriptors_pnfd_content_update", + "description": "Upload PNFD content", + "parameters": [], + "responses": { + "204": { + "description": "No content" + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["NSD Management interface"] + }, + "parameters": [{ + "name": "pnfdInfoId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/nsd/v1/subscriptions": { + "get": { + "operationId": "api_nsd_v1_subscriptions_list", + "description": "Query subscriptions for Nsd Management", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/NsdmSubscription" + } + } + }, + "400": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "404": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["NSD Management interface"] + }, + "post": { + "operationId": "api_nsd_v1_subscriptions_create", + "description": "Create Subscription for NSD Management", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/NsdmSubscriptionRequest" + } + }], + "responses": { + "201": { + "description": "", + "schema": { + "$ref": "#/definitions/NsdmSubscription" + } + }, + "303": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "400": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["NSD Management interface"] + }, + "parameters": [] + }, + "/api/nsd/v1/subscriptions/{subscriptionId}": { + "get": { + "operationId": "api_nsd_v1_subscriptions_read", + "description": "Query subscriptions for Nsd Management", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/NsdmSubscription" + } + }, + "400": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "404": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["NSD Management interface"] + }, + "delete": { + "operationId": "api_nsd_v1_subscriptions_delete", + "description": "Delete subscription for Nsd Management", + "parameters": [], + "responses": { + "204": { + "description": "No_Content" + }, + "400": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "404": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["NSD Management interface"] + }, + "parameters": [{ + "name": "subscriptionId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/parser/v1/health_check": { + "get": { + "operationId": "api_parser_v1_health_check_list", + "description": "", + "parameters": [], + "responses": { + "200": { + "description": "Active" + } + }, + "tags": ["Health Check interface"] + }, + "parameters": [] + }, + "/api/parser/v1/parser": { + "post": { + "operationId": "api_parser_v1_parser_create", + "description": "Parse model(NS, Service, VNF, PNF)", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ParseModelRequest" + } + }], + "responses": { + "202": { + "description": "", + "schema": { + "$ref": "#/definitions/ParseModelResponse" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Parser interface"] + }, + "parameters": [] + }, + "/api/parser/v1/parsernsd": { + "post": { + "operationId": "api_parser_v1_parsernsd_create", + "description": "Parse NS model", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ParseModelRequest" + } + }], + "responses": { + "202": { + "description": "", + "schema": { + "$ref": "#/definitions/ParseModelResponse" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Parser interface"] + }, + "parameters": [] + }, + "/api/parser/v1/parserpnfd": { + "post": { + "operationId": "api_parser_v1_parserpnfd_create", + "description": "Parse PNF model", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ParseModelRequest" + } + }], + "responses": { + "202": { + "description": "", + "schema": { + "$ref": "#/definitions/ParseModelResponse" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Parser interface"] + }, + "parameters": [] + }, + "/api/parser/v1/parservnfd": { + "post": { + "operationId": "api_parser_v1_parservnfd_create", + "description": "Parse NF model", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ParseModelRequest" + } + }], + "responses": { + "202": { + "description": "", + "schema": { + "$ref": "#/definitions/ParseModelResponse" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/InternalErrorRequest" + } + } + }, + "tags": ["Parser interface"] + }, + "parameters": [] + }, + "/api/vnfpkgm/v1/health_check": { + "get": { + "operationId": "api_vnfpkgm_v1_health_check_list", + "description": "", + "parameters": [], + "responses": { + "200": { + "description": "Active" + } + }, + "tags": ["Health Check interface"] + }, + "parameters": [] + }, + "/api/vnfpkgm/v1/subscriptions": { + "get": { + "operationId": "api_vnfpkgm_v1_subscriptions_list", + "description": "", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/PkgmSubscription" + } + }, + "400": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["VNF Package Management interface"] + }, + "post": { + "operationId": "api_vnfpkgm_v1_subscriptions_create", + "description": "", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PkgmSubscriptionRequest" + } + }], + "responses": { + "201": { + "description": "", + "schema": { + "$ref": "#/definitions/PkgmSubscription" + } + }, + "400": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["VNF Package Management interface"] + }, + "parameters": [] + }, + "/api/vnfpkgm/v1/subscriptions/{subscriptionId}": { + "get": { + "operationId": "api_vnfpkgm_v1_subscriptions_read", + "description": "", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/PkgmSubscription" + } + }, + "404": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["VNF Package Management interface"] + }, + "delete": { + "operationId": "api_vnfpkgm_v1_subscriptions_delete", + "description": "", + "parameters": [], + "responses": { + "204": { + "description": "" + }, + "404": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + }, + "500": { + "description": "", + "schema": { + "$ref": "#/definitions/SUBSCRIPTION_ProblemDetailsSerializer" + } + } + }, + "tags": ["VNF Package Management interface"] + }, + "parameters": [{ + "name": "subscriptionId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/vnfpkgm/v1/vnf_packages": { + "get": { + "operationId": "api_vnfpkgm_v1_vnf_packages_list", + "description": "Query multiple VNF package resource", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/VnfPkgInfo" + } + } + }, + "500": { + "description": "Internal error", + "schema": { + "type": "string" + } + } + }, + "tags": ["VNF Package Management interface"] + }, + "post": { + "operationId": "api_vnfpkgm_v1_vnf_packages_create", + "description": "Create an individual VNF package resource", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateVnfPkgInfoRequest" + } + }], + "responses": { + "201": { + "description": "", + "schema": { + "$ref": "#/definitions/VnfPkgInfo" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal error", + "schema": { + "type": "string" + } + } + }, + "tags": ["VNF Package Management interface"] + }, + "parameters": [] + }, + "/api/vnfpkgm/v1/vnf_packages/{vnfPkgId}": { + "get": { + "operationId": "api_vnfpkgm_v1_vnf_packages_read", + "description": "Query an individual VNF package resource", + "parameters": [], + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/VnfPkgInfo" + } + }, + "404": { + "description": "VNF package does not exist", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal error", + "schema": { + "type": "string" + } + } + }, + "tags": ["VNF Package Management interface"] + }, + "delete": { + "operationId": "api_vnfpkgm_v1_vnf_packages_delete", + "description": "Delete an individual VNF package resource", + "parameters": [], + "responses": { + "204": { + "description": "No content" + }, + "500": { + "description": "Internal error", + "schema": { + "type": "string" + } + } + }, + "tags": ["VNF Package Management interface"] + }, + "parameters": [{ + "name": "vnfPkgId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/vnfpkgm/v1/vnf_packages/{vnfPkgId}/artifacts/{artifactPath}": { + "get": { + "operationId": "api_vnfpkgm_v1_vnf_packages_artifacts_read", + "description": "", + "parameters": [], + "responses": { + "200": { + "description": "Return the artifact file", + "schema": { + "type": "string", + "format": "binary" + } + }, + "404": { + "description": "Artifact not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal error", + "schema": { + "type": "string" + } + } + }, + "produces": ["application/octet-stream", "application/json"], + "tags": ["VNF Package Management interface"] + }, + "parameters": [{ + "name": "artifactPath", + "in": "path", + "required": true, + "type": "string" + }, { + "name": "vnfPkgId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/vnfpkgm/v1/vnf_packages/{vnfPkgId}/package_content": { + "get": { + "operationId": "api_vnfpkgm_v1_vnf_packages_package_content_list", + "description": "Fetch VNF package content", + "parameters": [], + "responses": { + "200": { + "description": "VNF package file", + "schema": { + "type": "string", + "format": "binary" + } + }, + "404": { + "description": "VNF package does not exist", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal error", + "schema": { + "type": "string" + } + } + }, + "produces": ["application/octet-stream", "application/json"], + "tags": ["VNF Package Management interface"] + }, + "put": { + "operationId": "api_vnfpkgm_v1_vnf_packages_package_content_update", + "description": "Upload VNF package content", + "parameters": [], + "responses": { + "202": { + "description": "Successfully" + }, + "500": { + "description": "Internal error", + "schema": { + "type": "string" + } + } + }, + "tags": ["VNF Package Management interface"] + }, + "parameters": [{ + "name": "vnfPkgId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/vnfpkgm/v1/vnf_packages/{vnfPkgId}/package_content/upload_from_uri": { + "post": { + "operationId": "api_vnfpkgm_v1_vnf_packages_package_content_upload_from_uri_create", + "description": "Upload VNF package content from uri", + "parameters": [{ + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UploadVnfPackageFromUriRequest" + } + }], + "responses": { + "202": { + "description": "Successfully" + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal error", + "schema": { + "type": "string" + } + } + }, + "tags": ["VNF Package Management interface"] + }, + "parameters": [{ + "name": "vnfPkgId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/api/vnfpkgm/v1/vnf_packages/{vnfPkgId}/vnfd": { + "get": { + "operationId": "VNFD of an on-boarded VNF package", + "description": "Read VNFD of an on-boarded VNF package", + "parameters": [], + "responses": { + "200": { + "description": "VNFD of an on-boarded VNF package", + "schema": { + "type": "string", + "format": "binary" + } + }, + "404": { + "description": "VNF package does not exist", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal error", + "schema": { + "type": "string" + } + } + }, + "produces": ["application/octet-stream", "application/json"], + "tags": ["VNF Package Management interface"] + }, + "parameters": [{ + "name": "vnfPkgId", + "in": "path", + "required": true, + "type": "string" + }] + }, + "/samples/": { + "get": { + "operationId": "samples_list", + "description": "List all samples.", + "parameters": [], + "responses": { + "200": { + "description": "" + } + }, + "tags": ["Sample interface"] + }, + "parameters": [] + } + }, + "definitions": { + "JobResponseHistoryList": { + "description": "Response History List", + "type": "object", + "properties": { + "status": { + "title": "Status", + "description": "Status", + "type": "string", + "minLength": 1 + }, + "progress": { + "title": "Progress", + "description": "Job Progress", + "type": "string", + "minLength": 1 + }, + "statusDescription": { + "title": "Statusdescription", + "description": "Status Description", + "type": "string", + "minLength": 1 + }, + "errorCode": { + "title": "Errorcode", + "description": "Error Code", + "type": "string", + "minLength": 1, + "x-nullable": true + }, + "responseId": { + "title": "Responseid", + "description": "Response Id", + "type": "string", + "minLength": 1 + } + } + }, + "JobResponseDescriptor": { + "title": "Responsedescriptor", + "description": "Job Response Descriptor", + "type": "object", + "properties": { + "status": { + "title": "Status", + "description": "Status", + "type": "string", + "minLength": 1 + }, + "progress": { + "title": "Progress", + "description": "Job Progress", + "type": "string", + "minLength": 1 + }, + "statusDescription": { + "title": "Statusdescription", + "description": "Status Description", + "type": "string", + "minLength": 1 + }, + "errorCode": { + "title": "Errorcode", + "description": "Error Code", + "type": "string", + "minLength": 1, + "x-nullable": true + }, + "responseId": { + "title": "Responseid", + "description": "Response Id", + "type": "string", + "minLength": 1 + }, + "responseHistoryList": { + "description": "Response History List", + "type": "array", + "items": { + "$ref": "#/definitions/JobResponseHistoryList" + } + } + } + }, + "GetJobResponse": { + "type": "object", + "properties": { + "jobId": { + "title": "Jobid", + "description": "Job Id", + "type": "string", + "minLength": 1 + }, + "responseDescriptor": { + "$ref": "#/definitions/JobResponseDescriptor" + } + } + }, + "PostJobResponseResult": { + "required": ["result"], + "type": "object", + "properties": { + "result": { + "title": "Result", + "description": "Result", + "type": "string", + "minLength": 1 + }, + "msg": { + "title": "Msg", + "description": "Message", + "type": "string", + "minLength": 1 + } + } + }, + "PostJobRequest": { + "type": "object", + "properties": { + "progress": { + "title": "Progress", + "description": "Job Progress", + "type": "string", + "minLength": 1 + }, + "desc": { + "title": "Desc", + "description": "Description", + "type": "string", + "minLength": 1 + }, + "errcode": { + "title": "Errcode", + "description": "Error Code", + "type": "string", + "minLength": 1 + } + } + }, + "NsPackageInfo": { + "title": "Packageinfo", + "description": "NS Package Info", + "type": "object", + "properties": { + "nsdId": { + "title": "Nsdid", + "description": "NSD ID", + "type": "string", + "minLength": 1, + "x-nullable": true + }, + "nsPackageId": { + "title": "Nspackageid", + "description": "NS Package ID", + "type": "string", + "x-nullable": true + }, + "nsdProvider": { + "title": "Nsdprovider", + "description": "NSD Provider", + "type": "string", + "x-nullable": true + }, + "nsdVersion": { + "title": "Nsdversion", + "description": "NSD Version", + "type": "string", + "x-nullable": true + }, + "csarName": { + "title": "Csarname", + "description": "CSAR name", + "type": "string", + "x-nullable": true + }, + "nsdModel": { + "title": "Nsdmodel", + "description": "NSD Model", + "type": "string", + "x-nullable": true + }, + "downloadUrl": { + "title": "Downloadurl", + "description": "URL to download NSD Model", + "type": "string", + "minLength": 1, + "x-nullable": true + } + }, + "x-nullable": true + }, + "NsPackage": { + "type": "object", + "properties": { + "csarId": { + "title": "Csarid", + "description": "CSAR ID", + "type": "string", + "minLength": 1, + "x-nullable": true + }, + "packageInfo": { + "$ref": "#/definitions/NsPackageInfo" + } + } + }, + "InternalErrorRequest": { + "required": ["error"], + "type": "object", + "properties": { + "error": { + "title": "Error", + "description": "Error", + "type": "string", + "minLength": 1 + }, + "errorMessage": { + "title": "Errormessage", + "description": "Error Message", + "type": "string", + "minLength": 1 + } + } + }, + "NsPackageDistributeRequest": { + "required": ["csarId"], + "type": "object", + "properties": { + "csarId": { + "title": "Csarid", + "description": "csarId", + "type": "string", + "minLength": 1 + } + } + }, + "NsPackageDistributeResponse": { + "required": ["status", "statusDescription", "errorCode"], + "type": "object", + "properties": { + "status": { + "title": "Status", + "description": "status", + "type": "string", + "minLength": 1 + }, + "statusDescription": { + "title": "Statusdescription", + "description": "statusDescription", + "type": "string", + "minLength": 1 + }, + "errorCode": { + "title": "Errorcode", + "description": "errorCode", + "type": "string", + "minLength": 1 + } + } + }, + "ServicePackageInfo": { + "title": "Packageinfo", + "description": "Service Package Info", + "type": "object", + "properties": { + "servicedId": { + "title": "Servicedid", + "description": "ServiceD ID", + "type": "string", + "minLength": 1, + "x-nullable": true + }, + "servicePackageId": { + "title": "Servicepackageid", + "description": "Service Package ID", + "type": "string", + "x-nullable": true + }, + "servicedProvider": { + "title": "Servicedprovider", + "description": "ServiceD Provider", + "type": "string", + "x-nullable": true + }, + "servicedVersion": { + "title": "Servicedversion", + "description": "ServiceD Version", + "type": "string", + "x-nullable": true + }, + "csarName": { + "title": "Csarname", + "description": "CSAR name", + "type": "string", + "x-nullable": true + }, + "servicedModel": { + "title": "Servicedmodel", + "description": "ServiceD Model", + "type": "string", + "x-nullable": true + }, + "downloadUrl": { + "title": "Downloadurl", + "description": "URL to download ServiceD Model", + "type": "string", + "minLength": 1, + "x-nullable": true + } + }, + "x-nullable": true + }, + "ServicePackage": { + "type": "object", + "properties": { + "csarId": { + "title": "Csarid", + "description": "CSAR ID", + "type": "string", + "minLength": 1, + "x-nullable": true + }, + "packageInfo": { + "$ref": "#/definitions/ServicePackageInfo" + } + } + }, + "ServicePackageDistributeRequest": { + "required": ["csarId"], + "type": "object", + "properties": { + "csarId": { + "title": "Csarid", + "description": "csarId", + "type": "string", + "minLength": 1 + } + } + }, + "NfPackageInfo": { + "title": "Packageinfo", + "description": "VNF Package Info", + "required": ["vnfPackageId"], + "type": "object", + "properties": { + "vnfdId": { + "title": "Vnfdid", + "description": "VNFD ID", + "type": "string", + "x-nullable": true + }, + "vnfPackageId": { + "title": "Vnfpackageid", + "description": "VNF Package ID", + "type": "string", + "minLength": 1 + }, + "vnfdProvider": { + "title": "Vnfdprovider", + "description": "VNFD Provider", + "type": "string", + "x-nullable": true + }, + "vnfdVersion": { + "title": "Vnfdversion", + "description": "VNFD Version", + "type": "string", + "x-nullable": true + }, + "vnfVersion": { + "title": "Vnfversion", + "description": "VNF Version", + "type": "string", + "x-nullable": true + }, + "csarName": { + "title": "Csarname", + "description": "CSAR Name", + "type": "string", + "x-nullable": true + }, + "vnfdModel": { + "title": "Vnfdmodel", + "description": "VNFD Model", + "type": "string", + "x-nullable": true + }, + "downloadUrl": { + "title": "Downloadurl", + "description": "URL to download VNFD Model", + "type": "string", + "x-nullable": true + } + } + }, + "NfImageInfo": { + "description": "Image Info", + "required": ["index", "fileName", "imageId", "vimId", "vimUser", "tenant", "status"], + "type": "object", + "properties": { + "index": { + "title": "Index", + "description": "Index of VNF Image", + "type": "string", + "minLength": 1 + }, + "fileName": { + "title": "Filename", + "description": "Image file name", + "type": "string", + "minLength": 1 + }, + "imageId": { + "title": "Imageid", + "description": "Image ID", + "type": "string", + "minLength": 1 + }, + "vimId": { + "title": "Vimid", + "description": "VIM ID", + "type": "string", + "minLength": 1 + }, + "vimUser": { + "title": "Vimuser", + "description": "User of VIM", + "type": "string", + "minLength": 1 + }, + "tenant": { + "title": "Tenant", + "description": "Tenant", + "type": "string", + "minLength": 1 + }, + "status": { + "title": "Status", + "description": "Status", + "type": "string", + "minLength": 1 + } + } + }, + "NfPackage": { + "required": ["csarId", "packageInfo"], + "type": "object", + "properties": { + "csarId": { + "title": "Csarid", + "description": "CSAR ID", + "type": "string", + "minLength": 1 + }, + "packageInfo": { + "$ref": "#/definitions/NfPackageInfo" + }, + "imageInfo": { + "description": "Image Info", + "type": "array", + "items": { + "$ref": "#/definitions/NfImageInfo" + }, + "x-nullable": true + } + } + }, + "NfPackageDistributeRequest": { + "required": ["csarId"], + "type": "object", + "properties": { + "csarId": { + "title": "Csarid", + "description": "CSAR ID", + "type": "string", + "minLength": 1 + }, + "vimIds": { + "description": "A string for vimIds", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "labVimId": { + "title": "Labvimid", + "description": "A list of VIM IDs.", + "type": "string" + } + } + }, + "PostJobResponse": { + "required": ["jobId"], + "type": "object", + "properties": { + "jobId": { + "title": "Jobid", + "description": "jobId", + "type": "string", + "minLength": 1 + } + } + }, + "ProblemDetails": { + "title": "Onboardingfailuredetails", + "description": "Failure details of current onboarding procedure.It shall be present when the nsdOnboardingState attribute is CREATED and the uploading or processing fails in NFVO.", + "required": ["title", "detail"], + "type": "object", + "properties": { + "type": { + "title": "Type", + "description": "A URI reference according to IETF RFC 3986 [10] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".", + "type": "string", + "x-nullable": true + }, + "title": { + "title": "Title", + "description": "The HTTP status code for this occurrence of the problem.", + "type": "integer" + }, + "detail": { + "title": "Detail", + "description": "A human-readable explanation specific to this occurrence of the problem.", + "type": "string", + "minLength": 1 + }, + "instance": { + "title": "Instance", + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.", + "type": "string", + "x-nullable": true + }, + "additional_attributes": { + "title": "Additional attributes", + "description": "Any number of additional attributes, as defined in a specification or by an implementation.", + "type": "object", + "additionalProperties": { + "description": "Additional attribute", + "type": "string" + }, + "x-nullable": true + } + } + }, + "UriLink": { + "title": "Self", + "description": "URI of this resource.", + "required": ["href"], + "type": "object", + "properties": { + "href": { + "title": "Href", + "description": "URI of the referenced resource", + "type": "string", + "minLength": 1 + } + } + }, + "NSD_LinkSerializer": { + "title": " links", + "description": "Links to resources related to this resource.", + "required": ["self", "nsd_content"], + "type": "object", + "properties": { + "self": { + "$ref": "#/definitions/UriLink" + }, + "nsd_content": { + "$ref": "#/definitions/UriLink" + } + } + }, + "NsdInfo": { + "required": ["id", "nsdOnboardingState", "nsdOperationalState", "nsdUsageState", "_links"], + "type": "object", + "properties": { + "id": { + "title": "Id", + "description": "Identifier of the onboarded individual NS descriptor resource.This identifier is allocated by the NFVO.", + "type": "string", + "minLength": 1 + }, + "nsdId": { + "title": "Nsdid", + "description": "This identifier, which is allocated by the NSD designer,identifies the NSD in a globally unique way.It is copied from the NSD content and shall be present after the NSD content is on-boarded.", + "type": "string", + "x-nullable": true + }, + "nsdName": { + "title": "Nsdname", + "description": "Name of the onboarded NSD.This information is copied from the NSD content and shall be present after the NSD content is on-boarded.", + "type": "string", + "x-nullable": true + }, + "nsdVersion": { + "title": "Nsdversion", + "description": "Version of the on-boarded NSD.This information is copied from the NSD content and shall be present after the NSD content is on-boarded.", + "type": "string", + "x-nullable": true + }, + "nsdDesigner": { + "title": "Nsddesigner", + "description": "Designer of the on-boarded NSD.This information is copied from the NSD content and shall be present after the NSD content is on-boarded.", + "type": "string", + "x-nullable": true + }, + "nsdInvariantId": { + "title": "Nsdinvariantid", + "description": "This identifier, which is allocated by the NSD designer,identifies an NSD in a version independent manner.This information is copied from the NSD content and shall be present after the NSD content is on-boarded.", + "type": "string", + "x-nullable": true + }, + "vnfPkgIds": { + "description": "Identifies the VNF package for the VNFD referenced by the on-boarded NS descriptor resource.", + "type": "array", + "items": { + "description": "Identifier of the VNF package", + "type": "string" + }, + "x-nullable": true + }, + "pnfdInfoIds": { + "description": "Identifies the PnfdInfo element for the PNFD referenced by the on-boarded NS descriptor resource.", + "type": "array", + "items": { + "description": "Identifier of the PnfdInfo element", + "type": "string" + }, + "x-nullable": true + }, + "nestedNsdInfoIds": { + "description": "Identifies the NsdInfo element for the nested NSD referenced by the on-boarded NS descriptor resource.", + "type": "array", + "items": { + "description": "Identifier of the NsdInfo element", + "type": "string" + }, + "x-nullable": true + }, + "nsdOnboardingState": { + "title": "Nsdonboardingstate", + "description": "Onboarding state of the individual NS descriptor resource.", + "type": "string", + "enum": ["CREATED", "UPLOADING", "PROCESSING", "ONBOARDED"] + }, + "onboardingFailureDetails": { + "$ref": "#/definitions/ProblemDetails" + }, + "nsdOperationalState": { + "title": "Nsdoperationalstate", + "description": "Operational state of the individual NS descriptor resource.This attribute can be modified with the PATCH method.", + "type": "string", + "enum": ["ENABLED", "DISABLED"] + }, + "nsdUsageState": { + "title": "Nsdusagestate", + "description": "Usage state of the individual NS descriptor resource.", + "type": "string", + "enum": ["IN_USE", "NOT_IN_USE"] + }, + "userDefinedData": { + "title": "Userdefineddata", + "description": "User defined data for the individual NS descriptor resource.This attribute can be modified with the PATCH method.", + "type": "object", + "additionalProperties": { + "description": "Key Value Pairs", + "type": "string" + }, + "x-nullable": true + }, + "_links": { + "$ref": "#/definitions/NSD_LinkSerializer" + } + } + }, + "CreateNsdInfoRequest": { + "type": "object", + "properties": { + "userDefinedData": { + "title": "Userdefineddata", + "description": "User-defined data for the NS descriptor resource to be created.It shall be present when the user defined data is set for the individual NS descriptor resource to be created.", + "type": "object", + "additionalProperties": { + "description": "Key Value Pairs", + "type": "string" + }, + "x-nullable": true + } + } + }, + "PNFD_LinkSerializer": { + "title": " links", + "description": "Links to resources related to this resource.", + "required": ["self", "pnfd_content"], + "type": "object", + "properties": { + "self": { + "$ref": "#/definitions/UriLink" + }, + "pnfd_content": { + "$ref": "#/definitions/UriLink" + } + } + }, + "PnfdInfo": { + "required": ["id", "pnfdOnboardingState", "pnfdUsageState", "_links"], + "type": "object", + "properties": { + "id": { + "title": "Id", + "description": "Identifier of the onboarded individual PNF descriptor resource. This identifier is allocated by the NFVO.", + "type": "string", + "minLength": 1 + }, + "pnfdId": { + "title": "Pnfdid", + "description": "This identifier, which is allocated by the PNFD designer, identifies the PNFD in a globally unique way. It is copied from the PNFD content and shall be present after the PNFD content is on-boarded.", + "type": "string", + "x-nullable": true + }, + "pnfdName": { + "title": "Pnfdname", + "description": "Name of the onboarded PNFD. This information is copied from the PNFD content and shall be present after the PNFD content is on-boarded.", + "type": "string", + "x-nullable": true + }, + "pnfdVersion": { + "title": "Pnfdversion", + "description": "Version of the on-boarded PNFD. This information is copied from the PNFD content and shall be present after the PNFD content is on-boarded.", + "type": "string", + "x-nullable": true + }, + "pnfdProvider": { + "title": "Pnfdprovider", + "description": "Provider of the on-boarded PNFD. This information is copied from the PNFD content and shall be present after the PNFD content is on-boarded.", + "type": "string", + "x-nullable": true + }, + "pnfdInvariantId": { + "title": "Pnfdinvariantid", + "description": "Identifies a PNFD in a version independent manner. This attribute is invariant across versions of PNFD.", + "type": "string", + "x-nullable": true + }, + "pnfdOnboardingState": { + "title": "Pnfdonboardingstate", + "description": "Onboarding state of the individual PNF descriptor resource.", + "type": "string", + "enum": ["CREATED", "UPLOADING", "PROCESSING", "ONBOARDED"] + }, + "onboardingFailureDetails": { + "$ref": "#/definitions/ProblemDetails" + }, + "pnfdUsageState": { + "title": "Pnfdusagestate", + "description": "Usage state of the individual PNF descriptor resource.", + "type": "string", + "enum": ["IN_USE", "NOT_IN_USE"] + }, + "userDefinedData": { + "title": "Userdefineddata", + "description": "User defined data for the individual PNF descriptor resource. This attribute can be modified with the PATCH method.", + "type": "object", + "additionalProperties": { + "description": "Key Value Pairs", + "type": "string" + }, + "x-nullable": true + }, + "_links": { + "$ref": "#/definitions/PNFD_LinkSerializer" + } + } + }, + "SUBSCRIPTION_ProblemDetailsSerializer": { + "required": ["status", "detail"], + "type": "object", + "properties": { + "type": { + "title": "Type", + "description": "Type", + "type": "string", + "minLength": 1, + "x-nullable": true + }, + "title": { + "title": "Title", + "description": "Title", + "type": "string", + "minLength": 1, + "x-nullable": true + }, + "status": { + "title": "Status", + "description": "Status", + "type": "integer" + }, + "detail": { + "title": "Detail", + "description": "Detail", + "type": "string", + "minLength": 1 + }, + "instance": { + "title": "Instance", + "description": "Instance", + "type": "string", + "minLength": 1, + "x-nullable": true + }, + "additional_details": { + "description": "Any number of additional attributes, as defined in a specification or by an implementation.", + "type": "array", + "items": { + "type": "string" + }, + "x-nullable": true + } + } + }, + "CreatePnfdInfoRequest": { + "type": "object", + "properties": { + "userDefinedData": { + "title": "Userdefineddata", + "description": "User-defined data for the PNF descriptor resource to be created.It shall be present when the user defined data is set for the individual PNF descriptor resource to be created.", + "type": "object", + "additionalProperties": { + "description": "Key Value Pairs", + "type": "string" + }, + "x-nullable": true + } + } + }, + "NsdmNotificationsFilter": { + "title": "Filter", + "description": "Filter settings for this subscription, to define the of all notifications this subscription relates to.", + "type": "object", + "properties": { + "notificationTypes": { + "description": "Match particular notification types", + "type": "array", + "items": { + "type": "string", + "enum": ["NsdOnBoardingNotification", "NsdOnboardingFailureNotification", "NsdChangeNotification", "NsdDeletionNotification", "PnfdOnBoardingNotification", "PnfdOnBoardingFailureNotification", "PnfdDeletionNotification"] + } + }, + "nsdInfoId": { + "description": "Match NS packages with particular nsdInfoIds", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "nsdId": { + "description": "Match NS Packages with particular nsdIds", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "nsdName": { + "description": "Match NS Packages with particular nsdNames", + "type": "array", + "items": { + "type": "string", + "maxLength": 255, + "minLength": 1 + } + }, + "nsdVersion": { + "description": "match NS packages that belong to certain nsdversion", + "type": "array", + "items": { + "type": "string", + "maxLength": 255, + "minLength": 1 + } + }, + "nsdInvariantId": { + "description": "Match NS Packages with particular nsdInvariantIds", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "vnfPkgIds": { + "description": "Match NS Packages that has VNF PackageIds", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "nestedNsdInfoIds": { + "description": "Match NS Packages with particular nsdInvariantIds", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "nsdOnboardingState": { + "description": "Match NS Packages with particular NS Onboarding State", + "type": "array", + "items": { + "type": "string", + "enum": ["CREATED", "UPLOADING", "PROCESSING", "ONBOARDED"] + } + }, + "nsdOperationalState": { + "description": "Match NS Packages with particular NS Operational State", + "type": "array", + "items": { + "type": "string", + "enum": ["ENABLED", "DISABLED"] + } + }, + "nsdUsageState": { + "description": "Match NS Packages with particular NS Usage State", + "type": "array", + "items": { + "type": "string", + "enum": ["IN_USE", "NOT_IN_USE"] + } + }, + "pnfdInfoIds": { + "description": "Match PF packages with particular pnfdInfoIds", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "pnfdId": { + "description": "Match PF packages with particular pnfdInfoIds", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "pnfdName": { + "description": "Match PF Packages with particular pnfdNames", + "type": "array", + "items": { + "type": "string", + "maxLength": 255, + "minLength": 1 + } + }, + "pnfdVersion": { + "description": "match PF packages that belong to certain pnfd version", + "type": "array", + "items": { + "type": "string", + "maxLength": 255, + "minLength": 1 + } + }, + "pnfdProvider": { + "description": "Match PF Packages with particular pnfdProvider", + "type": "array", + "items": { + "type": "string", + "maxLength": 255, + "minLength": 1 + } + }, + "pnfdInvariantId": { + "description": "Match PF Packages with particular pnfdInvariantIds", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "pnfdOnboardingState": { + "description": "Match PF Packages with particular PNF Onboarding State ", + "type": "array", + "items": { + "type": "string", + "enum": ["CREATED", "UPLOADING", "PROCESSING", "ONBOARDED"] + } + }, + "pnfdUsageState": { + "description": "Match PF Packages with particular PNF usage State", + "type": "array", + "items": { + "type": "string", + "enum": ["IN_USE", "NOT_IN_USE"] + } + } + } + }, + "NSDM_SUB_LinkSerializer": { + "title": " links", + "description": "Links to resources related to this resource.", + "required": ["self"], + "type": "object", + "properties": { + "self": { + "$ref": "#/definitions/UriLink" + } + } + }, + "NsdmSubscription": { + "required": ["id", "callbackUri", "_links"], + "type": "object", + "properties": { + "id": { + "title": "Id", + "description": "Identifier of this subscription resource.", + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "callbackUri": { + "title": "Callbackuri", + "description": "The URI of the endpoint to send the notification to.", + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "filter": { + "$ref": "#/definitions/NsdmNotificationsFilter" + }, + "_links": { + "$ref": "#/definitions/NSDM_SUB_LinkSerializer" + } + } + }, + "BasicAuth": { + "title": "Paramsbasic", + "description": "Parameters for authentication/authorization using BASIC.", + "type": "object", + "properties": { + "userName": { + "title": "Username", + "description": "Username to be used in HTTP Basic authentication.", + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "password": { + "title": "Password", + "description": "Password to be used in HTTP Basic authentication.", + "type": "string", + "maxLength": 255, + "minLength": 1 + } + } + }, + "OAuthCredentials": { + "title": "Paramsoauth2clientcredentials", + "description": "Parameters for authentication/authorization using OAUTH2_CLIENT_CREDENTIALS.", + "type": "object", + "properties": { + "clientId": { + "title": "Clientid", + "description": "Client identifier to be used in the access token request of the OAuth 2.0 client credentials grant type.", + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "clientPassword": { + "title": "Clientpassword", + "description": "Client password to be used in the access token request of the OAuth 2.0 client credentials grant type.", + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "tokenEndpoint": { + "title": "Tokenendpoint", + "description": "The token endpoint from which the access token can be obtained.", + "type": "string", + "maxLength": 255, + "minLength": 1 + } + } + }, + "SubscriptionAuthentication": { + "title": "Authentication", + "description": "Authentication parameters to configure the use of Authorization when sending notifications corresponding to this subscription.", + "required": ["authType"], + "type": "object", + "properties": { + "authType": { + "description": "Defines the types of Authentication / Authorization which the API consumer is willing to accept when receiving a notification.", + "type": "array", + "items": { + "type": "string", + "enum": ["BASIC", "OAUTH2_CLIENT_CREDENTIALS", "TLS_CERT"] + } + }, + "paramsBasic": { + "$ref": "#/definitions/BasicAuth" + }, + "paramsOauth2ClientCredentials": { + "$ref": "#/definitions/OAuthCredentials" + } + } + }, + "NsdmSubscriptionRequest": { + "required": ["callbackUri"], + "type": "object", + "properties": { + "callbackUri": { + "title": "Callbackuri", + "description": "The URI of the endpoint to send the notification to.", + "type": "string", + "minLength": 1 + }, + "filter": { + "$ref": "#/definitions/NsdmNotificationsFilter" + }, + "authentication": { + "$ref": "#/definitions/SubscriptionAuthentication" + } + } + }, + "ParseModelRequest": { + "required": ["csarId"], + "type": "object", + "properties": { + "csarId": { + "title": "Csarid", + "description": "CSAR ID", + "type": "string", + "minLength": 1 + }, + "packageType": { + "title": "Packagetype", + "description": "Package type: VNF, PNF, NS, Service", + "type": "string", + "minLength": 1 + }, + "inputs": { + "title": "Inputs", + "description": "Inputs", + "type": "object" + } + } + }, + "ParseModelResponse": { + "required": ["model"], + "type": "object", + "properties": { + "model": { + "title": "Model", + "description": "Model", + "type": "object" + } + } + }, + "VNF_SUBSCRIPTION_LINKSERIALIZER": { + "title": "Self", + "description": "URI of this resource.", + "required": ["href"], + "type": "object", + "properties": { + "href": { + "title": "Href", + "description": "URI of the referenced resource.", + "type": "string", + "minLength": 1 + } + } + }, + "LinkSelf": { + "title": " links", + "description": "Links to resources related to this resource.", + "required": ["self"], + "type": "object", + "properties": { + "self": { + "$ref": "#/definitions/VNF_SUBSCRIPTION_LINKSERIALIZER" + } + } + }, + "Version": { + "required": ["vnfSoftwareVersion"], + "type": "object", + "properties": { + "vnfSoftwareVersion": { + "title": "Vnfsoftwareversion", + "description": "VNF software version to match.", + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "vnfdVersions": { + "description": "Match VNF packages that contain VNF products with certain VNFD versions", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + } + } + }, + "vnfProducts": { + "required": ["vnfProductName"], + "type": "object", + "properties": { + "vnfProductName": { + "title": "Vnfproductname", + "description": "Name of the VNF product to match.", + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "versions": { + "description": "match VNF packages that contain VNF products with certain versions", + "type": "array", + "items": { + "$ref": "#/definitions/Version" + } + } + } + }, + "vnfProductsProviders": { + "required": ["vnfProvider"], + "type": "object", + "properties": { + "vnfProvider": { + "title": "Vnfprovider", + "description": "Name of the VNFprovider to match.", + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + "vnfProducts": { + "description": "match VNF packages that contain VNF products with certain product names, from one particular provider", + "type": "array", + "items": { + "$ref": "#/definitions/vnfProducts" + } + } + } + }, + "PkgmNotificationsFilter": { + "title": "Filter", + "description": "Filter settings for this subscription, to define the subset of all notifications this subscription relates to", + "type": "object", + "properties": { + "notificationTypes": { + "description": "Match particular notification types", + "type": "array", + "items": { + "type": "string", + "enum": ["VnfPackageOnboardingNotification", "VnfPackageChangeNotification"] + } + }, + "vnfProductsFromProviders": { + "description": "Match VNF packages that contain VNF products from certain providers.", + "type": "array", + "items": { + "$ref": "#/definitions/vnfProductsProviders" + } + }, + "vnfdId": { + "description": "Match VNF packages with a VNFD identifierlisted in the attribute", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "vnfPkgId": { + "description": "Match VNF packages with a VNFD identifierlisted in the attribute", + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "operationalState": { + "description": "Operational state of the VNF package.", + "type": "array", + "items": { + "type": "string", + "enum": ["ENABLED", "DISABLED"] + } + }, + "usageState": { + "description": "Operational state of the VNF package.", + "type": "array", + "items": { + "type": "string", + "enum": ["IN_USE", "NOT_IN_USE"] + } + } + } + }, + "PkgmSubscription": { + "required": ["id", "callbackUri", "_links"], + "type": "object", + "properties": { + "id": { + "title": "Id", + "description": "Identifier of this subscription resource.", + "type": "string", + "minLength": 1 + }, + "callbackUri": { + "title": "Callbackuri", + "description": "The URI of the endpoint to send the notification to.", + "type": "string", + "format": "uri", + "minLength": 1 + }, + "_links": { + "$ref": "#/definitions/LinkSelf" + }, + "filter": { + "$ref": "#/definitions/PkgmNotificationsFilter" + } + } + }, + "PkgmSubscriptionRequest": { + "required": ["callbackUri"], + "type": "object", + "properties": { + "filter": { + "$ref": "#/definitions/PkgmNotificationsFilter" + }, + "callbackUri": { + "title": "Callbackuri", + "description": "Callback URI to sendthe notification", + "type": "string", + "format": "uri", + "minLength": 1 + }, + "authentication": { + "$ref": "#/definitions/SubscriptionAuthentication" + } + } + }, + "Checksum": { + "title": "Checksum", + "description": "Checksum of the on-boarded VNF package.", + "required": ["algorithm", "hash"], + "type": "object", + "properties": { + "algorithm": { + "title": "Algorithm", + "description": "Name of the algorithm used to generate the checksum.", + "type": "string", + "minLength": 1 + }, + "hash": { + "title": "Hash", + "description": "The hexadecimal value of the checksum.", + "type": "string", + "minLength": 1 + } + } + }, + "VnfPackageSoftwareImageInfo": { + "description": "Information about VNF package artifacts that are software images.", + "required": ["id", "name", "provider", "version", "checksum", "containerFormat", "diskFormat", "createdAt", "minDisk", "minRam", "size", "imagePath"], + "type": "object", + "properties": { + "id": { + "title": "Id", + "description": "Identifier of the software image.", + "type": "string", + "minLength": 1 + }, + "name": { + "title": "Name", + "description": "Name of the software image.", + "type": "string", + "minLength": 1 + }, + "provider": { + "title": "Provider", + "description": "Provider of the software image.", + "type": "string", + "minLength": 1 + }, + "version": { + "title": "Version", + "description": "Version of the software image.", + "type": "string", + "minLength": 1 + }, + "checksum": { + "$ref": "#/definitions/Checksum" + }, + "containerFormat": { + "title": "Containerformat", + "description": "terminationType: Indicates whether forceful or graceful termination is requested.", + "type": "string", + "enum": ["AKI", "AMI", "ARI", "BARE", "DOCKER", "OVA", "OVF"] + }, + "diskFormat": { + "title": "Diskformat", + "description": "Disk format of a software image is the format of the underlying disk image.", + "type": "string", + "enum": ["AKI", "AMI", "ARI", "ISO", "QCOW2", "RAW", "VDI", "VHD", "VHDX", "VMDK"] + }, + "createdAt": { + "title": "Createdat", + "description": "Time when this software image was created.", + "type": "string", + "format": "date-time" + }, + "minDisk": { + "title": "Mindisk", + "description": "The minimal disk for this software image in bytes.", + "type": "integer" + }, + "minRam": { + "title": "Minram", + "description": "The minimal RAM for this software image in bytes.", + "type": "integer" + }, + "size": { + "title": "Size", + "description": "Size of this software image in bytes.", + "type": "integer" + }, + "userMetadata": { + "title": "Usermetadata", + "description": "User-defined data.", + "type": "object", + "additionalProperties": { + "description": "KeyValue Pairs", + "type": "string" + }, + "x-nullable": true + }, + "imagePath": { + "title": "Imagepath", + "description": "Path in the VNF package.", + "type": "string", + "minLength": 1 + } + } + }, + "VnfPackageArtifactInfo": { + "description": "Information about VNF package artifacts contained in the VNF package that are not software images.", + "required": ["artifactPath", "checksum"], + "type": "object", + "properties": { + "artifactPath": { + "title": "Artifactpath", + "description": "Path in the VNF package.", + "type": "string", + "minLength": 1 + }, + "checksum": { + "$ref": "#/definitions/Checksum" + }, + "metadata": { + "title": "Metadata", + "description": "The metadata of the artifact that are available in the VNF package", + "type": "object", + "additionalProperties": { + "description": "KeyValue Pairs", + "type": "string" + }, + "x-nullable": true + } + } + }, + "VNF_PKGM_Link_Serializer": { + "title": " links", + "description": "Links to resources related to this resource.", + "required": ["self", "packageContent"], + "type": "object", + "properties": { + "self": { + "$ref": "#/definitions/UriLink" + }, + "vnfd": { + "$ref": "#/definitions/UriLink" + }, + "packageContent": { + "$ref": "#/definitions/UriLink" + } + } + }, + "VnfPkgInfo": { + "required": ["id", "onboardingState", "operationalState", "usageState", "_links"], + "type": "object", + "properties": { + "id": { + "title": "Id", + "description": "Identifier of the on-boarded VNF package.", + "type": "string", + "minLength": 1 + }, + "vnfdId": { + "title": "Vnfdid", + "description": "This identifier, which is managed by the VNF provider, identifies the VNF package and the VNFD in a globally unique way.", + "type": "string", + "x-nullable": true + }, + "vnfProvider": { + "title": "Vnfprovider", + "description": "Provider of the VNF package and the VNFD.", + "type": "string", + "x-nullable": true + }, + "vnfProductName": { + "title": "Vnfproductname", + "description": "Name to identify the VNF product.", + "type": "string", + "x-nullable": true + }, + "vnfSoftwareVersion": { + "title": "Vnfsoftwareversion", + "description": "Software version of the VNF.", + "type": "string", + "x-nullable": true + }, + "vnfdVersion": { + "title": "Vnfdversion", + "description": "The version of the VNvFD.", + "type": "string", + "x-nullable": true + }, + "checksum": { + "$ref": "#/definitions/Checksum" + }, + "softwareImages": { + "description": "Information about VNF package artifacts that are software images.", + "type": "array", + "items": { + "$ref": "#/definitions/VnfPackageSoftwareImageInfo" + }, + "x-nullable": true + }, + "additionalArtifacts": { + "description": "Information about VNF package artifacts contained in the VNF package that are not software images.", + "type": "array", + "items": { + "$ref": "#/definitions/VnfPackageArtifactInfo" + }, + "x-nullable": true + }, + "onboardingState": { + "title": "Onboardingstate", + "description": "On-boarding state of the VNF package.", + "type": "string", + "enum": ["CREATED", "UPLOADING", "PROCESSING", "ONBOARDED"] + }, + "operationalState": { + "title": "Operationalstate", + "description": "Operational state of the VNF package.", + "type": "string", + "enum": ["ENABLED", "DISABLED"] + }, + "usageState": { + "title": "Usagestate", + "description": "Usage state of the VNF package.", + "type": "string", + "enum": ["IN_USE", "NOT_IN_USE"] + }, + "userDefinedData": { + "title": "Userdefineddata", + "description": "User defined data for the VNF package.", + "type": "object", + "additionalProperties": { + "description": "KeyValue Pairs", + "type": "string" + }, + "x-nullable": true + }, + "_links": { + "$ref": "#/definitions/VNF_PKGM_Link_Serializer" + } + } + }, + "CreateVnfPkgInfoRequest": { + "type": "object", + "properties": { + "userDefinedData": { + "title": "Userdefineddata", + "description": "User defined data for the VNF package.", + "type": "object", + "additionalProperties": { + "description": "KeyValue Pairs", + "type": "string" + }, + "x-nullable": true + } + } + }, + "UploadVnfPackageFromUriRequest": { + "required": ["addressInformation"], + "type": "object", + "properties": { + "addressInformation": { + "title": "Addressinformation", + "description": "Address information of the VNF package content.", + "type": "string", + "minLength": 1 + }, + "userName": { + "title": "Username", + "description": "User name to be used for authentication.", + "type": "string", + "minLength": 1 + }, + "password": { + "title": "Password", + "description": "Password to be used for authentication.", + "type": "string", + "minLength": 1 + } + } + } + } +}
\ No newline at end of file diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-ext-clients/src/main/resources/SOL003-VNFPackageManagement-Notification-API.json b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-ext-clients/src/main/resources/SOL003-VNFPackageManagement-Notification-API.json new file mode 100644 index 0000000000..32e002f0e7 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/etsi-sol003-pkgm-ext-clients/src/main/resources/SOL003-VNFPackageManagement-Notification-API.json @@ -0,0 +1,1778 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.2.0-impl:etsi.org:ETSI_NFV_OpenAPI:1", + "title": "SOL003 - VNF Package Management Notification interface", + "description": "SOL003 - VNF Package Management Notification interface\n\nIMPORTANT: Please note that this file might be not aligned to the current version of the ETSI Group Specification it refers to. In case of discrepancies the published ETSI Group Specification takes precedence.\n\nIn clause 4.3.2 of ETSI GS NFV-SOL 003 v2.4.1, an attribute-based filtering mechanism is defined. This mechanism is currently not included in the corresponding OpenAPI design for this GS version. Changes to the attribute-based filtering mechanism are being considered in v2.5.1 of this GS for inclusion in the corresponding future ETSI NFV OpenAPI design.\nPlease report bugs to https://forge.etsi.org/bugzilla/buglist.cgi?component=Nfv-Openapis&list_id=61&product=NFV&resolution=\n", + "license": { + "name": "ETSI Forge copyright notice", + "url": "https://forge.etsi.org/etsi-forge-copyright-notice.txt" + } + }, + "externalDocs": { + "description": "ETSI GS NFV-SOL 003 V2.5.1", + "url": "https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/003/02.05.01_60/gs_nfv-sol003v020501p.pdf" + }, + "basePath": "/callback/v1", + "schemes": ["https"], + "consumes": ["application/json"], + "produces": ["application/json"], + "paths": { + "/URI-is-provided-by-the-client-when-creating-the-subscription-VnfPackageOnboardingNotification": { + "post": { + "description": "Notify\n\nThe POST method delivers a notification from the server to the client.\n", + "parameters": [{ + "name": "VnfPackageOnboardingNotification", + "description": "A notification about on-boarding of a VNF package.", + "in": "body", + "required": true, + "schema": { + "description": "This type represents a VNF package management notification, which informs the receiver that the onboarding process of a VNF package is complete and the package is ready for use. The notification shall be triggered by the NFVO when the \"onboardingState\" attribute of a new VNF package has changed to \"ONBOARDED\".\n", + "type": "object", + "required": ["id", "notificationType", "subscriptionId", "timeStamp", "vnfPkgId", "vnfdId", "_links"], + "properties": { + "id": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "notificationType": { + "description": "Discriminator for the different notification types. Shall be set to \"VnfPackageOnboardingNotification\" for this notification type.\n", + "type": "string", + "enum": ["VnfPackageOnboardingNotification"] + }, + "subscriptionId": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "timeStamp": { + "description": "Date-time stamp. Representation: String formatted according to IETF RFC 3339.\n", + "type": "string", + "format": "date-time" + }, + "vnfPkgId": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "vnfdId": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "_links": { + "description": "This type represents the links to resources that a VNF package management notification can contain.\n", + "type": "object", + "required": ["vnfPackage", "subscription"], + "properties": { + "vnfPackage": { + "description": "This type represents a link to a resource in a notification, using an absolute or relative URI. It shall comply with the provisions defined in table 4.4.1.3a-1.\n", + "type": "object", + "required": ["href"], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + }, + "subscription": { + "description": "This type represents a link to a resource in a notification, using an absolute or relative URI. It shall comply with the provisions defined in table 4.4.1.3a-1.\n", + "type": "object", + "required": ["href"], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + } + } + } + } + } + }, { + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, { + "name": "Content-Type", + "description": "The MIME type of the body of the request. Reference: IETF RFC 7231\n", + "in": "header", + "required": true, + "type": "string" + }, { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + }], + "responses": { + "204": { + "description": "204 NO CONTENT\nThe notification was delivered successfully.\n", + "headers": { + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + }, + "get": { + "description": "The GET method allows the server to test the notification endpoint that is provided by the client, e.g. during subscription.\n", + "parameters": [{ + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + }], + "responses": { + "204": { + "description": "204 NO CONTENT\nThe notification endpoint was tested successfully. The response body shall be empty.\n", + "headers": { + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + } + }, + "/URI-is-provided-by-the-client-when-creating-the-subscription-VnfPackageChangeNotification": { + "post": { + "description": "Notify\n\nThe POST method delivers a notification from the server to the client.\n", + "parameters": [{ + "name": "VnfPackageChangeNotification", + "description": "A notification about changes of status in a VNF package.\n", + "in": "body", + "required": true, + "schema": { + "description": "This type represents a VNF package management notification, which informs the receiver of a change of the status in an on-boarded VNF package. Only changes in the \"operationalState\" attribute of an on-boarded VNF package and the deletion NF package will be reported. Changes in the \"usageState\" and \"onboardingState\" attributes are not reported. The notification shall be triggered by the NFVO when there is a change in the status of an onboarded VNF package, as follows: * The \"operationalState\" attribute of a VNF package has changed, and the \"onboardingState\" attribute of the package has the value \"ONBOARDED\"\n (i.e. the package has been onboarded previously).\n* The on-boarded VNF package has been deleted.\n", + "type": "object", + "required": ["id", "notificationType", "subscriptionId", "timeStamp", "vnfPkgId", "vnfdId", "changeType", "_links"], + "properties": { + "id": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "notificationType": { + "description": "Discriminator for the different notification types. Shall be set to \"VnfPackageChangeNotification\" for this notification type.\n", + "type": "string", + "enum": ["VnfPackageChangeNotification"] + }, + "subscriptionId": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "timeStamp": { + "description": "Date-time stamp. Representation: String formatted according to IETF RFC 3339.\n", + "type": "string", + "format": "date-time" + }, + "vnfPkgId": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "vnfdId": { + "description": "An identifier with the intention of being globally unique.\n", + "type": "string" + }, + "changeType": { + "description": "- OP_STATE_CHANGE: The \"operationalState\" attribute has been changed. - PKG_DELETE: The VNF package has been deleted.\n", + "type": "string", + "enum": ["OP_STATE_CHANGE", "PKG_DELETE"] + }, + "operationalState": { + "description": "- ENABLED: The VNF package is enabled, i.e. it can be used for instantiation of new VNF instances.\n- DISABLED: The VNF package is disabled, i.e. it cannot be used for further VNF instantiation requests (unless and until the VNF package\n is re-enabled).\n", + "type": "string", + "enum": ["ENABLED", "DISABLED"] + }, + "_links": { + "description": "This type represents the links to resources that a VNF package management notification can contain.\n", + "type": "object", + "required": ["vnfPackage", "subscription"], + "properties": { + "vnfPackage": { + "description": "This type represents a link to a resource in a notification, using an absolute or relative URI. It shall comply with the provisions defined in table 4.4.1.3a-1.\n", + "type": "object", + "required": ["href"], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + }, + "subscription": { + "description": "This type represents a link to a resource in a notification, using an absolute or relative URI. It shall comply with the provisions defined in table 4.4.1.3a-1.\n", + "type": "object", + "required": ["href"], + "properties": { + "href": { + "description": "String formatted according to IETF RFC 3986.\n", + "type": "string" + } + } + } + } + } + } + } + }, { + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, { + "name": "Content-Type", + "description": "The MIME type of the body of the request. Reference: IETF RFC 7231\n", + "in": "header", + "required": true, + "type": "string" + }, { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + }], + "responses": { + "204": { + "description": "204 NO CONTENT\nThe notification was delivered successfully.\n", + "headers": { + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + }, + "get": { + "description": "The GET method allows the server to test the notification endpoint that is provided by the client, e.g. during subscription.\n", + "parameters": [{ + "name": "Authorization", + "description": "The authorization token for the request. Reference: IETF RFC 7235\n", + "in": "header", + "required": false, + "type": "string" + }, { + "name": "Version", + "description": "Version of the API requested to use when responding to this request.\n", + "in": "header", + "required": true, + "type": "string" + }], + "responses": { + "204": { + "description": "204 NO CONTENT\nThe notification endpoint was tested successfully. The response body shall be empty.\n", + "headers": { + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + } + }, + "400": { + "description": "400 BAD REQUEST\n400 code can be returned in the following specified cases, the specific cause has to be proper specified in the \"ProblemDetails\" structure to be returned.\nIf the request is malformed or syntactically incorrect (e.g. if the request URI contains incorrect query parameters or the payload body contains a syntactically incorrect data structure), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf the response to a GET request which queries a container resource would be so big that the performance of the API producer is adversely affected, and the API producer does not support paging for the affected resource, it shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and should include in the \"detail\" attribute more information about the source of the problem.\nIf there is an application error related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\nIf the request contains a malformed access token, the API producer should respond with this response. The details of the error shall be returned in the WWW Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\nThe use of this HTTP error response code described above is applicable to the use of the OAuth 2.0 for the authorization of API requests and notifications, as defined in clauses 4.5.3.3 and 4.5.3.4.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "401": { + "description": "401 UNAUTHORIZED\nIf the request contains no access token even though one is required, or if the request contains an authorization token that is invalid (e.g. expired or revoked), the API producer should respond with this response. The details of the error shall be returned in the WWW-Authenticate HTTP header, as defined in IETF RFC 6750 and IETF RFC 7235. The ProblemDetails structure may be provided.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "403": { + "description": "403 FORBIDDEN\nIf the API consumer is not allowed to perform a particular request to a particular resource, the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided. It should include in the \"detail\" attribute information about the source of the problem, and may indicate how to solve it.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "404": { + "description": "404 NOT FOUND\nIf the API producer did not find a current representation for the resource addressed by the URI passed in the request or is not willing to disclose that one exists, it shall respond with this response code. The \"ProblemDetails\" structure may be provided, including in the \"detail\" attribute information about the source of the problem, e.g. a wrong resource URI variable.\nThis response code is not appropriate in case the resource addressed by the URI is a container resource which is designed to contain child resources, but does not contain any child resource at the time the request is received. For a GET request to an existing empty container resource, a typical response contains a 200 OK response code and a payload body with an empty array.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "406": { + "description": "406 NOT ACCEPTABLE\nIf the \"Accept\" header does not contain at least one name of a content type that is acceptable to the API producer, the API producer shall respond with this response code. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "500": { + "description": "500 INTERNAL SERVER ERROR\nIf there is an application error not related to the client's input that cannot be easily mapped to any other HTTP response code (\"catch all error\"), the API producer shall respond with this response code. The \"ProblemDetails\" structure shall be provided, and shall include in the \"detail\" attribute more information about the source of the problem.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + }, + "503": { + "description": "503 SERVICE UNAVAILABLE\nIf the API producer encounters an internal overload situation of itself or of a system it relies on, it should respond with this response code, following the provisions in IETF RFC 7231 for the use of the \"Retry-After\" HTTP header and for the alternative to refuse the connection. The \"ProblemDetails\" structure may be omitted.\n", + "headers": { + "Content-Type": { + "description": "The MIME type of the body of the response.", + "type": "string", + "maximum": 1, + "minimum": 1 + }, + "WWW-Authenticate": { + "description": "Challenge if the corresponding HTTP request has not provided authorization, or error details if the corresponding HTTP request has provided an invalid authorization token.\n", + "type": "string", + "maximum": 1, + "minimum": 0 + }, + "Version": { + "description": "Version of the API used in the response.\n", + "type": "string", + "maximum": 1, + "minimum": 1 + } + }, + "schema": { + "description": "The definition of the general \"ProblemDetails\" data structure from IETF RFC 7807 [19] is reproduced inthis structure. Compared to the general framework defined in IETF RFC 7807 [19], the \"status\" and \"detail\" attributes are mandated to be included by the present document, to ensure that the response contains additional textual information about an error. IETF RFC 7807 [19] foresees extensibility of the \"ProblemDetails\" type. It is possible that particular APIs in the present document, or particular implementations, define extensions to define additional attributes that provide more information about the error. The description column only provides some explanation of the meaning to Facilitate understanding of the design. For a full description, see IETF RFC 7807 [19].\n", + "type": "object", + "required": ["status", "detail"], + "properties": { + "type": { + "description": "A URI reference according to IETF RFC 3986 [5] that identifies the problem type. It is encouraged that the URI provides human-readable documentation for the problem (e.g. using HTML) when dereferenced. When this member is not present, its value is assumed to be \"about:blank\".\n", + "type": "string", + "format": "URI" + }, + "title": { + "description": "A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization. If type is given and other than \"about:blank\", this attribute shall also be provided. A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).\n", + "type": "string" + }, + "status": { + "description": "The HTTP status code for this occurrence of the problem. The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.\n", + "type": "integer" + }, + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.\n", + "type": "string" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem. It may yield further information if dereferenced.\n", + "type": "string", + "format": "URI" + } + } + } + } + } + } + } + } +}
\ No newline at end of file diff --git a/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/pom.xml b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/pom.xml new file mode 100644 index 0000000000..fb5b636ee4 --- /dev/null +++ b/adapters/etsi-sol003-adapter/etsi-sol003-pkgm/pom.xml @@ -0,0 +1,17 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.so.adapters</groupId> + <artifactId>etsi-sol003-adapter</artifactId> + <version>1.6.0-SNAPSHOT</version> + </parent> + <artifactId>etsi-sol003-pkgm</artifactId> + <name>ETSI SOL003 VNF Package Management</name> + <packaging>pom</packaging> + <modules> + <module>etsi-sol003-pkgm-api</module> + <module>etsi-sol003-pkgm-ext-clients</module> + <module>etsi-sol003-pkgm-adapter</module> + </modules> +</project>
\ No newline at end of file |