diff options
31 files changed, 664 insertions, 156 deletions
diff --git a/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V6.1__AlterColumnActionCategoryControllerSelectionCategory.sql b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V6.1__AlterColumnActionCategoryControllerSelectionCategory.sql new file mode 100644 index 0000000000..6f61b830f2 --- /dev/null +++ b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V6.1__AlterColumnActionCategoryControllerSelectionCategory.sql @@ -0,0 +1,3 @@ +USE catalogdb; + +ALTER TABLE controller_selection_reference MODIFY ACTION_CATEGORY VARCHAR(50) NOT NULL; diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java index 89e0320615..14d83b3b06 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java @@ -84,8 +84,9 @@ public class AuditVServer extends AbstractAudit { try { logger.debug("Vserver to Audit: {}", objectMapper.getMapper().writeValueAsString(vserver)); } catch (JsonProcessingException e) { - + logger.error("Json parse exception: {}", e.getMessage()); } + }); AAIObjectAuditList auditList = new AAIObjectAuditList(); vServersToAudit.stream().forEach(vServer -> auditList.getAuditList() diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImpl.java index 70fb0b3857..d5fe285274 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImpl.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImpl.java @@ -616,7 +616,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { vnfResource = vfModuleCust.getVfModule().getVnfResources(); } catch (Exception e) { - logger.debug("unhandled exception in create VF - [Query]" + e.getMessage()); + logger.debug("unhandled exception in create VF - [Query] {}", e.getMessage()); throw new VnfException("Exception during create VF " + e.getMessage()); } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/pom.xml b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/pom.xml index e2dd64d0f4..bc491a6fc5 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/pom.xml +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/pom.xml @@ -108,6 +108,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.springframework.security.oauth</groupId> + <artifactId>spring-security-oauth2</artifactId> + <version>2.3.6.RELEASE</version> + </dependency> + <dependency> <groupId>org.onap.so.adapters</groupId> <artifactId>mso-adapters-rest-interface</artifactId> <version>${project.version}</version> diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/MessageConverterConfiguration.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/MessageConverterConfiguration.java index d99b68846e..32c22356b3 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/MessageConverterConfiguration.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/MessageConverterConfiguration.java @@ -20,14 +20,16 @@ package org.onap.so.adapters.vnfmadapter; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import java.util.ArrayList; import java.util.Collection; -import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.JSON; +import org.onap.so.adapters.vnfmadapter.oauth.OAuth2AccessTokenAdapter; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.security.oauth2.common.OAuth2AccessToken; /** * Configures message converter @@ -38,7 +40,8 @@ public class MessageConverterConfiguration { @Bean public HttpMessageConverters customConverters() { final Collection<HttpMessageConverter<?>> messageConverters = new ArrayList<>(); - final Gson gson = new JSON().getGson(); + final Gson gson = new GsonBuilder() + .registerTypeHierarchyAdapter(OAuth2AccessToken.class, new OAuth2AccessTokenAdapter()).create(); final GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter(gson); messageConverters.add(gsonHttpMessageConverter); return new HttpMessageConverters(true, messageConverters); diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/WebSecurityConfigImpl.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/WebSecurityConfigImpl.java index f0830139b7..2b33e8b11d 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/WebSecurityConfigImpl.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/WebSecurityConfigImpl.java @@ -36,11 +36,9 @@ public class WebSecurityConfigImpl extends WebSecurityConfig { @Override protected void configure(final HttpSecurity http) throws Exception { - http.csrf().disable().authorizeRequests() - .antMatchers("/manage/health", "/manage/info", Constants.BASE_URL + "/lcn/**", - Constants.BASE_URL + "/grants/**") - .permitAll().antMatchers("/**").hasAnyRole(StringUtils.collectionToDelimitedString(getRoles(), ",")) - .and().httpBasic(); + http.csrf().disable().authorizeRequests().antMatchers("/manage/health", "/manage/info").permitAll() + .antMatchers("/**").hasAnyRole(StringUtils.collectionToDelimitedString(getRoles(), ",")).and() + .httpBasic(); } @Override diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHelper.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHelper.java index 249cf74cb2..b4355efc20 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHelper.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHelper.java @@ -41,6 +41,7 @@ import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.LccnSubscriptionRe import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthentication; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthentication.AuthTypeEnum; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsBasic; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsOauth2ClientCredentials; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsFilter; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsFilter.NotificationTypesEnum; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsFilterVnfInstanceSubscriptionFilter; @@ -194,12 +195,21 @@ public class VnfmHelper { } private SubscriptionsAuthentication getSubscriptionsAuthentication() throws GeneralSecurityException { - final SubscriptionsAuthenticationParamsBasic basicAuthParams = new SubscriptionsAuthenticationParamsBasic(); + final SubscriptionsAuthentication authentication = new SubscriptionsAuthentication(); + final String[] decrypedAuth = CryptoUtils.decrypt(vnfmAdapterAuth, msoEncryptionKey).split(":"); + + SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthParams = + new SubscriptionsAuthenticationParamsOauth2ClientCredentials(); + oauthParams.setTokenEndpoint(vnfmAdapterEndoint + "/oauth/token"); + oauthParams.clientId(decrypedAuth[0]); + oauthParams.setClientPassword(decrypedAuth[1]); + authentication.addAuthTypeItem(AuthTypeEnum.OAUTH2_CLIENT_CREDENTIALS); + authentication.paramsOauth2ClientCredentials(oauthParams); + + final SubscriptionsAuthenticationParamsBasic basicAuthParams = new SubscriptionsAuthenticationParamsBasic(); basicAuthParams.setUserName(decrypedAuth[0]); basicAuthParams.setPassword(decrypedAuth[1]); - - final SubscriptionsAuthentication authentication = new SubscriptionsAuthentication(); authentication.addAuthTypeItem(AuthTypeEnum.BASIC); authentication.paramsBasic(basicAuthParams); return authentication; diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProvider.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProvider.java index 7a0df0fdba..cb8c7c4e56 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProvider.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProvider.java @@ -21,6 +21,7 @@ package org.onap.so.adapters.vnfmadapter.extclients.vnfm; import com.google.common.base.Optional; +import org.onap.aai.domain.yang.EsrVnfm; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse2001; @@ -37,63 +38,67 @@ public interface VnfmServiceProvider { /** * Invoke a get request for a VNF. * + * @param vnfm the VNFM in AAI * @param vnfSelfLink the link to the VNF in the VNFM * @return the VNF from the VNFM */ - Optional<InlineResponse201> getVnf(final String vnfSelfLink); + Optional<InlineResponse201> getVnf(final EsrVnfm vnfm, final String vnfSelfLink); /** * Invoke an instantiate request for a VNF. * + * @param vnfm the VNFM in AAI * @param vnfSelfLink the link to he VNF on the VNFM * @param instantiateVnfRequest the instantiate request * @return the operation ID of the instantiation operation */ - String instantiateVnf(final String vnfSelfLink, final InstantiateVnfRequest instantiateVnfRequest); + String instantiateVnf(final EsrVnfm vnfm, final String vnfSelfLink, + final InstantiateVnfRequest instantiateVnfRequest); /** * Invoke a notification subscription request to a VNFM. * - * @param vnfmId the ID of the VNFM + * @param vnfm the VNFM in AAI * @param subscriptionRequest * @return the response to the subscription request */ - InlineResponse2001 subscribeForNotifications(final String vnfmId, - final LccnSubscriptionRequest subscriptionRequest); + InlineResponse2001 subscribeForNotifications(final EsrVnfm vnfm, final LccnSubscriptionRequest subscriptionRequest); /** * Invoke a terminate request for a VNF. * + * @param vnfm the VNFM in AAI * @param vnfSelfLink the link to he VNF on the VNFM * @param terminateVnfRequest the terminate request * @return the operation ID of the termination operation */ - String terminateVnf(final String vnfSelfLink, final TerminateVnfRequest terminateVnfRequest); + String terminateVnf(final EsrVnfm vnfm, final String vnfSelfLink, final TerminateVnfRequest terminateVnfRequest); /** * Invoke a delete request for a VNF. * + * @param vnfm the VNFM in AAI * @param vnfSelfLink the link to he VNF on the VNFM * @return the operation ID of the instantiation operation */ - void deleteVnf(final String vnfSelfLink); + void deleteVnf(final EsrVnfm vnfm, final String vnfSelfLink); /** * Invoke a get request for a VNFM operation. * - * @param vnfmId the id of the VNFM in AAI + * @param vnfm the VNFM in AAI * @param operationId the id of the operation on the VNFM * @return the operation from the VNFM */ - Optional<InlineResponse200> getOperation(final String vnfmId, final String operationId); + Optional<InlineResponse200> getOperation(final EsrVnfm vnfm, final String operationId); /** * Invoke a create request to a VNFM * - * @param vnfmId the id of the VNFM in AAI + * @param vnfm the VNFM in AAI * @param createVnfRequest the parameters for creating a VNF * @return the newly created VNF */ - Optional<InlineResponse201> createVnf(final String vnfmId, final CreateVnfRequest createVnfRequest); + Optional<InlineResponse201> createVnf(final EsrVnfm vnfm, final CreateVnfRequest createVnfRequest); } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderConfiguration.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderConfiguration.java index ab631837db..a604f9a6b9 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderConfiguration.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderConfiguration.java @@ -29,14 +29,19 @@ import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.util.Iterator; import java.util.ListIterator; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import javax.net.ssl.SSLContext; +import org.apache.commons.lang3.StringUtils; import org.apache.http.client.HttpClient; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContextBuilder; +import org.onap.aai.domain.yang.EsrSystemInfo; +import org.onap.aai.domain.yang.EsrVnfm; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.JSON; import org.onap.so.configuration.rest.BasicHttpHeadersProvider; -import org.onap.so.configuration.rest.HttpHeadersProvider; import org.onap.so.logging.jaxrs.filter.SpringClientFilter; import org.onap.so.rest.service.HttpRestServiceProvider; import org.onap.so.rest.service.HttpRestServiceProviderImpl; @@ -45,7 +50,6 @@ 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.ClientHttpRequestInterceptor; @@ -53,6 +57,8 @@ 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.security.oauth2.client.OAuth2RestTemplate; +import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; import org.springframework.web.client.RestTemplate; /** @@ -62,26 +68,63 @@ import org.springframework.web.client.RestTemplate; public class VnfmServiceProviderConfiguration { private static final Logger logger = LoggerFactory.getLogger(VnfmServiceProviderConfiguration.class); + private Map<String, HttpRestServiceProvider> mapOfVnfmIdToHttpRestServiceProvider = new ConcurrentHashMap<>(); @Value("${http.client.ssl.trust-store:#{null}}") - private Resource keyStore; + private Resource trustStore; @Value("${http.client.ssl.trust-store-password:#{null}}") - private String keyStorePassword; + private String trustPassword; - @Bean(name = "vnfmServiceProvider") - public HttpRestServiceProvider httpRestServiceProvider( - @Qualifier(CONFIGURABLE_REST_TEMPLATE) @Autowired final RestTemplate restTemplate) { - return getHttpRestServiceProvider(restTemplate, new BasicHttpHeadersProvider()); + /** + * This property is only intended to be temporary until the AAI schema is updated to support setting the endpoint + */ + @Value("${vnfmadapter.temp.vnfm.oauth.endpoint:#{null}}") + private String oauthEndpoint; + + @Qualifier(CONFIGURABLE_REST_TEMPLATE) + @Autowired() + private RestTemplate defaultRestTemplate; + + public HttpRestServiceProvider getHttpRestServiceProvider(final EsrVnfm vnfm) { + if (!mapOfVnfmIdToHttpRestServiceProvider.containsKey(vnfm.getVnfmId())) { + mapOfVnfmIdToHttpRestServiceProvider.put(vnfm.getVnfmId(), createHttpRestServiceProvider(vnfm)); + } + return mapOfVnfmIdToHttpRestServiceProvider.get(vnfm.getVnfmId()); } - private HttpRestServiceProvider getHttpRestServiceProvider(final RestTemplate restTemplate, - final HttpHeadersProvider httpHeadersProvider) { + private HttpRestServiceProvider createHttpRestServiceProvider(final EsrVnfm vnfm) { + final RestTemplate restTemplate = createRestTemplate(vnfm); setGsonMessageConverter(restTemplate); - if (keyStore != null) { + if (trustStore != null) { setTrustStore(restTemplate); } removeSpringClientFilter(restTemplate); - return new HttpRestServiceProviderImpl(restTemplate, httpHeadersProvider); + return new HttpRestServiceProviderImpl(restTemplate, new BasicHttpHeadersProvider()); + } + + private RestTemplate createRestTemplate(final EsrVnfm vnfm) { + if (vnfm != null) { + for (final EsrSystemInfo esrSystemInfo : vnfm.getEsrSystemInfoList().getEsrSystemInfo()) { + if (!StringUtils.isEmpty(esrSystemInfo.getUserName()) + && !StringUtils.isEmpty(esrSystemInfo.getPassword())) { + return createOAuth2RestTemplate(esrSystemInfo); + } + } + } + return defaultRestTemplate; + } + + private OAuth2RestTemplate createOAuth2RestTemplate(final EsrSystemInfo esrSystemInfo) { + logger.debug("Getting OAuth2RestTemplate ..."); + final ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails(); + resourceDetails.setId(UUID.randomUUID().toString()); + resourceDetails.setClientId(esrSystemInfo.getUserName()); + resourceDetails.setClientSecret(esrSystemInfo.getPassword()); + resourceDetails.setAccessTokenUri( + oauthEndpoint == null ? esrSystemInfo.getServiceUrl().replace("vnflcm/v1", "oauth/token") + : oauthEndpoint); + resourceDetails.setGrantType("client_credentials"); + return new OAuth2RestTemplate(resourceDetails); } private void setGsonMessageConverter(final RestTemplate restTemplate) { @@ -98,9 +141,9 @@ public class VnfmServiceProviderConfiguration { private void setTrustStore(final RestTemplate restTemplate) { SSLContext sslContext; try { - sslContext = new SSLContextBuilder().loadTrustMaterial(keyStore.getURL(), keyStorePassword.toCharArray()) - .build(); - logger.info("Setting truststore: {}", keyStore.getURL()); + sslContext = + new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustPassword.toCharArray()).build(); + logger.info("Setting truststore: {}", trustStore.getURL()); final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext); final HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build(); final HttpComponentsClientHttpRequestFactory factory = diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderImpl.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderImpl.java index c470008d08..948f5fc269 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderImpl.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderImpl.java @@ -21,6 +21,7 @@ package org.onap.so.adapters.vnfmadapter.extclients.vnfm; import com.google.common.base.Optional; +import org.onap.aai.domain.yang.EsrVnfm; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse2001; @@ -33,7 +34,6 @@ 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.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; @@ -42,28 +42,29 @@ import org.springframework.stereotype.Service; public class VnfmServiceProviderImpl implements VnfmServiceProvider { private static final Logger logger = LoggerFactory.getLogger(VnfmServiceProviderImpl.class); - private final HttpRestServiceProvider httpServiceProvider; + private final VnfmServiceProviderConfiguration vnfmServiceProviderConfiguration; private final VnfmUrlProvider urlProvider; @Autowired public VnfmServiceProviderImpl(final VnfmUrlProvider urlProvider, - @Qualifier("vnfmServiceProvider") final HttpRestServiceProvider httpServiceProvider) { - this.httpServiceProvider = httpServiceProvider; + VnfmServiceProviderConfiguration vnfmServiceProviderConfiguration) { + this.vnfmServiceProviderConfiguration = vnfmServiceProviderConfiguration; this.urlProvider = urlProvider; } @Override - public Optional<InlineResponse201> getVnf(final String vnfSelfLink) { - return httpServiceProvider.get(vnfSelfLink, InlineResponse201.class); + public Optional<InlineResponse201> getVnf(final EsrVnfm vnfm, final String vnfSelfLink) { + return getHttpServiceProvider(vnfm).get(vnfSelfLink, InlineResponse201.class); } @Override - public String instantiateVnf(final String vnfSelfLink, final InstantiateVnfRequest instantiateVnfRequest) { + public String instantiateVnf(final EsrVnfm vnfm, final String vnfSelfLink, + final InstantiateVnfRequest instantiateVnfRequest) { logger.debug("Sending instantiate request " + instantiateVnfRequest + " to : " + vnfSelfLink); ResponseEntity<Void> response = null; try { - response = httpServiceProvider.postHttpRequest(instantiateVnfRequest, vnfSelfLink + "/instantiate", + response = getHttpServiceProvider(vnfm).postHttpRequest(instantiateVnfRequest, vnfSelfLink + "/instantiate", Void.class); } catch (final Exception exception) { final String errorMessage = @@ -82,22 +83,22 @@ public class VnfmServiceProviderImpl implements VnfmServiceProvider { } @Override - public InlineResponse2001 subscribeForNotifications(final String vnfmId, + public InlineResponse2001 subscribeForNotifications(final EsrVnfm vnfm, final LccnSubscriptionRequest subscriptionRequest) { logger.info("Subscribing for notifications {}", subscriptionRequest); - final String url = urlProvider.getSubscriptionsUrl(vnfmId); + final String url = urlProvider.getSubscriptionsUrl(vnfm.getVnfmId()); ResponseEntity<InlineResponse2001> response = null; try { - response = httpServiceProvider.postHttpRequest(subscriptionRequest, url, InlineResponse2001.class); + response = getHttpServiceProvider(vnfm).postHttpRequest(subscriptionRequest, url, InlineResponse2001.class); logger.info("Subscribing for notifications response {}", response); } catch (final Exception exception) { final String errorMessage = - "Subscription to VNFM " + vnfmId + " resulted in exception" + subscriptionRequest; + "Subscription to VNFM " + vnfm.getVnfmId() + " resulted in exception" + subscriptionRequest; logger.error(errorMessage, exception); throw new VnfmRequestFailureException(errorMessage, exception); } if (response.getStatusCode() != HttpStatus.CREATED) { - final String errorMessage = "Subscription to VNFM " + vnfmId + " returned status code: " + final String errorMessage = "Subscription to VNFM " + vnfm.getVnfmId() + " returned status code: " + response.getStatusCode() + ", request: " + subscriptionRequest; logger.error(errorMessage); throw new VnfmRequestFailureException(errorMessage); @@ -106,12 +107,14 @@ public class VnfmServiceProviderImpl implements VnfmServiceProvider { } @Override - public String terminateVnf(final String vnfSelfLink, final TerminateVnfRequest terminateVnfRequest) { + public String terminateVnf(final EsrVnfm vnfm, final String vnfSelfLink, + final TerminateVnfRequest terminateVnfRequest) { logger.debug("Sending terminate request " + terminateVnfRequest + " to : " + vnfSelfLink); ResponseEntity<Void> response = null; try { - response = httpServiceProvider.postHttpRequest(terminateVnfRequest, vnfSelfLink + "/terminate", Void.class); + response = getHttpServiceProvider(vnfm).postHttpRequest(terminateVnfRequest, vnfSelfLink + "/terminate", + Void.class); } catch (final Exception exception) { final String errorMessage = "Terminate request to " + vnfSelfLink + " resulted in exception" + terminateVnfRequest; @@ -130,9 +133,9 @@ public class VnfmServiceProviderImpl implements VnfmServiceProvider { } @Override - public void deleteVnf(final String vnfSelfLink) { + public void deleteVnf(final EsrVnfm vnfm, final String vnfSelfLink) { logger.debug("Sending delete request to : " + vnfSelfLink); - final ResponseEntity<Void> response = httpServiceProvider.deleteHttpRequest(vnfSelfLink, Void.class); + final ResponseEntity<Void> response = getHttpServiceProvider(vnfm).deleteHttpRequest(vnfSelfLink, Void.class); if (response.getStatusCode() != HttpStatus.NO_CONTENT) { throw new VnfmRequestFailureException( "Delete request to " + vnfSelfLink + " return status code: " + response.getStatusCode()); @@ -140,23 +143,27 @@ public class VnfmServiceProviderImpl implements VnfmServiceProvider { } @Override - public Optional<InlineResponse200> getOperation(final String vnfmId, final String operationId) { - final String url = urlProvider.getOperationUrl(vnfmId, operationId); - return httpServiceProvider.get(url, InlineResponse200.class); + public Optional<InlineResponse200> getOperation(final EsrVnfm vnfm, final String operationId) { + final String url = urlProvider.getOperationUrl(vnfm.getVnfmId(), operationId); + return getHttpServiceProvider(vnfm).get(url, InlineResponse200.class); } @Override - public Optional<InlineResponse201> createVnf(final String vnfmId, final CreateVnfRequest createVnfRequest) { - final String url = urlProvider.getCreationUrl(vnfmId); + public Optional<InlineResponse201> createVnf(final EsrVnfm vnfm, final CreateVnfRequest createVnfRequest) { + final String url = urlProvider.getCreationUrl(vnfm.getVnfmId()); logger.debug("Sending create request {} to : {}", createVnfRequest, url); try { - return httpServiceProvider.post(createVnfRequest, url, InlineResponse201.class); + return getHttpServiceProvider(vnfm).post(createVnfRequest, url, InlineResponse201.class); } catch (final Exception exception) { final String errorMessage = - "Create request to vnfm:" + vnfmId + " resulted in exception" + createVnfRequest; + "Create request to vnfm:" + vnfm.getVnfmId() + " resulted in exception" + createVnfRequest; logger.error(errorMessage, exception); throw new VnfmRequestFailureException(errorMessage, exception); } } + private HttpRestServiceProvider getHttpServiceProvider(final EsrVnfm vnfm) { + return vnfmServiceProviderConfiguration.getHttpRestServiceProvider(vnfm); + } + } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/jobmanagement/JobManager.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/jobmanagement/JobManager.java index 537bb77b32..d01e5b186c 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/jobmanagement/JobManager.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/jobmanagement/JobManager.java @@ -25,6 +25,7 @@ import com.google.common.base.Optional; import com.google.common.collect.Maps; import java.util.Map; import java.util.UUID; +import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiServiceProvider; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmServiceProvider; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200; import org.onap.so.adapters.vnfmadapter.rest.exceptions.JobNotFoundException; @@ -45,10 +46,12 @@ public class JobManager { private static Logger logger = getLogger(JobManager.class); private final Map<String, VnfmOperation> mapOfJobIdToVnfmOperation = Maps.newConcurrentMap(); private final VnfmServiceProvider vnfmServiceProvider; + private final AaiServiceProvider aaiServiceProvider; @Autowired - JobManager(final VnfmServiceProvider vnfmServiceProvider) { + JobManager(final VnfmServiceProvider vnfmServiceProvider, final AaiServiceProvider aaiServiceProvider) { this.vnfmServiceProvider = vnfmServiceProvider; + this.aaiServiceProvider = aaiServiceProvider; } /** @@ -90,16 +93,15 @@ public class JobManager { } try { - final Optional<InlineResponse200> operationOptional = - vnfmServiceProvider.getOperation(vnfmOperation.getVnfmId(), vnfmOperation.getOperationId()); + final Optional<InlineResponse200> operationOptional = vnfmServiceProvider.getOperation( + aaiServiceProvider.invokeGetVnfm(vnfmOperation.getVnfmId()), vnfmOperation.getOperationId()); if (!operationOptional.isPresent()) { return response.operationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.OPERATION_NOT_FOUND); } final InlineResponse200 operation = operationOptional.get(); - logger.debug( - "Job Id: " + jobId + ", operationId: " + operation.getId() + ", operation details: " + operation); + logger.debug("Job Id: {} operationId: {} operation details: {} ", jobId, operation.getId(), operation); if (operation.getOperationState() == null) { return response.operationStatusRetrievalStatus(OperationStatusRetrievalStatusEnum.WAITING_FOR_STATUS); @@ -145,7 +147,8 @@ public class JobManager { if (relatedOperation.isPresent()) { relatedOperation.get().setNotificationProcessed(notificationProcessingWasSuccessful); } else { - logger.debug("No operation found for operation ID " + operationId); + logger.debug("No operation found for operation ID {} ", operationId); + } } @@ -156,7 +159,7 @@ public class JobManager { if (relatedOperation.isPresent()) { relatedOperation.get().setVnfDeleted();; } else { - logger.debug("No operation found for operation ID " + operationId); + logger.debug("No operation found for operation ID {} ", operationId); } } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/lifecycle/LifecycleManager.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/lifecycle/LifecycleManager.java index fa2fa30b4a..0aad91e5be 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/lifecycle/LifecycleManager.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/lifecycle/LifecycleManager.java @@ -82,16 +82,15 @@ public class LifecycleManager { */ public CreateVnfResponse createVnf(final String vnfIdInAai, final CreateVnfRequest request) { final GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai); - checkIfVnfAlreadyExistsInVnfm(genericVnf); - EsrVnfm vnfm = aaiHelper.getAssignedVnfm(genericVnf); + checkIfVnfAlreadyExistsInVnfm(vnfm, genericVnf); + if (vnfm == null) { vnfm = aaiHelper.selectVnfm(genericVnf); aaiHelper.addRelationshipFromGenericVnfToVnfm(genericVnf, vnfm.getVnfmId()); } aaiHelper.addRelationshipFromGenericVnfToTenant(genericVnf, request.getTenant()); - final InlineResponse201 vnfmResponse = - sendCreateRequestToVnfm(request, genericVnf, vnfIdInAai, vnfm.getVnfmId()); + final InlineResponse201 vnfmResponse = sendCreateRequestToVnfm(request, genericVnf, vnfIdInAai, vnfm); logger.info("Create response: {}", vnfmResponse); @@ -102,8 +101,8 @@ public class LifecycleManager { final OamIpAddressSource oamIpAddressSource = extractOamIpAddressSource(request); aaiHelper.setOamIpAddressSource(vnfIdInVnfm, oamIpAddressSource); - createNotificationSubscription(vnfm.getVnfmId(), vnfIdInVnfm); - final String operationId = sendInstantiateRequestToVnfm(vnfm, genericVnf, request, vnfIdInAai, vnfIdInVnfm); + createNotificationSubscription(vnfm, vnfIdInVnfm); + final String operationId = sendInstantiateRequestToVnfm(vnfm, genericVnf, request); final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, false); final CreateVnfResponse response = new CreateVnfResponse(); @@ -133,11 +132,11 @@ public class LifecycleManager { } } - private void checkIfVnfAlreadyExistsInVnfm(final GenericVnf genericVnf) { - if (genericVnf.getSelflink() != null && !genericVnf.getSelflink().isEmpty()) { + private void checkIfVnfAlreadyExistsInVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf) { + if (genericVnf.getSelflink() != null && !genericVnf.getSelflink().isEmpty() && vnfm != null) { Optional<InlineResponse201> response = Optional.absent(); try { - response = vnfmServiceProvider.getVnf(genericVnf.getSelflink()); + response = vnfmServiceProvider.getVnf(vnfm, genericVnf.getSelflink()); } catch (final Exception exception) { logger.debug("Ignoring invalid self link in generic vnf", exception); } @@ -149,7 +148,7 @@ public class LifecycleManager { } private InlineResponse201 sendCreateRequestToVnfm(final CreateVnfRequest aaiRequest, final GenericVnf genericVnf, - final String vnfIdInAai, final String vnfmId) { + final String vnfIdInAai, final EsrVnfm vnfm) { logger.debug("Sending a create request to SVNFM " + aaiRequest); final org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest vnfmRequest = new org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest(); @@ -159,7 +158,7 @@ public class LifecycleManager { vnfmRequest.setVnfInstanceName(aaiRequest.getName().replaceAll(" ", "_")); vnfmRequest.setVnfInstanceDescription(vnfIdInAai); - final Optional<InlineResponse201> optionalResponse = vnfmServiceProvider.createVnf(vnfmId, vnfmRequest); + final Optional<InlineResponse201> optionalResponse = vnfmServiceProvider.createVnf(vnfm, vnfmRequest); try { return optionalResponse.get(); @@ -170,24 +169,24 @@ public class LifecycleManager { } } - private void createNotificationSubscription(final String vnfmId, final String vnfId) { + private void createNotificationSubscription(final EsrVnfm vnfm, final String vnfId) { try { final LccnSubscriptionRequest subscriptionRequest = vnfmHelper.createNotificationSubscriptionRequest(vnfId); - vnfmServiceProvider.subscribeForNotifications(vnfmId, subscriptionRequest); + vnfmServiceProvider.subscribeForNotifications(vnfm, subscriptionRequest); } catch (final Exception exception) { - logger.warn("Subscription for notifications to VNFM: " + vnfmId + " for VNF " + vnfId + logger.warn("Subscription for notifications to VNFM: " + vnfm.getVnfmId() + " for VNF " + vnfId + " failed. AAI will not be updated unless the VNFM is configured by other means to send notifications relating to this VNF", exception); } } private String sendInstantiateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf, - final CreateVnfRequest createVnfRequest, final String vnfIdInAai, final String vnfIdInVnfm) { + final CreateVnfRequest createVnfRequest) { final InstantiateVnfRequest instantiateVnfRequest = vnfmHelper.createInstantiateRequest(createVnfRequest.getTenant(), createVnfRequest, packageProvider.getFlavourId(genericVnf.getModelVersionId())); - final String jobId = vnfmServiceProvider.instantiateVnf(genericVnf.getSelflink(), instantiateVnfRequest); + final String jobId = vnfmServiceProvider.instantiateVnf(vnfm, genericVnf.getSelflink(), instantiateVnfRequest); logger.info("Instantiate VNF request successfully sent to " + genericVnf.getSelflink()); return jobId; @@ -201,18 +200,18 @@ public class LifecycleManager { */ public DeleteVnfResponse deleteVnf(final String vnfIdInAai) { final GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai); - final String vnfmId = getIdOfAssignedVnfm(genericVnf); + final EsrVnfm vnfm = getAssignedVnfm(genericVnf); - final String operationId = sendTerminateRequestToVnfm(genericVnf); - final String jobId = jobManager.createJob(vnfmId, operationId, true); + final String operationId = sendTerminateRequestToVnfm(vnfm, genericVnf); + final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, true); return new DeleteVnfResponse().jobId(jobId); } - private String sendTerminateRequestToVnfm(final GenericVnf genericVnf) { + private String sendTerminateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf) { final TerminateVnfRequest terminateVnfRequest = new TerminateVnfRequest(); terminateVnfRequest.setTerminationType(TerminationTypeEnum.FORCEFUL); - return vnfmServiceProvider.terminateVnf(genericVnf.getSelflink(), terminateVnfRequest); + return vnfmServiceProvider.terminateVnf(vnfm, genericVnf.getSelflink(), terminateVnfRequest); } private GenericVnf getGenericVnfFromAai(final String vnfIdInAai) { @@ -224,11 +223,11 @@ public class LifecycleManager { return genericVnf; } - private String getIdOfAssignedVnfm(final GenericVnf genericVnf) { - final String vnfmId = aaiHelper.getIdOfAssignedVnfm(genericVnf); - if (vnfmId == null) { + private EsrVnfm getAssignedVnfm(final GenericVnf genericVnf) { + final EsrVnfm vnfm = aaiHelper.getAssignedVnfm(genericVnf); + if (vnfm == null) { throw new VnfmNotFoundException("No VNFM found in AAI for VNF " + genericVnf.getVnfId()); } - return vnfmId; + return vnfm; } } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/notificationhandling/NotificationHandler.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/notificationhandling/NotificationHandler.java index 93c7ea91ff..eb912c8775 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/notificationhandling/NotificationHandler.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/notificationhandling/NotificationHandler.java @@ -156,7 +156,7 @@ public class NotificationHandler implements Runnable { boolean deleteSuccessful = false; try { - vnfmServiceProvider.deleteVnf(genericVnf.getSelflink()); + vnfmServiceProvider.deleteVnf(aaiHelper.getAssignedVnfm(genericVnf), genericVnf.getSelflink()); deleteSuccessful = true; } finally { jobManager.notificationProcessedForOperation(vnfLcmOperationOccurrenceNotification.getVnfLcmOpOccId(), diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/AuthorizationServerConfig.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/AuthorizationServerConfig.java new file mode 100644 index 0000000000..7f71b2e9d6 --- /dev/null +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/AuthorizationServerConfig.java @@ -0,0 +1,55 @@ +/*- + * ============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.vnfmadapter.oauth; + +import org.onap.so.utils.CryptoUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; + +@Configuration +@EnableAuthorizationServer +/** + * Configures the authorization server for oauth token based authentication. + */ +public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { + + private static final int ONE_DAY = 60 * 60 * 24; + + @Value("${vnfmadapter.auth:E39823AAB2739CC654C4E92B52C05BC34149342D0A46451B00CA508C8EDC62242CE4E9DA9445D3C01A3F13}") + private String vnfmAdapterAuth; + + @Value("${mso.key}") + private String msoEncryptionKey; + + @Override + public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { + final String[] decrypedAuth = CryptoUtils.decrypt(vnfmAdapterAuth, msoEncryptionKey).split(":"); + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + clients.inMemory().withClient(decrypedAuth[0]).secret(passwordEncoder.encode(decrypedAuth[1])) + .authorizedGrantTypes("client_credentials").scopes("write").accessTokenValiditySeconds(ONE_DAY) + .refreshTokenValiditySeconds(ONE_DAY); + } + +} diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2AccessTokenAdapter.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2AccessTokenAdapter.java new file mode 100644 index 0000000000..2f51406e23 --- /dev/null +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2AccessTokenAdapter.java @@ -0,0 +1,51 @@ +/*- + * ============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.vnfmadapter.oauth; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import java.lang.reflect.Type; +import org.springframework.security.oauth2.common.OAuth2AccessToken; + +public class OAuth2AccessTokenAdapter implements JsonSerializer<OAuth2AccessToken> { + + @Override + public JsonElement serialize(final OAuth2AccessToken src, final Type typeOfSrc, + final JsonSerializationContext context) { + final JsonObject obj = new JsonObject(); + obj.addProperty(OAuth2AccessToken.ACCESS_TOKEN, src.getValue()); + obj.addProperty(OAuth2AccessToken.TOKEN_TYPE, src.getTokenType()); + if (src.getRefreshToken() != null) { + obj.addProperty(OAuth2AccessToken.REFRESH_TOKEN, src.getRefreshToken().getValue()); + } + obj.addProperty(OAuth2AccessToken.EXPIRES_IN, src.getExpiresIn()); + final JsonArray scopeObj = new JsonArray(); + for (final String scope : src.getScope()) { + scopeObj.add(scope); + } + obj.add(OAuth2AccessToken.SCOPE, scopeObj); + + return obj; + } +} diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2ResourceServer.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2ResourceServer.java new file mode 100644 index 0000000000..1f0594e811 --- /dev/null +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/oauth/OAuth2ResourceServer.java @@ -0,0 +1,52 @@ +/*- + * ============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.vnfmadapter.oauth; + +import javax.servlet.http.HttpServletRequest; +import org.onap.so.adapters.vnfmadapter.Constants; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; +import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; +import org.springframework.security.web.util.matcher.RequestMatcher; + +@Configuration +@EnableResourceServer +/** + * Enforces oauth token based authentication when a token is provided in the request. + */ +public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter { + + @Override + public void configure(final HttpSecurity http) throws Exception { + http.requestMatcher(new OAuth2ResourceServerRequestMatcher()).authorizeRequests() + .antMatchers(Constants.BASE_URL + "/grants/**", Constants.BASE_URL + "/lcn/**").authenticated(); + } + + private static class OAuth2ResourceServerRequestMatcher implements RequestMatcher { + @Override + public boolean matches(HttpServletRequest request) { + String auth = request.getHeader("Authorization"); + String uri = request.getRequestURI(); + return (auth != null && auth.startsWith("Bearer") && (uri.contains("/grants") || uri.contains("/lcn/"))); + } + } +} diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/rest/Sol003LcnContoller.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/rest/Sol003LcnContoller.java index 9cb09e6261..f97822a0cd 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/rest/Sol003LcnContoller.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/rest/Sol003LcnContoller.java @@ -20,6 +20,14 @@ package org.onap.so.adapters.vnfmadapter.rest; +import static org.onap.so.adapters.vnfmadapter.Constants.BASE_URL; +import static org.onap.so.adapters.vnfmadapter.Constants.OPERATION_NOTIFICATION_ENDPOINT; +import static org.slf4j.LoggerFactory.getLogger; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import javax.ws.rs.core.MediaType; +import org.onap.aai.domain.yang.EsrVnfm; +import org.onap.aai.domain.yang.GenericVnf; import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiHelper; import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiServiceProvider; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmServiceProvider; @@ -39,12 +47,6 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import javax.ws.rs.core.MediaType; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import static org.onap.so.adapters.vnfmadapter.Constants.BASE_URL; -import static org.onap.so.adapters.vnfmadapter.Constants.OPERATION_NOTIFICATION_ENDPOINT; -import static org.slf4j.LoggerFactory.getLogger; /** * Controller for handling notifications from the VNFM (Virtual Network Function Manager). @@ -118,8 +120,12 @@ public class Sol003LcnContoller { private InlineResponse201 getVnfInstance( final VnfLcmOperationOccurrenceNotification vnfLcmOperationOccurrenceNotification) { - return vnfmServiceProvider.getVnf(vnfLcmOperationOccurrenceNotification.getLinks().getVnfInstance().getHref()) - .get(); + GenericVnf vnfInAai = aaiServiceProvider + .invokeQueryGenericVnf(vnfLcmOperationOccurrenceNotification.getLinks().getVnfInstance().getHref()) + .getGenericVnf().get(0); + EsrVnfm vnfm = aaiHelper.getAssignedVnfm(vnfInAai); + return vnfmServiceProvider + .getVnf(vnfm, vnfLcmOperationOccurrenceNotification.getLinks().getVnfInstance().getHref()).get(); } } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/Sol003LcnControllerTest.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/Sol003LcnControllerTest.java index aeb7cd3540..89a2c102f4 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/Sol003LcnControllerTest.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/Sol003LcnControllerTest.java @@ -46,6 +46,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.hamcrest.MockitoHamcrest; +import org.onap.aai.domain.yang.EsrSystemInfoList; +import org.onap.aai.domain.yang.EsrVnfm; import org.onap.aai.domain.yang.GenericVnf; import org.onap.aai.domain.yang.GenericVnfs; import org.onap.aai.domain.yang.Relationship; @@ -169,6 +171,7 @@ public class Sol003LcnControllerTest { .andRespond(withSuccess(gson.toJson(vnfInstance), MediaType.APPLICATION_JSON)); final GenericVnf genericVnf = createGenericVnf("vnfmType1"); + addRelationshipFromGenericVnfToVnfm(genericVnf, "vnfm1"); final List<GenericVnf> listOfGenericVnfs = new ArrayList<>(); listOfGenericVnfs.add(genericVnf); final GenericVnfs genericVnfs = new GenericVnfs(); @@ -176,6 +179,12 @@ public class Sol003LcnControllerTest { doReturn(Optional.of(genericVnfs)).when(aaiResourcesClient).get(eq(GenericVnfs.class), MockitoHamcrest.argThat(new AaiResourceUriMatcher( "/network/generic-vnfs?selflink=http%3A%2F%2Fvnfm%3A8080%2Fvnfs%2FmyTestVnfIdOnVnfm"))); + EsrVnfm vnfm = new EsrVnfm(); + vnfm.setVnfmId("vnfm1"); + final EsrSystemInfoList esrSystemInfoList = new EsrSystemInfoList(); + vnfm.setEsrSystemInfoList(esrSystemInfoList); + doReturn(Optional.of(vnfm)).when(aaiResourcesClient).get(eq(EsrVnfm.class), MockitoHamcrest + .argThat(new AaiResourceUriMatcher("/external-system/esr-vnfm-list/esr-vnfm/vnfm1?depth=1"))); final ResponseEntity<Void> response = controller.lcnVnfLcmOperationOccurrenceNotificationPost(vnfLcmOperationOccurrenceNotification); @@ -226,6 +235,7 @@ public class Sol003LcnControllerTest { .andRespond(withStatus(HttpStatus.NO_CONTENT).contentType(MediaType.APPLICATION_JSON)); final GenericVnf genericVnf = createGenericVnf("vnfmType1"); + addRelationshipFromGenericVnfToVnfm(genericVnf, "vnfm1"); genericVnf.setSelflink("http://vnfm:8080/vnfs/myTestVnfIdOnVnfm"); final List<GenericVnf> listOfGenericVnfs = new ArrayList<>(); listOfGenericVnfs.add(genericVnf); @@ -236,6 +246,12 @@ public class Sol003LcnControllerTest { doReturn(Optional.of(genericVnfs)).when(aaiResourcesClient).get(eq(GenericVnfs.class), MockitoHamcrest.argThat(new AaiResourceUriMatcher( "/network/generic-vnfs?selflink=http%3A%2F%2Fvnfm%3A8080%2Fvnfs%2FmyTestVnfIdOnVnfm"))); + EsrVnfm vnfm = new EsrVnfm(); + vnfm.setVnfmId("vnfm1"); + final EsrSystemInfoList esrSystemInfoList = new EsrSystemInfoList(); + vnfm.setEsrSystemInfoList(esrSystemInfoList); + doReturn(Optional.of(vnfm)).when(aaiResourcesClient).get(eq(EsrVnfm.class), MockitoHamcrest + .argThat(new AaiResourceUriMatcher("/external-system/esr-vnfm-list/esr-vnfm/vnfm1?depth=1"))); final ResponseEntity<Void> response = controller.lcnVnfLcmOperationOccurrenceNotificationPost(vnfLcmOperationOccurrenceNotification); @@ -323,6 +339,22 @@ public class Sol003LcnControllerTest { return genericVnf; } + private void addRelationshipFromGenericVnfToVnfm(final GenericVnf genericVnf, final String vnfmId) { + final Relationship relationshipToVnfm = new Relationship(); + relationshipToVnfm.setRelatedLink("/aai/v15/external-system/esr-vnfm-list/esr-vnfm/" + vnfmId); + relationshipToVnfm.setRelatedTo("esr-vnfm"); + final RelationshipData relationshipData = new RelationshipData(); + relationshipData.setRelationshipKey("esr-vnfm.vnfm-id"); + relationshipData.setRelationshipValue(vnfmId); + relationshipToVnfm.getRelationshipData().add(relationshipData); + + if (genericVnf.getRelationshipList() == null) { + final RelationshipList relationshipList = new RelationshipList(); + genericVnf.setRelationshipList(relationshipList); + } + genericVnf.getRelationshipList().getRelationship().add(relationshipToVnfm); + } + private void addRelationshipFromGenericVnfToVserver(final GenericVnf genericVnf, final String vserverId) { final Relationship relationshipToVserver = new Relationship(); relationshipToVserver.setRelatedTo("vserver"); @@ -343,9 +375,11 @@ public class Sol003LcnControllerTest { relationshipData4.setRelationshipValue(TENANT_ID); relationshipToVserver.getRelationshipData().add(relationshipData4); - final RelationshipList relationshipList = new RelationshipList(); - relationshipList.getRelationship().add(relationshipToVserver); - genericVnf.setRelationshipList(relationshipList); + if (genericVnf.getRelationshipList() == null) { + final RelationshipList relationshipList = new RelationshipList(); + genericVnf.setRelationshipList(relationshipList); + } + genericVnf.getRelationshipList().getRelationship().add(relationshipToVserver); } private class AaiResourceUriMatcher extends BaseMatcher<AAIResourceUri> { diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/VnfmAdapterControllerTest.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/VnfmAdapterControllerTest.java index b48de30f88..6cdabb9374 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/VnfmAdapterControllerTest.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/VnfmAdapterControllerTest.java @@ -133,7 +133,7 @@ public class VnfmAdapterControllerTest { setUpVimInMockAai(); final String expectedsubscriptionRequest = - "{\"filter\":{\"vnfInstanceSubscriptionFilter\":{\"vnfInstanceIds\":[\"vnfId\"]},\"notificationTypes\":[\"VnfLcmOperationOccurrenceNotification\"]},\"callbackUri\":\"https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/lcn/VnfLcmOperationOccurrenceNotification\",\"authentication\":{\"authType\":[\"BASIC\"],\"paramsBasic\":{\"userName\":\"vnfm\",\"password\":\"password1$\"}}}"; + "{\"filter\":{\"vnfInstanceSubscriptionFilter\":{\"vnfInstanceIds\":[\"vnfId\"]},\"notificationTypes\":[\"VnfLcmOperationOccurrenceNotification\"]},\"callbackUri\":\"https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/lcn/VnfLcmOperationOccurrenceNotification\",\"authentication\":{\"authType\":[\"OAUTH2_CLIENT_CREDENTIALS\", \"BASIC\"],\"paramsOauth2ClientCredentials\":{\"clientId\":\"vnfm\",\"clientPassword\":\"password1$\",\"tokenEndpoint\":\"https://so-vnfm-adapter.onap:30406/oauth/token\"},\"paramsBasic\":{\"userName\":\"vnfm\",\"password\":\"password1$\"}}}"; final InlineResponse2001 subscriptionResponse = new InlineResponse2001(); final InlineResponse201 createResponse = createCreateResponse(); @@ -214,6 +214,8 @@ public class VnfmAdapterControllerTest { final GenericVnf genericVnf = setUpGenericVnfInMockAai("vnfmType1"); addSelfLinkToGenericVnf(genericVnf); + addRelationshipFromGenericVnfToVnfm(genericVnf, "vnfm1"); + setUpVnfmsInMockAai(); final InlineResponse201 reponse = new InlineResponse201(); mockRestServer.expect(requestTo(new URI("http://vnfm:8080/vnfs/myTestVnfIdOnVnfm"))) @@ -239,7 +241,7 @@ public class VnfmAdapterControllerTest { final CreateVnfRequest createVnfRequest = new CreateVnfRequest().name("myTestName").tenant(tenant); final GenericVnf genericVnf = setUpGenericVnfInMockAai("vnfmType2"); - addRelationshipFromGenericVnfToVnfm(genericVnf, "vnfm1"); + addRelationshipFromGenericVnfToVnfm(genericVnf, "vnfm2"); setUpVnfmsInMockAai(); setUpVimInMockAai(); @@ -279,24 +281,25 @@ public class VnfmAdapterControllerTest { public void deleteVnf_ValidRequest_Returns202AndJobId() throws Exception { final TestRestTemplate restTemplate = new TestRestTemplate("test", "test"); - final GenericVnf genericVnf = setUpGenericVnfInMockAai("vnfmType"); + final GenericVnf genericVnf = setUpGenericVnfInMockAai("vnfmType1"); addSelfLinkToGenericVnf(genericVnf); - addRelationshipFromGenericVnfToVnfm(genericVnf, "vnfm"); + addRelationshipFromGenericVnfToVnfm(genericVnf, "vnfm1"); + setUpVnfmsInMockAai(); mockRestServer.expect(requestTo("http://vnfm:8080/vnfs/myTestVnfIdOnVnfm/terminate")) .andRespond(withStatus(HttpStatus.ACCEPTED).contentType(MediaType.APPLICATION_JSON) - .location(new URI("http://vnfm2:8080/vnf_lcm_op_occs/1234567"))); + .location(new URI("http://vnfm1:8080/vnf_lcm_op_occs/1234567"))); final InlineResponse200 firstOperationQueryResponse = createOperationQueryResponse( org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200.OperationEnum.TERMINATE, org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200.OperationStateEnum.PROCESSING); - mockRestServer.expect(requestTo("http://vnfm:8080/vnf_lcm_op_occs/1234567")) + mockRestServer.expect(requestTo("http://vnfm1:8080/vnf_lcm_op_occs/1234567")) .andRespond(withSuccess(gson.toJson(firstOperationQueryResponse), MediaType.APPLICATION_JSON)); final InlineResponse200 secondOperationQueryReponse = createOperationQueryResponse( org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200.OperationEnum.TERMINATE, org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200.OperationStateEnum.COMPLETED); - mockRestServer.expect(requestTo("http://vnfm:8080/vnf_lcm_op_occs/1234567")) + mockRestServer.expect(requestTo("http://vnfm1:8080/vnf_lcm_op_occs/1234567")) .andRespond(withSuccess(gson.toJson(secondOperationQueryReponse), MediaType.APPLICATION_JSON)); final RequestEntity<Void> request = RequestEntity @@ -308,16 +311,6 @@ public class VnfmAdapterControllerTest { assertEquals(202, deleteVnfResponse.getStatusCode().value()); assertNotNull(deleteVnfResponse.getBody().getJobId()); - final EsrSystemInfo esrSystemInfo = new EsrSystemInfo(); - esrSystemInfo.setServiceUrl("http://vnfm:8080"); - esrSystemInfo.setType("vnfmType"); - esrSystemInfo.setSystemType("VNFM"); - final EsrSystemInfoList esrSystemInfoList = new EsrSystemInfoList(); - esrSystemInfoList.getEsrSystemInfo().add(esrSystemInfo); - - doReturn(Optional.of(esrSystemInfoList)).when(aaiResourcesClient).get(eq(EsrSystemInfoList.class), - MockitoHamcrest.argThat(new AaiResourceUriMatcher("/external-system/esr-vnfm-list/esr-vnfm/..."))); - final ResponseEntity<QueryJobResponse> firstJobQueryResponse = controller.jobQuery(deleteVnfResponse.getBody().getJobId(), "", "so", "1213"); assertEquals(OperationEnum.TERMINATE, firstJobQueryResponse.getBody().getOperation()); @@ -367,9 +360,10 @@ public class VnfmAdapterControllerTest { public void deleteVnf_ErrorStatusCodeFromVnfm_Returns500() throws Exception { final TestRestTemplate restTemplate = new TestRestTemplate("test", "test"); - final GenericVnf genericVnf = setUpGenericVnfInMockAai("vnfmType"); + final GenericVnf genericVnf = setUpGenericVnfInMockAai("vnfmType1"); addSelfLinkToGenericVnf(genericVnf); - addRelationshipFromGenericVnfToVnfm(genericVnf, "vnfm"); + addRelationshipFromGenericVnfToVnfm(genericVnf, "vnfm1"); + setUpVnfmsInMockAai(); mockRestServer.expect(requestTo("http://vnfm:8080/vnfs/myTestVnfIdOnVnfm/terminate")) .andRespond(withStatus(HttpStatus.BAD_REQUEST).contentType(MediaType.APPLICATION_JSON)); @@ -419,12 +413,7 @@ public class VnfmAdapterControllerTest { private void addRelationshipFromGenericVnfToVnfm(final GenericVnf genericVnf, final String vnfmId) { final Relationship relationshipToVnfm = new Relationship(); - relationshipToVnfm.setRelatedLink( - "/aai/v15/external-system/esr-vnfm-li// final InlineResponse201 vnfInstance = new InlineResponse201();\n" - + "// vnfInstance.setInstantiationState(InstantiationStateEnum.NOT_INSTANTIATED);\n" - + "// mockRestServer.expect(requestTo(\"http://dummy.value/until/create/implememted/vnfId\"))\n" - + "// .andRespond(withSuccess(gson.toJson(vnfInstance), MediaType.APPLICATION_JSON));st/esr-vnfm/" - + vnfmId); + relationshipToVnfm.setRelatedLink("/aai/v15/external-system/esr-vnfm-list/esr-vnfm/" + vnfmId); relationshipToVnfm.setRelatedTo("esr-vnfm"); final RelationshipData relationshipData = new RelationshipData(); relationshipData.setRelationshipKey("esr-vnfm.vnfm-id"); @@ -465,6 +454,12 @@ public class VnfmAdapterControllerTest { esrVnfmList.getEsrVnfm().add(esrVnfm1); esrVnfmList.getEsrVnfm().add(esrVnfm2); + doReturn(Optional.of(esrVnfm1)).when(aaiResourcesClient).get(eq(EsrVnfm.class), MockitoHamcrest + .argThat(new AaiResourceUriMatcher("/external-system/esr-vnfm-list/esr-vnfm/vnfm1?depth=1"))); + + doReturn(Optional.of(esrVnfm2)).when(aaiResourcesClient).get(eq(EsrVnfm.class), MockitoHamcrest + .argThat(new AaiResourceUriMatcher("/external-system/esr-vnfm-list/esr-vnfm/vnfm2?depth=1"))); + doReturn(Optional.of(esrVnfmList)).when(aaiResourcesClient).get(eq(EsrVnfmList.class), MockitoHamcrest.argThat(new AaiResourceUriMatcher("/external-system/esr-vnfm-list"))); diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/BBInputSetup.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/BBInputSetup.java index 9a39334af1..433aa0c11a 100644 --- a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/BBInputSetup.java +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/BBInputSetup.java @@ -1388,8 +1388,10 @@ public class BBInputSetup implements JavaDelegate { vnfs.getInstanceParams(), productFamilyId); } else if (bbName.contains(VF_MODULE) || bbName.contains(VOLUME_GROUP)) { Pair<Vnfs, VfModules> vnfsAndVfModules = getVfModulesAndItsVnfsByKey(key, resources); - vfModules = vnfsAndVfModules.getValue1(); - vnfs = vnfsAndVfModules.getValue0(); + if (vnfsAndVfModules != null) { + vfModules = vnfsAndVfModules.getValue1(); + vnfs = vnfsAndVfModules.getValue0(); + } lookupKeyMap.put(ResourceKey.GENERIC_VNF_ID, getVnfId(executeBB, lookupKeyMap)); if (vnfs == null) { throw new Exception("Could not find Vnf to orchestrate VfModule"); @@ -1410,8 +1412,10 @@ public class BBInputSetup implements JavaDelegate { } else if (bbName.contains(NETWORK)) { networks = findNetworksByKey(key, resources); String networkId = lookupKeyMap.get(ResourceKey.NETWORK_ID); - this.populateL3Network(networks.getInstanceName(), networks.getModelInfo(), service, bbName, - serviceInstance, lookupKeyMap, networkId, networks.getInstanceParams()); + if (networks != null) { + this.populateL3Network(networks.getInstanceName(), networks.getModelInfo(), service, bbName, + serviceInstance, lookupKeyMap, networkId, networks.getInstanceParams()); + } } else if (bbName.contains("Configuration")) { String configurationId = lookupKeyMap.get(ResourceKey.CONFIGURATION_ID); ModelInfo configurationModelInfo = new ModelInfo(); @@ -1608,8 +1612,10 @@ public class BBInputSetup implements JavaDelegate { protected void mapCatalogNetworkCollectionInstanceGroup(Service service, InstanceGroup instanceGroup, String key) { CollectionResourceCustomization collectionCust = this.findCatalogNetworkCollection(service, key); - org.onap.so.db.catalog.beans.InstanceGroup catalogInstanceGroup = - collectionCust.getCollectionResource().getInstanceGroup(); + org.onap.so.db.catalog.beans.InstanceGroup catalogInstanceGroup = null; + if (collectionCust != null) { + catalogInstanceGroup = collectionCust.getCollectionResource().getInstanceGroup(); + } instanceGroup.setModelInfoInstanceGroup( mapperLayer.mapCatalogInstanceGroupToInstanceGroup(collectionCust, catalogInstanceGroup)); } diff --git a/bpmn/MSOCoreBPMN/src/main/java/org/onap/so/bpmn/core/BaseTask.java b/bpmn/MSOCoreBPMN/src/main/java/org/onap/so/bpmn/core/BaseTask.java index 2e66493a25..1442099286 100644 --- a/bpmn/MSOCoreBPMN/src/main/java/org/onap/so/bpmn/core/BaseTask.java +++ b/bpmn/MSOCoreBPMN/src/main/java/org/onap/so/bpmn/core/BaseTask.java @@ -86,8 +86,13 @@ public class BaseTask implements JavaDelegate { } return variable; } else { - throw new BadInjectedFieldException(fieldName, getTaskName(), - "expected a variable name string" + ", got object of type " + o.getClass().getName()); + if (o != null) { + throw new BadInjectedFieldException(fieldName, getTaskName(), + "expected a variable name string, got object of type " + o.getClass().getName()); + } else { + throw new BadInjectedFieldException(fieldName, getTaskName(), + "expected a variable name string, got null object"); + } } } @@ -114,7 +119,7 @@ public class BaseTask implements JavaDelegate { return null; } else { throw new BadInjectedFieldException(fieldName, getTaskName(), - "expected a variable name string" + ", got object of type " + o.getClass().getName()); + "expected a variable name string, got object of type " + o.getClass().getName()); } } @@ -133,9 +138,11 @@ public class BaseTask implements JavaDelegate { Object o = getFieldImpl(expression, execution, fieldName, false); if (o instanceof String) { return (String) o; - } else { + } else if (o != null) { throw new BadInjectedFieldException(fieldName, getTaskName(), "cannot convert '" + o.toString() + "' to Integer"); + } else { + throw new MissingInjectedFieldException(fieldName, getTaskName()); } } @@ -189,8 +196,12 @@ public class BaseTask implements JavaDelegate { try { return Integer.parseInt(o.toString()); } catch (NumberFormatException e) { - throw new BadInjectedFieldException(fieldName, getTaskName(), - "cannot convert '" + o.toString() + "' to Integer"); + if (o != null) { + throw new BadInjectedFieldException(fieldName, getTaskName(), + "cannot convert '" + o.toString() + "' to Integer"); + } else { + throw new MissingInjectedFieldException(fieldName, getTaskName()); + } } } } @@ -289,8 +300,12 @@ public class BaseTask implements JavaDelegate { try { return Long.parseLong(o.toString()); } catch (NumberFormatException e) { - throw new BadInjectedFieldException(fieldName, getTaskName(), - "cannot convert '" + o.toString() + "' to Long"); + if (o != null) { + throw new BadInjectedFieldException(fieldName, getTaskName(), + "cannot convert '" + o.toString() + "' to Long"); + } else { + throw new MissingInjectedFieldException(fieldName, getTaskName()); + } } } } diff --git a/bpmn/mso-infrastructure-bpmn/src/test/java/org/onap/so/bpmn/common/WorkflowTest.java b/bpmn/mso-infrastructure-bpmn/src/test/java/org/onap/so/bpmn/common/WorkflowTest.java index 389f931901..e71404a2ff 100644 --- a/bpmn/mso-infrastructure-bpmn/src/test/java/org/onap/so/bpmn/common/WorkflowTest.java +++ b/bpmn/mso-infrastructure-bpmn/src/test/java/org/onap/so/bpmn/common/WorkflowTest.java @@ -350,10 +350,12 @@ public abstract class WorkflowTest { */ try { - msoRequestId = (String) injectedVariables.get("requestId"); - variables.put("mso-request-id", msoRequestId); - msoServiceInstanceId = (String) injectedVariables.get("serviceInstanceId"); - variables.put("mso-service-instance-id", msoServiceInstanceId); + if (injectedVariables != null) { + msoRequestId = (String) injectedVariables.get("requestId"); + variables.put("mso-request-id", msoRequestId); + msoServiceInstanceId = (String) injectedVariables.get("serviceInstanceId"); + variables.put("mso-service-instance-id", msoServiceInstanceId); + } } catch (Exception e) { } if (msoRequestId == null || msoRequestId.trim().equals("")) { diff --git a/common/src/main/java/org/onap/so/client/aai/AAIValidatorImpl.java b/common/src/main/java/org/onap/so/client/aai/AAIValidatorImpl.java index 95ed01ee94..96844ff1cb 100644 --- a/common/src/main/java/org/onap/so/client/aai/AAIValidatorImpl.java +++ b/common/src/main/java/org/onap/so/client/aai/AAIValidatorImpl.java @@ -47,10 +47,12 @@ public class AAIValidatorImpl implements AAIValidator { List<Pserver> pservers; boolean isLocked = false; pservers = client.getPhysicalServerByVnfId(vnfId); - for (Pserver pserver : pservers) { - if (pserver.isInMaint()) { - isLocked = true; - return isLocked; + if (pservers != null) { + for (Pserver pserver : pservers) { + if (pserver.isInMaint()) { + isLocked = true; + return isLocked; + } } } return isLocked; diff --git a/common/src/test/java/org/onap/so/client/aai/AAIValidatorTest.java b/common/src/test/java/org/onap/so/client/aai/AAIValidatorTest.java index 5fa2ff0295..b91d0e705a 100644 --- a/common/src/test/java/org/onap/so/client/aai/AAIValidatorTest.java +++ b/common/src/test/java/org/onap/so/client/aai/AAIValidatorTest.java @@ -91,6 +91,13 @@ public class AAIValidatorTest { } @Test + public void test_IsPhysicalServerLocked_NoServers_False() throws IOException { + when(client.getPhysicalServerByVnfId(vnfName)).thenReturn(null); + boolean locked = validator.isPhysicalServerLocked(vnfName); + assertEquals(false, locked); + } + + @Test public void test_IsVNFLocked_False() { when(client.getVnfByName(vnfName)).thenReturn(createGenericVnfs(false)); boolean locked = validator.isVNFLocked(vnfName); diff --git a/mso-api-handlers/mso-requests-db/src/main/java/org/onap/so/db/request/beans/InfraRequests.java b/mso-api-handlers/mso-requests-db/src/main/java/org/onap/so/db/request/beans/InfraRequests.java index 464cacb6b0..05845dd058 100644 --- a/mso-api-handlers/mso-requests-db/src/main/java/org/onap/so/db/request/beans/InfraRequests.java +++ b/mso-api-handlers/mso-requests-db/src/main/java/org/onap/so/db/request/beans/InfraRequests.java @@ -161,7 +161,7 @@ public abstract class InfraRequests implements java.io.Serializable { private String rollbackExtSystemErrorSource; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) - @JoinColumn(name = "SO_REQUEST_ID", referencedColumnName = "REQUEST_ID") + @JoinColumn(name = "SO_REQUEST_ID", referencedColumnName = "REQUEST_ID", updatable = false) private List<CloudApiRequests> cloudApiRequests = new ArrayList<>(); @ResourceId diff --git a/vnfm-simulator/vnfm-service/pom.xml b/vnfm-simulator/vnfm-service/pom.xml index 7beccb6561..1e3244bae4 100644 --- a/vnfm-simulator/vnfm-service/pom.xml +++ b/vnfm-simulator/vnfm-service/pom.xml @@ -44,6 +44,11 @@ <scope>runtime</scope> </dependency> <dependency> + <groupId>org.springframework.security.oauth</groupId> + <artifactId>spring-security-oauth2</artifactId> + <version>2.3.6.RELEASE</version> + </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/AuthorizationServerConfig.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/AuthorizationServerConfig.java new file mode 100644 index 0000000000..5d2c310635 --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/AuthorizationServerConfig.java @@ -0,0 +1,28 @@ +package org.onap.svnfm.simulator.oauth; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; + +@Configuration +@EnableAuthorizationServer +@Profile("oauth-authentication") +/** + * Configures the authorization server for oauth token based authentication when the spring profile + * "oauth-authentication" is active + */ +public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { + + private static final int ONE_DAY = 60 * 60 * 24; + + @Override + public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { + clients.inMemory().withClient("vnfmadapter") + .secret("$2a$10$dHzTlqSBcm8hdO52LBvnX./zNTvUzzJy.lZrc4bCBL5gkln0wX6T6") + .authorizedGrantTypes("client_credentials").scopes("write").accessTokenValiditySeconds(ONE_DAY) + .refreshTokenValiditySeconds(ONE_DAY); + } + +} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/JsonSerializerConfiguration.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/JsonSerializerConfiguration.java new file mode 100644 index 0000000000..d6eda28eb6 --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/JsonSerializerConfiguration.java @@ -0,0 +1,49 @@ +/*- + * ============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.svnfm.simulator.oauth; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.util.ArrayList; +import java.util.Collection; +import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.security.oauth2.common.OAuth2AccessToken; + +/** + * Configures message converter + */ +@Configuration +public class JsonSerializerConfiguration { + + @Bean + public HttpMessageConverters customConverters() { + final Collection<HttpMessageConverter<?>> messageConverters = new ArrayList<>(); + + final Gson gson = new GsonBuilder() + .registerTypeHierarchyAdapter(OAuth2AccessToken.class, new OAuth2AccessTokenAdapter()).create(); + final GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter(gson); + messageConverters.add(gsonHttpMessageConverter); + return new HttpMessageConverters(true, messageConverters); + } +} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/OAuth2AccessTokenAdapter.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/OAuth2AccessTokenAdapter.java new file mode 100644 index 0000000000..7bccffa2e0 --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/OAuth2AccessTokenAdapter.java @@ -0,0 +1,31 @@ +package org.onap.svnfm.simulator.oauth; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import java.lang.reflect.Type; +import org.springframework.security.oauth2.common.OAuth2AccessToken; + +public class OAuth2AccessTokenAdapter implements JsonSerializer<OAuth2AccessToken> { + + @Override + public JsonElement serialize(final OAuth2AccessToken src, final Type typeOfSrc, + final JsonSerializationContext context) { + final JsonObject obj = new JsonObject(); + obj.addProperty(OAuth2AccessToken.ACCESS_TOKEN, src.getValue()); + obj.addProperty(OAuth2AccessToken.TOKEN_TYPE, src.getTokenType()); + if (src.getRefreshToken() != null) { + obj.addProperty(OAuth2AccessToken.REFRESH_TOKEN, src.getRefreshToken().getValue()); + } + obj.addProperty(OAuth2AccessToken.EXPIRES_IN, src.getExpiresIn()); + final JsonArray scopeObj = new JsonArray(); + for (final String scope : src.getScope()) { + scopeObj.add(scope); + } + obj.add(OAuth2AccessToken.SCOPE, scopeObj); + + return obj; + } +} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/OAuth2ResourceServer.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/OAuth2ResourceServer.java new file mode 100644 index 0000000000..18fb1a9461 --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/oauth/OAuth2ResourceServer.java @@ -0,0 +1,36 @@ +/*- + * ============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.svnfm.simulator.oauth; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; +import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; + +@Configuration +@EnableResourceServer +@Profile("oauth-authentication") +/** + * Enforces oauth token based authentication when the spring profile "oauth-authentication" is active + */ +public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter { + +} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java index 83f079c376..eed62780c0 100644 --- a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java @@ -1,11 +1,17 @@ package org.onap.svnfm.simulator.services; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import javax.net.ssl.HttpsURLConnection; import javax.ws.rs.core.MediaType; import org.apache.commons.codec.binary.Base64; import org.modelmapper.ModelMapper; @@ -30,6 +36,7 @@ import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperatio import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201InstantiatedVnfInfoVnfcResourceInfo; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsBasic; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsOauth2ClientCredentials; import org.onap.svnfm.simulator.config.ApplicationConfig; import org.onap.svnfm.simulator.model.VnfOperation; import org.onap.svnfm.simulator.model.Vnfds; @@ -187,7 +194,8 @@ public abstract class OperationProgressor implements Runnable { final String auth = subscriptionAuthentication.getUserName() + ":" + subscriptionAuthentication.getPassword(); final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1)); - final String authHeader = "Basic " + new String(encodedAuth); + String authHeader = "Basic " + new String(encodedAuth); + notificationClient.lcnVnfLcmOperationOccurrenceNotificationPostWithHttpInfo(notification, MediaType.APPLICATION_JSON, authHeader); } catch (final ApiException exception) { @@ -235,8 +243,15 @@ public abstract class OperationProgressor implements Runnable { private InlineResponse201 sendGrantRequest(final GrantRequest grantRequest) { LOGGER.info("Sending grant request: {}", grantRequest); try { + + final SubscriptionsAuthenticationParamsOauth2ClientCredentials subscriptionAuthentication = + subscriptionService.getSubscriptions().iterator().next().getAuthentication() + .getParamsOauth2ClientCredentials(); + final String authHeader = + "Bearer " + getToken(notificationClient.getApiClient(), subscriptionAuthentication); + final ApiResponse<InlineResponse201> response = grantClient.grantsPostWithHttpInfo(grantRequest, - MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, "Basic dm5mbTpwYXNzd29yZDEk"); + MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, authHeader); LOGGER.info("Grant Response: {}", response); return response.getData(); } catch (final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiException exception) { @@ -257,4 +272,46 @@ public abstract class OperationProgressor implements Runnable { return applicationConfig.getBaseUrl() + "/vnflcm/v1"; } + private String getToken(final ApiClient apiClient, + final SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthClientCredentials) { + final String basePath = apiClient.getBasePath().substring(0, apiClient.getBasePath().indexOf("/so/")); + final String tokenUrl = basePath + "/oauth/token?grant_type=client_credentials"; + + try { + URL url = new URL(tokenUrl); + HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + final String authorizationHeader = getAuthorizationHeader(oauthClientCredentials); + connection.addRequestProperty("Authorization", authorizationHeader); + + connection.connect(); + + return getResponse(connection).get("access_token").getAsString(); + + } catch (IOException exception) { + LOGGER.error("Error getting token", exception); + return null; + } + } + + private String getAuthorizationHeader( + final SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthClientCredentials) { + final String auth = oauthClientCredentials.getClientId() + ":" + oauthClientCredentials.getClientPassword(); + final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8)); + return "Basic " + new String(encodedAuth); + } + + private JsonObject getResponse(HttpsURLConnection connection) throws IOException { + BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String line, data = ""; + while ((line = in.readLine()) != null) { + data += line; + } + in.close(); + connection.getInputStream().close(); + + JsonObject jsonObject = new JsonParser().parse(data).getAsJsonObject(); + return jsonObject; + } + } |