Update configuration capabilities 65/2665/4
authorSerban Jora <sj2381@att.com>
Fri, 24 Aug 2018 20:28:03 +0000 (16:28 -0400)
committerSerban Jora <sj2381@att.com>
Tue, 4 Sep 2018 22:07:11 +0000 (18:07 -0400)
Change-Id: I52f384316c0ee8d038c5a10cfe302740fca0e4d1
Issue-ID: ACUMOS-1692
Signed-off-by: Serban Jora <sj2381@att.com>
22 files changed:
docs/release-notes.rst
gateway/pom.xml
gateway/src/main/java/org/acumos/federation/gateway/common/Clients.java
gateway/src/main/java/org/acumos/federation/gateway/config/AdapterConfiguration.java
gateway/src/main/java/org/acumos/federation/gateway/config/CDMSClientConfiguration.java [new file with mode: 0644]
gateway/src/main/java/org/acumos/federation/gateway/config/DockerConfiguration.java
gateway/src/main/java/org/acumos/federation/gateway/config/GatewayConfiguration.java
gateway/src/main/java/org/acumos/federation/gateway/config/InterfaceConfiguration.java
gateway/src/main/java/org/acumos/federation/gateway/config/NexusConfiguration.java
gateway/src/main/java/org/acumos/federation/gateway/security/Tools.java [new file with mode: 0644]
gateway/src/main/java/org/acumos/federation/gateway/service/CatalogServiceConfiguration.java [new file with mode: 0644]
gateway/src/main/java/org/acumos/federation/gateway/service/impl/AbstractServiceImpl.java
gateway/src/main/java/org/acumos/federation/gateway/service/impl/CatalogServiceImpl.java
gateway/src/main/java/org/acumos/federation/gateway/service/impl/ContentServiceImpl.java
gateway/src/main/java/org/acumos/federation/gateway/service/impl/PeerServiceImpl.java
gateway/src/test/java/org/acumos/federation/gateway/test/CatalogServiceTest.java
gateway/src/test/java/org/acumos/federation/gateway/test/PeerGatewayTest.java
gateway/src/test/java/org/acumos/federation/gateway/test/PeerServiceTest.java
gateway/src/test/resources/mockCDSPeerSearchResponse.json
gateway/src/test/resources/mockCDSPeerSearchSelfResponse.json
gateway/src/test/resources/mockCDSPeerUpdateResponse.json
gateway/src/test/resources/mockCDSSolutionRevisionsResponse.json

index 25b598e..f8278f1 100644 (file)
@@ -22,6 +22,11 @@ Federated Gateway Release Notes
 
 The Federated Gateway server is available as a Docker image in a Docker registry.
 
+Version 1.17.1, 2018-09-04
+-------------------------
+
+* Spread the use of configuration beans (ACUMS-1692)
+
 Version 1.17.0, 2018-08-14
 -------------------------
 
index c857201..410852e 100644 (file)
@@ -24,14 +24,14 @@ limitations under the License.
        <modelVersion>4.0.0</modelVersion>
        <groupId>org.acumos.federation</groupId>
        <artifactId>gateway</artifactId>
-       <version>1.17.0-SNAPSHOT</version>
+       <version>1.17.1-SNAPSHOT</version>
        <name>Federation Gateway</name>
        <description>Federated Acumos Interface for inter-acumos and ONAP communication</description>
 
        <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
-               <version>1.5.10.RELEASE</version>
+               <version>1.5.14.RELEASE</version>
                <!-- silence warning about parent relative path -->
                <relativePath />
        </parent>
index 603670b..ef825e0 100644 (file)
@@ -22,7 +22,6 @@ package org.acumos.federation.gateway.common;
 
 import java.lang.invoke.MethodHandles;
 
-import org.acumos.cds.client.CommonDataServiceRestClientImpl;
 import org.acumos.cds.client.ICommonDataServiceRestClient;
 import org.acumos.federation.gateway.cds.Mapper;
 import org.acumos.federation.gateway.config.NexusConfiguration;
@@ -30,19 +29,15 @@ import org.acumos.federation.gateway.config.DockerConfiguration;
 import org.acumos.federation.gateway.config.EELFLoggerDelegate;
 import org.acumos.federation.gateway.config.FederationInterfaceConfiguration;
 import org.acumos.federation.gateway.config.LocalInterfaceConfiguration;
-import org.acumos.nexus.client.NexusArtifactClient;
-import org.acumos.nexus.client.RepositoryLocation;
+import org.acumos.federation.gateway.config.CDMSClientConfiguration;
+
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.web.client.RestTemplateBuilder;
-import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Scope;
-import org.springframework.core.env.Environment;
-import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
-import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
 import org.springframework.stereotype.Component;
 
+import org.acumos.nexus.client.NexusArtifactClient;
+
 import com.github.dockerjava.api.DockerClient;
-import com.github.dockerjava.core.DockerClientBuilder;
 
 /**
  * Unique entry point for building clients: peer access clients, cds clients
@@ -51,10 +46,6 @@ import com.github.dockerjava.core.DockerClientBuilder;
 @Scope("singleton")
 public class Clients {
 
-       @Autowired
-       private Environment env;
-       @Autowired
-       private ApplicationContext appCtx = null;
        @Autowired
        private LocalInterfaceConfiguration localConfig = null;
        @Autowired
@@ -63,6 +54,8 @@ public class Clients {
        private DockerConfiguration dockerConfig = null;
        @Autowired
        private NexusConfiguration nexusConfig = null;
+       @Autowired
+       private CDMSClientConfiguration cdmsConfig = null;
 
        private static final EELFLoggerDelegate log = EELFLoggerDelegate.getLogger(MethodHandles.lookup().lookupClass());
 
@@ -73,22 +66,7 @@ public class Clients {
         * @return The standard CDS client
         */
        public ICommonDataServiceRestClient getCDSClient() {
-
-               MappingJackson2HttpMessageConverter cdsMessageConverter = new MappingJackson2HttpMessageConverter();
-    cdsMessageConverter.setObjectMapper(Mapper.build()); //try to avoid building one every time
-
-               RestTemplateBuilder builder =
-                       new RestTemplateBuilder()
-                               .requestFactory(new HttpComponentsClientHttpRequestFactory( 
-                                                                                                       localConfig.buildClient()))
-                               //.rootUri(env.getProperty("cdms.client.url"))
-                               .basicAuthorization(env.getProperty("cdms.client.username"),
-                                                                                                               env.getProperty("cdms.client.password"))
-                               .messageConverters(cdsMessageConverter)
-                               ;
-
-                       return new CommonDataServiceRestClientImpl(
-                               env.getProperty("cdms.client.url"), builder.build());
+               return cdmsConfig.getCDSClient();
        }
 
        /**
@@ -100,14 +78,12 @@ public class Clients {
 
        /** */
        public NexusArtifactClient getNexusClient() {
-               return new NexusArtifactClient(nexusConfig.getRepositoryLocation());
+               return nexusConfig.getNexusClient();
        }
 
        /** */
        public DockerClient     getDockerClient() {
-    return DockerClientBuilder.getInstance(dockerConfig.buildConfig())
-                       .withDockerCmdExecFactory(DockerClientBuilder.getDefaultDockerCmdExecFactory())
-                       .build();
+    return dockerConfig.getDockerClient();
        }
 
 }
index ffbe836..d80026b 100644 (file)
@@ -48,6 +48,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
                                 AuthenticationConfiguration.class})
 @EnableConfigurationProperties({FederationInterfaceConfiguration.class,
                                                                                                                                LocalInterfaceConfiguration.class,
+                                                                                                                               CDMSClientConfiguration.class,
                                                                                                                                DockerConfiguration.class,
                                                                                                                                NexusConfiguration.class})
 @Conditional({AdapterCondition.class})
diff --git a/gateway/src/main/java/org/acumos/federation/gateway/config/CDMSClientConfiguration.java b/gateway/src/main/java/org/acumos/federation/gateway/config/CDMSClientConfiguration.java
new file mode 100644 (file)
index 0000000..83a68eb
--- /dev/null
@@ -0,0 +1,121 @@
+/*-
+ * ===============LICENSE_START=======================================================
+ * Acumos
+ * ===================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * ===================================================================================
+ * This Acumos software file is distributed by AT&T and Tech Mahindra
+ * 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
+ *  
+ * This file 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.
+ * ===============LICENSE_END=========================================================
+ */
+
+package org.acumos.federation.gateway.config;
+
+import java.lang.invoke.MethodHandles;
+
+import org.acumos.cds.client.ICommonDataServiceRestClient;
+import org.acumos.cds.client.CommonDataServiceRestClientImpl;
+
+import org.acumos.federation.gateway.cds.Mapper;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+
+/**
+ * Gathers all CDS connectivity related parameters. Allows one to construct a cds client based on the
+ * given parameters routing its requests through the local interface of the gateway.
+ */
+@Component
+@ConfigurationProperties(prefix = "cdms.client")
+public class CDMSClientConfiguration {
+
+       public static final int DEFAULT_PAGE_SIZE = 100;
+
+       private static final EELFLoggerDelegate log = EELFLoggerDelegate.getLogger(MethodHandles.lookup().lookupClass());
+       private String          url;
+       private String          username;
+       private String          password;
+       private int                             pageSize;
+
+       @Autowired
+       private LocalInterfaceConfiguration localIfConfig = null;
+
+       public CDMSClientConfiguration() {
+               reset();
+       }
+
+       private void reset() {
+               //defaults
+               this.url = null;
+               this.username = null;
+               this.password = null;
+               this.pageSize = DEFAULT_PAGE_SIZE;
+       }
+
+       public String getUrl() {
+               return this.url ;
+       }
+
+       public void setUrl(String theUrl) {
+               this.url = theUrl;
+  }
+
+       public String getUsername() {
+               return this.username;
+       }
+
+       public void setUsername(String theUsername) {
+               this.username = theUsername;
+       }
+
+       public String getPassword() {
+               return this.password;
+       }
+
+       public void setPassword(String thePassword) {
+               this.password = thePassword;
+       }
+
+       public int getPageSize() {
+               return this.pageSize;
+       }
+
+       public void setPageSize(int thePageSize) {
+               this.pageSize = thePageSize;
+  }
+
+       /**
+        * CDS traffic is always routed through the local interface;
+        */
+       public ICommonDataServiceRestClient getCDSClient() {
+
+               MappingJackson2HttpMessageConverter cdsMessageConverter = new MappingJackson2HttpMessageConverter();
+    cdsMessageConverter.setObjectMapper(Mapper.build()); //try to avoid building one every time
+
+               RestTemplateBuilder builder =
+                       new RestTemplateBuilder()
+                               .requestFactory(new HttpComponentsClientHttpRequestFactory( 
+                                                                                                       this.localIfConfig.buildClient()))
+                               //.rootUri(env.getProperty("cdms.client.url"))
+                               .basicAuthorization(this.username, this.password)
+                               .messageConverters(cdsMessageConverter)
+                               ;
+
+               return new CommonDataServiceRestClientImpl(this.url, builder.build());
+       }
+
+}
index 8ba7f0d..78b1f1a 100644 (file)
@@ -27,6 +27,8 @@ import org.springframework.stereotype.Component;
 
 import com.github.dockerjava.core.DefaultDockerClientConfig;
 import com.github.dockerjava.core.DockerClientConfig;
+import com.github.dockerjava.core.DockerClientBuilder;
+import com.github.dockerjava.api.DockerClient;
 
 /**
  * 
@@ -99,4 +101,10 @@ public class DockerConfiguration {
                return this.builder.build();
        }
 
+       /** */
+       public DockerClient     getDockerClient() {
+    return DockerClientBuilder.getInstance(buildConfig())
+                       .withDockerCmdExecFactory(DockerClientBuilder.getDefaultDockerCmdExecFactory())
+                       .build();
+       }
 }
index ec70073..f046e3d 100644 (file)
@@ -25,6 +25,7 @@ import org.acumos.federation.gateway.common.Clients;
 import org.acumos.federation.gateway.security.AuthenticationConfiguration;
 import org.acumos.federation.gateway.service.ContentService;
 import org.acumos.federation.gateway.service.CatalogService;
+import org.acumos.federation.gateway.service.CatalogServiceConfiguration;
 import org.acumos.federation.gateway.service.PeerService;
 import org.acumos.federation.gateway.service.PeerSubscriptionService;
 import org.acumos.federation.gateway.service.impl.ContentServiceImpl;
@@ -52,8 +53,10 @@ import org.springframework.scheduling.annotation.EnableScheduling;
                                 AuthenticationConfiguration.class})
 @EnableConfigurationProperties({FederationInterfaceConfiguration.class,
                                                                                                                                LocalInterfaceConfiguration.class,
+                                                                                                                               CDMSClientConfiguration.class,
                                                                                                                                DockerConfiguration.class,
-                                                                                                                               NexusConfiguration.class})
+                                                                                                                               NexusConfiguration.class,
+                                                                                                                               CatalogServiceConfiguration.class})
 @Conditional({GatewayCondition.class})
 @EnableScheduling
 public class GatewayConfiguration {
index 450f722..84f4336 100644 (file)
@@ -27,6 +27,10 @@ import java.io.InputStream;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
 
 import javax.annotation.PostConstruct;
 import javax.net.ssl.SSLContext;
@@ -68,9 +72,7 @@ public class InterfaceConfiguration {
        @Autowired
        private ResourceLoader resourceLoader;
 
-       protected final EELFLoggerDelegate log = EELFLoggerDelegate.getLogger(getClass().getName());
-
-       //private int poolSize = 10;
+       private final EELFLoggerDelegate log = EELFLoggerDelegate.getLogger(getClass().getName());
 
        private String                  address;
        private InetAddress     inetAddress;
@@ -147,6 +149,94 @@ public class InterfaceConfiguration {
                return this.address != null;
        }
 
+       /** 
+        * Provide the subject name specified in the SSL config
+        */
+       public String getSubjectName() throws KeyStoreException {
+               if (!hasSSL())
+                       return null;
+       
+               KeyStore keyStore = loadKeyStore();
+               X509Certificate certEntry = null;
+               
+               String alias = null;
+               if (this.ssl.keyAlias == null) {
+                       //we expect only one entry
+                       Enumeration<String> aliases = keyStore.aliases();
+                       try {
+                               alias = aliases.nextElement();
+                       }
+                       catch(NoSuchElementException nsex) {
+                               throw new KeyStoreException("Key store contains no entries");
+                       }
+
+                       assert(!aliases.hasMoreElements());
+               }
+               else {
+                       alias = this.ssl.keyAlias;
+               }
+
+               certEntry =  (X509Certificate)keyStore.getCertificate(alias);
+               if (certEntry == null)
+                       return null;
+
+               return certEntry.getSubjectX500Principal().getName();
+       }
+
+       /**
+        * Loads the specified key store
+        * @return the key store
+        */
+       public KeyStore loadKeyStore() {
+               return loadStore(this.ssl.keyStore, this.ssl.keyStoreType, this.ssl.keyStorePasswd);
+       }
+
+       /**
+        * Loads the specified trust store
+        * @return the key store
+        */
+       public KeyStore loadTrustStore() {
+               return loadStore(this.ssl.trustStore, this.ssl.trustStoreType, this.ssl.trustStorePasswd);
+       }
+
+       /** */
+       private KeyStore loadStore(String theLocation, String theType, String thePasswd) {
+               KeyStore store = null;
+               InputStream storeSource = null;
+               try {
+                       storeSource = this.resourceLoader.getResource(theLocation).getURL().openStream();
+               }
+               catch (FileNotFoundException rnfx) {
+                       try {
+                               storeSource = new FileInputStream(theLocation);
+                       }
+                       catch (FileNotFoundException fnfx) {
+                               throw new IllegalStateException("Failed to find key store " + theLocation);
+                       }
+               }
+               catch (IOException iox) {
+                       throw new IllegalStateException("Error loading key material: " + iox, iox);
+               }
+
+               try {
+                       store = KeyStore.getInstance(theType);
+                       store.load(storeSource, thePasswd.toCharArray());
+                       log.info(EELFLoggerDelegate.debugLogger, "Loaded key store: " + theLocation);
+               }
+               catch (Exception x) {
+                       throw new IllegalStateException("Error loading key material: " + x, x);
+               }
+               finally {
+                       try {
+                               storeSource.close();
+                       }
+                       catch (IOException iox) {
+                               log.debug(EELFLoggerDelegate.debugLogger, "Error closing key store source", iox);
+                       }
+               }
+               return store;
+       }
+       
        /**
         */
        public static class Client {
@@ -372,77 +462,8 @@ public class InterfaceConfiguration {
                        log.info(EELFLoggerDelegate.debugLogger, "No ssl config was provided");
                }
                else {
-                       KeyStore keyStore = null;
-                       if (this.ssl.hasKeyStoreInfo()) {
-                               InputStream keyStoreSource = null;
-                               try {
-                                       keyStoreSource = this.resourceLoader.getResource(this.ssl.keyStore).getURL().openStream();
-                               }
-                               catch (FileNotFoundException rnfx) {
-                                       try {
-                                               keyStoreSource = new FileInputStream(this.ssl.keyStore);
-                                       }
-                                       catch (FileNotFoundException fnfx) {
-                                               throw new IllegalStateException("Failed to find key store " + this.ssl.keyStore);
-                                       }
-                               }
-                               catch (IOException iox) {
-                                       throw new IllegalStateException("Error loading key material: " + iox, iox);
-                               }
-
-                               try {
-                                       keyStore = KeyStore.getInstance(this.ssl.keyStoreType);
-                                       keyStore.load(keyStoreSource,   this.ssl.keyStorePasswd.toCharArray());
-                                       log.info(EELFLoggerDelegate.debugLogger, "Loaded key store: " + this.ssl.keyStore);
-                               }
-                               catch (Exception x) {
-                                       throw new IllegalStateException("Error loading key material: " + x, x);
-                               }
-                               finally {
-                                       try {
-                                               keyStoreSource.close();
-                                       }
-                                       catch (IOException iox) {
-                                               log.debug(EELFLoggerDelegate.debugLogger, "Error closing key store source", iox);
-                                       }
-                               }
-                       }
-
-                       KeyStore trustStore = null;
-                       if (this.ssl.hasTrustStoreInfo()) {
-                               InputStream trustStoreSource = null;
-                               try {
-                                       trustStoreSource = this.resourceLoader.getResource(this.ssl.trustStore).getURL().openStream();
-                               }
-                               catch (FileNotFoundException rnfx) {
-                                       try {
-                                               trustStoreSource = new FileInputStream(this.ssl.trustStore);
-                                       }
-                                       catch (FileNotFoundException fnfx) {
-                                               throw new IllegalStateException("Failed to find trust store " + this.ssl.keyStore);
-                                       }
-                               }
-                               catch (IOException iox) {
-                                       throw new IllegalStateException("Error loading trust material: " + iox, iox);
-                               }
-
-                               try {
-                                       trustStore = KeyStore.getInstance(this.ssl.trustStoreType);
-                                       trustStore.load(trustStoreSource,       this.ssl.trustStorePasswd.toCharArray());
-                                       log.info(EELFLoggerDelegate.debugLogger, "Loaded trust store: " + this.ssl.trustStore);
-                               }
-                               catch (Exception x) {
-                                       throw new IllegalStateException("Error loading trust material: " + x, x);
-                               }
-                               finally {
-                                       try {
-                                               trustStoreSource.close();
-                                       }
-                                       catch (IOException iox) {
-                                               log.debug(EELFLoggerDelegate.debugLogger, "Error closing trust store source", iox);
-                                       }
-                               }
-                       }
+                       KeyStore keyStore = loadKeyStore(),
+                                                        trustStore = loadTrustStore();
 
                        SSLContextBuilder contextBuilder = SSLContexts.custom();
                        try {
@@ -460,7 +481,8 @@ public class InterfaceConfiguration {
                                }
 
                                sslContext = contextBuilder.build();
-                       } catch (Exception x) {
+                       }
+                       catch (Exception x) {
                                throw new IllegalStateException("Error building ssl context", x);
                        }
                }
index 2b249f0..ee26147 100644 (file)
@@ -25,6 +25,7 @@ import java.lang.invoke.MethodHandles;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.stereotype.Component;
 
+import org.acumos.nexus.client.NexusArtifactClient;
 import org.acumos.nexus.client.RepositoryLocation;
 
 /**
@@ -91,4 +92,8 @@ public class NexusConfiguration {
                return this.nameSeparator;
        }
 
+       /** */
+       public NexusArtifactClient getNexusClient() {
+               return new NexusArtifactClient(getRepositoryLocation());
+       }
 }
diff --git a/gateway/src/main/java/org/acumos/federation/gateway/security/Tools.java b/gateway/src/main/java/org/acumos/federation/gateway/security/Tools.java
new file mode 100644 (file)
index 0000000..9bcb26d
--- /dev/null
@@ -0,0 +1,72 @@
+/*-
+ * ===============LICENSE_START=======================================================
+ * Acumos
+ * ===================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * ===================================================================================
+ * This Acumos software file is distributed by AT&T and Tech Mahindra
+ * 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
+ *  
+ * This file 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.
+ * ===============LICENSE_END=========================================================
+ */
+
+package org.acumos.federation.gateway.security;
+
+import java.lang.invoke.MethodHandles;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+
+import org.acumos.federation.gateway.config.EELFLoggerDelegate;
+
+
+/**
+ * Set of security related utilities
+ */
+public class Tools {
+
+       private static final EELFLoggerDelegate log = EELFLoggerDelegate.getLogger(MethodHandles.lookup().lookupClass());
+
+       private Tools() {
+       }
+
+       /**
+        * Extract components of an X500 name, as employed in SSL certificates.
+        * @param theName the X500 name in String represention. An IllegalArgumentException is thrown if the argument cannot be parsed accordingly.
+        * @param theParts the X500 name components the client wants to extract
+        * @return a map of requested parts and their values. Only those parts for which an entry was found will be available.
+        */
+       public static  Map<String, Object> getNameParts(String theName, String... theParts) {
+               log.info(EELFLoggerDelegate.debugLogger, " X500 name: " + theName);
+               LdapName x500name = null;
+               try {
+                       x500name = new LdapName(theName);
+               }
+               catch (InvalidNameException inx) {
+                       log.warn(EELFLoggerDelegate.errorLogger, "Failed to parse name information '{}'", theName);
+                       throw new IllegalArgumentException(inx);
+               }
+
+               Map<String, Object> parts = new HashMap<String, Object>();
+               for (Rdn rdn :  x500name.getRdns()) {
+                       for (String part: theParts) {
+                               if (part.equalsIgnoreCase(rdn.getType())) {
+                                       parts.put(part, rdn.getValue());
+                               }
+                       }
+               }
+               return parts;
+       }
+}
diff --git a/gateway/src/main/java/org/acumos/federation/gateway/service/CatalogServiceConfiguration.java b/gateway/src/main/java/org/acumos/federation/gateway/service/CatalogServiceConfiguration.java
new file mode 100644 (file)
index 0000000..6c4a6dc
--- /dev/null
@@ -0,0 +1,99 @@
+/*-
+ * ===============LICENSE_START=======================================================
+ * Acumos
+ * ===================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * ===================================================================================
+ * This Acumos software file is distributed by AT&T and Tech Mahindra
+ * 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
+ *  
+ * This file 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.
+ * ===============LICENSE_END=========================================================
+ */
+
+package org.acumos.federation.gateway.service;
+
+import java.lang.invoke.MethodHandles;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import org.springframework.boot.json.JsonParser;
+import org.springframework.boot.json.JsonParserFactory;
+
+import org.acumos.cds.AccessTypeCode;
+import org.acumos.cds.ValidationStatusCode;
+
+import org.acumos.federation.gateway.config.EELFLoggerDelegate;
+import org.acumos.federation.gateway.cds.Solution;
+import org.acumos.federation.gateway.cds.SolutionRevision;
+
+/**
+ * Allows for the configuration of the base selector which determine the solutions exposed through federation.
+ * An implementation of the CatalogService should only provide those solutions that pass the solutions selector and
+ * only thos revisions of these solutions that pass the solution revisions selector.
+ */
+@Component
+@ConfigurationProperties(prefix = "catalog")
+public class CatalogServiceConfiguration {
+
+       private static final EELFLoggerDelegate log = EELFLoggerDelegate.getLogger(MethodHandles.lookup().lookupClass());
+
+       private Map<String, Object>     solutionsSelector;
+       private Map<String, Object>     solutionRevisionsSelector;
+
+
+       public CatalogServiceConfiguration() {
+               reset();
+       }
+
+       /**
+        * Resets the selectors to their default value.
+        * The validationStatusCode == Passed(PS) criteria has been removed from both solutions and solutionRevisions selector because
+        * the corresponding field is no longer maintained in the backend. It ca always be re-introduced through configuration.
+        */
+       private void reset() {
+               this.solutionsSelector = new HashMap<String, Object>();
+               // Fetch only active solutions
+               this.solutionsSelector.put(Solution.Fields.active, true);
+               // Fetch only Public models
+               this.solutionsSelector.put(Solution.Fields.accessTypeCode, AccessTypeCode.PB.toString());
+
+               this.solutionRevisionsSelector = new HashMap<String, Object>();
+               // Fetch only for Public revisions
+               this.solutionRevisionsSelector.put(SolutionRevision.Fields.accessTypeCode, AccessTypeCode.PB.toString());
+               
+               this.solutionsSelector = Collections.unmodifiableMap(this.solutionsSelector);;
+               this.solutionRevisionsSelector = Collections.unmodifiableMap(this.solutionRevisionsSelector);;
+       }
+
+       public Map<String, Object> getSolutionsSelector() {
+               return this.solutionsSelector;
+       }
+
+       public void setSolutionsSelector(String theSelector) {
+               this.solutionsSelector = Collections.unmodifiableMap(
+                                                                                                                       JsonParserFactory.getJsonParser().parseMap(theSelector));
+  }
+
+       public Map<String, Object> getSolutionRevisionsSelector() {
+               return this.solutionRevisionsSelector;
+       }
+
+       public void setSolutionRevisionsSelector(String theSelector) {
+               this.solutionRevisionsSelector = Collections.unmodifiableMap(
+                                                                                                                                                       JsonParserFactory.getJsonParser().parseMap(theSelector));
+       }
+
+}
index 655c028..f3003d3 100644 (file)
@@ -21,7 +21,7 @@
 package org.acumos.federation.gateway.service.impl;
 
 import org.acumos.cds.client.ICommonDataServiceRestClient;
-import org.acumos.federation.gateway.common.Clients;
+import org.acumos.federation.gateway.config.CDMSClientConfiguration;
 import org.acumos.federation.gateway.security.Peer;
 import org.acumos.federation.gateway.service.ServiceContext;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -31,12 +31,13 @@ import org.springframework.context.ApplicationContext;
 public abstract class AbstractServiceImpl {
 
        @Autowired
-       protected Clients clients;
+       protected CDMSClientConfiguration                       cdsConfig;
+
        @Autowired
        protected ApplicationContext appCtx;
 
        public ICommonDataServiceRestClient getClient() {
-               return clients.getCDSClient();
+               return cdsConfig.getCDSClient();
        }
 
        public ICommonDataServiceRestClient getClient(ServiceContext theContext) {
index 295490f..419a2db 100644 (file)
@@ -49,12 +49,12 @@ import org.acumos.federation.gateway.cds.Solution;
 import org.acumos.federation.gateway.cds.SolutionRevision;
 import org.acumos.federation.gateway.config.EELFLoggerDelegate;
 import org.acumos.federation.gateway.service.CatalogService;
+import org.acumos.federation.gateway.service.CatalogServiceConfiguration;
 import org.acumos.federation.gateway.service.ServiceContext;
 import org.acumos.federation.gateway.service.ServiceException;
 import org.acumos.federation.gateway.util.Errors;
 import org.apache.commons.beanutils.PropertyUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.HttpStatusCodeException;
 
@@ -69,31 +69,13 @@ public class CatalogServiceImpl extends AbstractServiceImpl
        private static final EELFLoggerDelegate log = EELFLoggerDelegate.getLogger(MethodHandles.lookup().lookupClass());
 
        @Autowired
-       private Environment env;
-
-       private Map<String, Object> baseSolutionSelector,
-       /*private List<Predicate<MLPSolutionRevision>>*/        baseSolutionRevisionSelector;
+       private CatalogServiceConfiguration config;
 
        @PostConstruct
        public void initService() {
-               baseSolutionSelector = new HashMap<String, Object>();
-               // Fetch all active solutions
-               baseSolutionSelector.put(Solution.Fields.active, true);
-               // Fetch allowed only for Public models
-               baseSolutionSelector.put(Solution.Fields.accessTypeCode, AccessTypeCode.PB.toString());
-               // Validation status should be passed locally
-               baseSolutionSelector.put(Solution.Fields.validationStatusCode, ValidationStatusCode.PS.toString());
-
-               baseSolutionRevisionSelector = new HashMap<String, Object>();
-               // Fetch allowed only for Public revisions
-               baseSolutionRevisionSelector.put(SolutionRevision.Fields.accessTypeCode, AccessTypeCode.PB.toString());
-               // Validation status should be passed locally
-               baseSolutionRevisionSelector.put(SolutionRevision.Fields.validationStatusCode, ValidationStatusCode.PS.toString());
        }
 
        @Override
-       /*
-        */
        public List<MLPSolution> getSolutions(Map<String, ?> theSelector, ServiceContext theContext) throws ServiceException {
                log.debug(EELFLoggerDelegate.debugLogger, "getSolutions with selector {}", theSelector);
 
@@ -102,10 +84,10 @@ public class CatalogServiceImpl extends AbstractServiceImpl
                        selector.putAll(theSelector);
                //it is essential that this gets done at the end as to force all baseSelector criteria (otherwise a submitted accessTypeCode
                //could overwrite the basic one end expose non public solutions ..).
-               selector.putAll(this.baseSolutionSelector);
+               selector.putAll(this.config.getSolutionsSelector());
                log.debug(EELFLoggerDelegate.debugLogger, "getSolutions with full selector {}", selector);
 
-               RestPageRequest pageRequest = new RestPageRequest(0, 50);
+               RestPageRequest pageRequest = new RestPageRequest(0, this.cdsConfig.getPageSize());
                RestPageResponse<MLPSolution> pageResponse = null;
                List<MLPSolution> solutions = new ArrayList<MLPSolution>(),
                                                                                        pageSolutions = null;
@@ -118,9 +100,13 @@ public class CatalogServiceImpl extends AbstractServiceImpl
                                        //and artifacts for related information modified since.
                                        pageResponse =
                                                cdsClient.findSolutionsByDate(
-                                                       (Boolean)selector.get(Solution.Fields.active),
-                                                       new String[] {selector.get(Solution.Fields.accessTypeCode).toString()},
-                                                       new String[] {selector.get(Solution.Fields.validationStatusCode).toString()},
+                                                       (Boolean)selector.getOrDefault(Solution.Fields.active, Boolean.TRUE),
+                                                       selector.containsKey(Solution.Fields.accessTypeCode) ?
+                                                               new String[] {selector.get(Solution.Fields.accessTypeCode).toString()} :
+                                                               null,
+                                                       selector.containsKey(Solution.Fields.validationStatusCode) ?
+                                                               new String[] {selector.get(Solution.Fields.validationStatusCode).toString()} :
+                                                               null,
                                                        new Date((Long)selector.get(Solution.Fields.modified)),
                                                        pageRequest);
                        
@@ -137,13 +123,17 @@ public class CatalogServiceImpl extends AbstractServiceImpl
                                                                                                                                                                        selector.containsKey(Solution.Fields.description) ?
                                                                                                                                                                                new String[] {selector.get(Solution.Fields.description).toString()} :
                                                                                                                                                                                null,
-                                                                                                                                                                       (Boolean)selector.get(Solution.Fields.active),
+                                                                                                                                                                       (Boolean)selector.getOrDefault(Solution.Fields.active, Boolean.TRUE),
                                                                                                                                                                        null, //user ids
-                                                                                                                                                                       new String[] {selector.get(Solution.Fields.accessTypeCode).toString()},
+                                                                                                                                                                       selector.containsKey(Solution.Fields.accessTypeCode) ?
+                                                                                                                                                                               new String[] {selector.get(Solution.Fields.accessTypeCode).toString()} :
+                                                                                                                                                                               null,
                                                                                                                                                                        selector.containsKey(Solution.Fields.modelTypeCode) ?
                                                                                                                                                                                new String[] {selector.get(Solution.Fields.modelTypeCode).toString()} :
                                                                                                                                                                                null,
-                                                                                                                                                                       new String[] {selector.get(Solution.Fields.validationStatusCode).toString()},
+                                                                                                                                                                       selector.containsKey(Solution.Fields.validationStatusCode) ?
+                                                                                                                                                                               new String[] {selector.get(Solution.Fields.validationStatusCode).toString()} :
+                                                                                                                                                                               null,
                                                                                                                                                                        selector.containsKey(Solution.Fields.tags) ?
                                                                                                                                                                                new String[] {selector.get(Solution.Fields.tags).toString()} :
                                                                                                                                                                                null,
@@ -199,18 +189,25 @@ public class CatalogServiceImpl extends AbstractServiceImpl
        @Override
        public List<MLPSolutionRevision> getSolutionRevisions(String theSolutionId, ServiceContext theContext) throws ServiceException {
 
-               log.trace(EELFLoggerDelegate.debugLogger, "getSolutionRevisions");
+               log.trace(EELFLoggerDelegate.debugLogger, "getSolutionRevisions {}", theSolutionId);
                try {
                        List<MLPSolutionRevision> revisions = getClient(theContext).getSolutionRevisions(theSolutionId);
                        //make sure we only expose revisions according to the filter
                        if (revisions != null) {
+                               log.trace(EELFLoggerDelegate.debugLogger, "getSolutionRevisions {}: got {} revisions", theSolutionId, revisions.size());
                                revisions = 
                                        revisions.stream()
-                                                                        .filter(revision -> baseSolutionRevisionSelector.entrySet().stream()
-                                                                                                                                                               .allMatch(s -> { try {
-                                                                                                                                                                                                                                       return PropertyUtils.getProperty(revision, s.getKey()).equals(s.getValue());
-                                                                                                                                                                                                                                } catch (Exception x) { return false; }
-                                                                                                                                                                                                                        })
+                                                                        .filter(revision -> this.config.getSolutionRevisionsSelector().entrySet().stream()
+                                                                                                                                                               .allMatch(s -> {
+                                                                                                                                                                       try {
+                                                                                                                                                                               log.trace(EELFLoggerDelegate.debugLogger, "getSolutionRevisions verifying filter: revision property value {} vs filter value {}", PropertyUtils.getProperty(revision, s.getKey()), s.getValue());
+                                                                                                                                                                               return PropertyUtils.getProperty(revision, s.getKey()).equals(s.getValue());
+                                                                                                                                                                       } 
+                                                                                                                                                                       catch (Exception x) { 
+                                                                                                                                                                               log.trace(EELFLoggerDelegate.errorLogger, "getSolutionRevisions failed to verify filter", x);
+                                                                                                                                                                               return false;
+                                                                                                                                                                       }
+                                                                                                                                                               })
                                                                                                        )
                                                                         .collect(Collectors.toList());
                        }
index f5f3503..9ac01a5 100644 (file)
@@ -78,7 +78,7 @@ public class ContentServiceImpl extends AbstractServiceImpl
                if (ArtifactType.DockerImage == ArtifactType.forCode(theArtifact.getArtifactTypeCode())) {
                        try {
                                //pull followed by save
-                               DockerClient docker = this.clients.getDockerClient();
+                               DockerClient docker = this.dockerConfig.getDockerClient();
 
                                try (PullImageResultCallback pullResult = new PullImageResultCallback()) {
                                        docker.pullImageCmd(theArtifact.getUri())
@@ -106,7 +106,7 @@ public class ContentServiceImpl extends AbstractServiceImpl
                if (ArtifactType.DockerImage == ArtifactType.forCode(theArtifact.getArtifactTypeCode())) {
                        try {
                                //load followed by push
-                               DockerClient docker = this.clients.getDockerClient();
+                               DockerClient docker = this.dockerConfig.getDockerClient();
 
                                docker.loadImageCmd(theResource.getInputStream())
                                                        .exec(); //sync xecution
@@ -165,7 +165,7 @@ public class ContentServiceImpl extends AbstractServiceImpl
 
        protected InputStreamResource getNexusContent(String theUri) throws ServiceException {
                try {
-                       NexusArtifactClient artifactClient = this.clients.getNexusClient();
+                       NexusArtifactClient artifactClient = this.nexusConfig.getNexusClient();
                        ByteArrayOutputStream artifactContent = artifactClient.getArtifact(theUri);
                        log.info(EELFLoggerDelegate.debugLogger, "Retrieved {} bytes of content from {}", artifactContent.size(), theUri);
                        return new InputStreamResource(
@@ -183,7 +183,7 @@ public class ContentServiceImpl extends AbstractServiceImpl
                String theGroupId, String theContentId, String theVersion, String thePackaging, Resource theResource) throws ServiceException {
 
                try {
-                       UploadArtifactInfo info = this.clients.getNexusClient()
+                       UploadArtifactInfo info = this.nexusConfig.getNexusClient()
                                                                                                                                        .uploadArtifact(theGroupId, theContentId, theVersion, thePackaging,
                                                                                                                                                                                                        theResource.contentLength(), theResource.getInputStream());
 
index 137e183..73478b4 100644 (file)
  * limitations under the License.
  * ===============LICENSE_END=========================================================
  */
-
-/**
- * 
- */
 package org.acumos.federation.gateway.service.impl;
 
 import java.lang.invoke.MethodHandles;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.acumos.cds.client.ICommonDataServiceRestClient;
 import org.acumos.cds.domain.MLPPeer;
@@ -33,37 +30,70 @@ import org.acumos.cds.transport.RestPageRequest;
 import org.acumos.cds.transport.RestPageResponse;
 import org.acumos.federation.gateway.cds.PeerStatus;
 import org.acumos.federation.gateway.config.EELFLoggerDelegate;
+import org.acumos.federation.gateway.config.FederationInterfaceConfiguration;
 import org.acumos.federation.gateway.service.PeerService;
 import org.acumos.federation.gateway.service.ServiceContext;
 import org.acumos.federation.gateway.service.ServiceException;
+import org.acumos.federation.gateway.security.Tools;
 import org.acumos.federation.gateway.util.MapBuilder;
 import org.springframework.stereotype.Service;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
- * 
- *
+ *  CDS based implementation of the hpeer service interface.
  */
 @Service
 public class PeerServiceImpl extends AbstractServiceImpl implements PeerService {
 
        private static final EELFLoggerDelegate log = EELFLoggerDelegate.getLogger(MethodHandles.lookup().lookupClass());
 
-       /**
-        * 
-        */
+       @Autowired
+       private FederationInterfaceConfiguration fedIfConfig;
+
        public PeerServiceImpl() {
        }
 
+       /**
+        * Retrieves from CDS the peer record representing this Acumos gateway.
+        * It can tolerate multiple CDS entries marked as 'self', requires a match between the locally configured identity as
+        * it appears in the federation interface configuration and the subjectName attribute of the CDS entry.
+        */
        @Override
        public MLPPeer getSelf() {
-               RestPageResponse<MLPPeer> response = 
-                       getClient().searchPeers(new MapBuilder().put("isSelf", Boolean.TRUE).build(), false, null);
-               log.debug(EELFLoggerDelegate.errorLogger, "Peers representing 'self': " + response.getContent());
-               if (response.getNumberOfElements() != 1) {
-                       log.warn(EELFLoggerDelegate.errorLogger, "Number of peers representing 'self' not 1. First page contains " + response.getNumberOfElements() + ".");
+
+               String selfName = null;
+               try {
+                       selfName = Tools.getNameParts(fedIfConfig.getSubjectName(), "CN").get("CN").toString();
+               }
+               catch(Exception x) {
+                       log.warn(EELFLoggerDelegate.errorLogger, "Cannot obtain 'self' name from interface config " + x);
+                       return null;
+               }
+               final String subjectName = selfName;
+               log.debug(EELFLoggerDelegate.debugLogger, "Expecting 'self' name '{}'", subjectName);
+
+               List<MLPPeer> selfPeers = new ArrayList<MLPPeer>();
+               RestPageRequest pageRequest = new RestPageRequest(0, 100);
+               RestPageResponse<MLPPeer> pageResponse = null;
+               do {
+                       pageResponse =
+                               getClient().searchPeers(new MapBuilder().put("isSelf", Boolean.TRUE).build(), false, pageRequest);
+                       log.debug(EELFLoggerDelegate.errorLogger, "Peers representing 'self': " + pageResponse.getContent());
+
+                       selfPeers.addAll(
+                               pageResponse.getContent().stream()
+                                                                               .filter(peer -> subjectName.equals(peer.getSubjectName()))
+                                                                               .collect(Collectors.toList()));
+
+                       pageRequest.setPage(pageResponse.getNumber() + 1);
+               }
+               while (!pageResponse.isLast());
+
+               if (selfPeers.size() != 1) {
+                       log.warn(EELFLoggerDelegate.errorLogger, "Number of peers representing 'self', i.e. '{}', not 1. Found {}.", subjectName, selfPeers);
                        return null;
                }
-               return response.getContent().get(0);
+               return selfPeers.get(0);
        }
 
        /**
index b0275a1..b40ebb8 100644 (file)
@@ -82,22 +82,19 @@ public class CatalogServiceTest extends ServiceTest {
 
        protected void initMockResponses() {
 
-               registerMockResponse("GET /ccds/solution/search/portal?atc=PB&vsc=PS&active=true&page=0&size=50", MockResponse.success("mockCDSPortalSolutionsResponse.json"));
-               registerMockResponse("GET /ccds/solution/search/date?atc=PB&datems=1531747662&vsc=PS&active=true&page=0&size=50", MockResponse.success("mockCDSDateSolutionsResponsePage0.json"));
-               registerMockResponse("GET /ccds/solution/search/date?atc=PB&datems=1531747662&vsc=PS&active=true&page=1&size=50", MockResponse.success("mockCDSDateSolutionsResponsePage1.json"));
+               registerMockResponse("GET /ccds/solution/search/portal?atc=PB&active=true&page=0&size=100", MockResponse.success("mockCDSPortalSolutionsResponse.json"));
+               registerMockResponse("GET /ccds/solution/search/date?atc=PB&datems=1531747662&vsc=PS&active=true&page=0&size=100", MockResponse.success("mockCDSDateSolutionsResponsePage0.json"));
+               registerMockResponse("GET /ccds/solution/search/date?atc=PB&datems=1531747662&vsc=PS&active=true&page=1&size=100", MockResponse.success("mockCDSDateSolutionsResponsePage1.json"));
                registerMockResponse("GET /ccds/solution/10101010-1010-1010-1010-101010101010", MockResponse.success("mockCDSSolutionResponse.json"));
                registerMockResponse("GET /ccds/solution/10101010-1010-1010-1010-101010101010/revision", MockResponse.success("mockCDSSolutionRevisionsResponse.json"));
-               //registerMockResponse("GET /ccds/solution/10101010-1010-1010-1010-101010101010/revision/a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0/artifact", MockResponse.success("mockCDSSolutionRevisionArtifactsResponse.json"));
                registerMockResponse("GET /ccds/revision/a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0/artifact", MockResponse.success("mockCDSSolutionRevisionArtifactsResponse.json"));
                registerMockResponse("GET /ccds/solution/f0f0f0f0-f0f0-f0f0-f0f0-f0f0f0f0f0f0", new MockResponse(400, "Error", "mockCDSNoEntryWithIDResponse.json"));
                registerMockResponse("GET /ccds/solution/f0f0f0f0-f0f0-f0f0-f0f0-f0f0f0f0f0f0/revision", new MockResponse(400, "Error", "mockCDSNoEntryWithIDResponse.json"));
-               //registerMockResponse("GET /ccds/solution/f0f0f0f0-f0f0-f0f0-f0f0-f0f0f0f0f0f0/revision/f0f0f0f0-f0f0-f0f0-f0f0-f0f0f0f0f0f0/artifact", new MockResponse(400, "Error", "mockCDSNoEntryWithIDResponse.json"));
                registerMockResponse("GET /ccds/revision/f0f0f0f0-f0f0-f0f0-f0f0-f0f0f0f0f0f0/artifact", new MockResponse(400, "Error", "mockCDSNoEntryWithIDResponse.json"));
                registerMockResponse("GET /ccds/solution/f1f1f1f1-f1f1-f1f1-f1f1-f1f1f1f1f1f1", new MockResponse(412, "Error", "mockCDSErrorResponse.json"));
                registerMockResponse("GET /ccds/solution/f1f1f1f1-f1f1-f1f1-f1f1-f1f1f1f1f1f1/revision", new MockResponse(412, "Error", "mockCDSErrorResponse.json"));
-               //registerMockResponse("GET /ccds/solution/f1f1f1f1-f1f1-f1f1-f1f1-f1f1f1f1f1f1/revision/f1f1f1f1-f1f1-f1f1-f1f1-f1f1f1f1f1f1/artifact", new MockResponse(412, "Error", "mockCDSErrorResponse.json"));
                registerMockResponse("GET /ccds/revision/f1f1f1f1-f1f1-f1f1-f1f1-f1f1f1f1f1f1/artifact", new MockResponse(412, "Error", "mockCDSErrorResponse.json"));
-               registerMockResponse("GET /ccds/peer/search?isSelf=true&_j=a", MockResponse.success("mockCDSPeerSearchSelfResponse.json"));
+               registerMockResponse("GET /ccds/peer/search?isSelf=true&_j=a&page=0&size=100", MockResponse.success("mockCDSPeerSearchSelfResponse.json"));
        }
 
        /**
@@ -109,11 +106,11 @@ public class CatalogServiceTest extends ServiceTest {
 
                try {
                        ServiceContext selfService = 
-                               ServiceContext.forPeer(new Peer(new MLPPeer("acumosb", "gateway.acumosb.org", "https://gateway.acumosb.org:9084", false, false, "admin@acumosab.org", "AC", "PS"), Role.SELF));
+                               ServiceContext.forPeer(new Peer(new MLPPeer("acumosa", "gateway.acumosa.org", "https://gateway.acumosa.org:9084", false, false, "admin@acumosa.org", "AC", "PS"), Role.SELF));
 
                        List<MLPSolution> solutions = catalog.getSolutions(Collections.EMPTY_MAP, selfService);
                        assertTrue("Unexpected solutions count: " + solutions.size(), solutions.size() == 5);
-                       
+               
                        Solution solution = catalog.getSolution("10101010-1010-1010-1010-101010101010", selfService);
                        assertTrue("Unexpected solution info", solution.getName().equals("test"));
 
@@ -161,7 +158,7 @@ public class CatalogServiceTest extends ServiceTest {
                        }
                }
                catch (Exception x) {
-                       fail("Unexpected catalog test outcome: " + x);
+                       fail("Unexpected catalog test outcome: " + org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(x));
                }
        }
 
index bfe52c8..002ae56 100644 (file)
@@ -41,6 +41,8 @@ import org.acumos.cds.transport.RestPageRequest;
 import org.acumos.cds.transport.RestPageResponse;
 import org.acumos.federation.gateway.cds.PeerStatus;
 import org.acumos.federation.gateway.cds.Mapper;
+import org.acumos.federation.gateway.config.CDMSClientConfiguration;
+import org.acumos.federation.gateway.config.NexusConfiguration;
 import org.acumos.federation.gateway.common.Clients;
 import org.acumos.federation.gateway.common.FederationClient;
 import org.acumos.nexus.client.NexusArtifactClient;
@@ -108,6 +110,12 @@ public class PeerGatewayTest {
        @MockBean(name = "clients")
        private Clients clients;
 
+       @MockBean
+       private CDMSClientConfiguration cdsConfig;
+
+       @MockBean
+       private NexusConfiguration nexusConfig;
+
        @Autowired
        private ApplicationContext context;
 
@@ -216,6 +224,18 @@ public class PeerGatewayTest {
                                .addHeader("Content-Length", String.valueOf(0));
 
                        //prepare the clients
+                       when(
+                               this.cdsConfig.getCDSClient()
+                       )
+                       .thenAnswer(new Answer<ICommonDataServiceRestClient>() {
+                                       public ICommonDataServiceRestClient answer(InvocationOnMock theInvocation) {
+                                               return cdsClient;
+                                       }
+                               });
+
+                       //clients delegates the cds cleint buils to CDMSconfiguration so normally this would not 
+                       //be required but .. we need to mock the federation client build so clients bean must be
+                       //mocked hence it needs to be done entierly (same for nexus client).
                        when(
                                this.clients.getCDSClient()
                        )
@@ -257,6 +277,11 @@ public class PeerGatewayTest {
                        )
                        .thenReturn(nexusClient);
 
+                       when(
+                               this.nexusConfig.getNexusClient()
+                       )
+                       .thenReturn(nexusClient);
+
                        when(
                                this.nexusClient.uploadArtifact(
                                        any(String.class),any(String.class),any(String.class),any(String.class),any(Long.class),any(InputStream.class)
@@ -275,8 +300,8 @@ public class PeerGatewayTest {
                                                MLPPeer peer = new MLPPeer();
                                                if (selector != null && selector.containsKey("isSelf") && selector.get("isSelf").equals(Boolean.TRUE)) {
                                                        peer.setPeerId("0");
-                                                       peer.setName("testSelf");
-                                                       peer.setSubjectName("test.org");
+                                                       peer.setName("acumosa");
+                                                       peer.setSubjectName("gateway.acumosa.org");
                                                        peer.setStatusCode(PeerStatus.Active.code());
                                                        peer.setSelf(true);
                                                        peer.setApiUrl("https://localhost:1110");
index 11fefe0..2c5fdd3 100644 (file)
@@ -51,19 +51,19 @@ import org.springframework.test.context.junit4.SpringRunner;
                                                                        "federation.instance=gateway",
                                                                        "federation.instance.name=test",
                                                                        "federation.operator=admin",
-                                                                       "federation.ssl.key-store=classpath:acumosb.pkcs12",
-                                                                       "federation.ssl.key-store-password=acumosb",
+                                                                       "federation.ssl.key-store=classpath:acumosa.pkcs12",
+                                                                       "federation.ssl.key-store-password=acumosa",
                                                                        "federation.ssl.key-store-type=PKCS12",
-                                                                       "federation.ssl.key-password = acumosb",
+                                                                       "federation.ssl.key-password=acumosa",
                                                                        "federation.ssl.trust-store=classpath:acumosTrustStore.jks",
                                                                        "federation.ssl.trust-store-password=acumos",
                                                                        "federation.ssl.client-auth=need",
                                                                        "local.addr=127.0.0.1",
                                                                        "local.server.port=9011",
-                                                                       "local.ssl.key-store=classpath:acumosb.pkcs12",
-                                                                       "local.ssl.key-store-password=acumosb",
+                                                                       "local.ssl.key-store=classpath:acumosa.pkcs12",
+                                                                       "local.ssl.key-store-password=acumosa",
                                                                        "local.ssl.key-store-type=PKCS12",
-                                                                       "local.ssl.key-password=acumosb",
+                                                                       "local.ssl.key-password=acumosa",
                                                                        "cdms.client.url=http://localhost:8000/ccds",
                                                                        "cdms.client.username=username",
                                                                        "cdms.client.password=password"
@@ -75,12 +75,11 @@ public class PeerServiceTest extends ServiceTest {
        private PeerService peerService;
 
        protected void initMockResponses() {
-               registerMockResponse("GET /ccds/peer/search?isSelf=true&_j=a", MockResponse.success("mockCDSPeerSearchSelfResponse.json"));
+               registerMockResponse("GET /ccds/peer/search?isSelf=true&_j=a&page=0&size=100", MockResponse.success("mockCDSPeerSearchSelfResponse.json"));
                registerMockResponse("GET /ccds/peer?page=0&size=100", MockResponse.success("mockCDSPeerSearchAllResponse.json"));
-               //registerMockResponse("/ccds/peer", MockResponse.success("mockCDSPeerSearchAllResponse.json"));
-               registerMockResponse("GET /ccds/peer/search?subjectName=gateway.acumosa.org&_j=a", MockResponse.success("mockCDSPeerSearchResponse.json"));
+               registerMockResponse("GET /ccds/peer/search?subjectName=gateway.acumosb.org&_j=a", MockResponse.success("mockCDSPeerSearchResponse.json"));
                registerMockResponse("GET /ccds/peer/search?subjectName=gateway.acumosc.org&_j=a", MockResponse.success("mockCDSSearchEmptyResponse.json"));
-               registerMockResponse("PUT /ccds/peer/a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0", MockResponse.success("mockCDSPeerUpdateResponse.json"));
+               registerMockResponse("PUT /ccds/peer/b0b0b0b0-b0b0-b0b0-b0b0-b0b0b0b0b0b0", MockResponse.success("mockCDSPeerUpdateResponse.json"));
                registerMockResponse("POST /ccds/peer", MockResponse.success("mockCDSPeerCreateResponse.json"));
        }
 
@@ -99,7 +98,7 @@ public class PeerServiceTest extends ServiceTest {
                        List<MLPPeer> peers = peerService.getPeers(selfService);
                        assertTrue("Unexpected all peers response", peers.size() == 2);
 
-                       List<MLPPeer> peersn = peerService.getPeerBySubjectName("gateway.acumosa.org");
+                       List<MLPPeer> peersn = peerService.getPeerBySubjectName("gateway.acumosb.org");
                        assertTrue("Expected one peer to be found", peersn.size() == 1);
 
                        try {
index a432592..a37bda8 100644 (file)
@@ -3,13 +3,13 @@
     {
       "created": 1532025563000,
       "modified": 1532025563000,
-      "peerId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
-      "name": "acumosa",
-      "subjectName": "gateway.acumosa.org",
+      "peerId": "b0b0b0b0-b0b0-b0b0-b0b0-b0b0b0b0b0b0",
+      "name": "acumosb",
+      "subjectName": "gateway.acumosb.org",
       "description": "test",
-      "apiUrl": "https://gateway.acumosa.org:9084",
-      "webUrl": "https://gateway.acumosa.org:9084",
-      "contact1": "admin@acumosa.org",
+      "apiUrl": "https://gateway.acumosb.org:9084",
+      "webUrl": "https://gateway.acumosb.org:9084",
+      "contact1": "admin@acumosb.org",
       "statusCode": "AC",
       "validationStatusCode": "PS",
       "local": false,
index 610e54b..43ac2bf 100644 (file)
@@ -3,13 +3,13 @@
     {
       "created": 1532025563000,
       "modified": 1532025563000,
-      "peerId": "b0b0b0b0-b0b0-b0b0-b0b0-b0b0b0b0b0b0",
-      "name": "acumosb",
-      "subjectName": "gateway.acumosb.org",
+      "peerId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
+      "name": "acumosa",
+      "subjectName": "gateway.acumosa.org",
       "description": "test",
-      "apiUrl": "https://gateway.acumosb.org:9084",
-      "webUrl": "https://gateway.acumosb.org:9084",
-      "contact1": "admin@acumosb.org",
+      "apiUrl": "https://gateway.acumosa.org:9084",
+      "webUrl": "https://gateway.acumosa.org:9084",
+      "contact1": "admin@acumosa.org",
       "statusCode": "AC",
       "validationStatusCode": "PS",
       "local": false,
index 4e31ffe..2d7eb0f 100644 (file)
@@ -1,13 +1,13 @@
 {
   "created": 1532025563000,
   "modified": 1532636037000,
-  "peerId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
-  "name": "acumosa",
-  "subjectName": "gateway.acumosa.org",
-  "description": "acumosa",
-  "apiUrl": "https://gateway.acumosa.org:9084",
-  "webUrl": "https://gateway.acumosa.org:9084",
-  "contact1": "admin@acumosa.org",
+  "peerId": "b0b0b0b0-b0b0-b0b0-b0b0-b0b0b0b0b0b0",
+  "name": "acumosb",
+  "subjectName": "gateway.acumosb.org",
+  "description": "acumosb",
+  "apiUrl": "https://gateway.acumosb.org:9084",
+  "webUrl": "https://gateway.acumosb.org:9084",
+  "contact1": "admin@acumosb.org",
   "statusCode": "RN",
   "validationStatusCode": "PS",
   "local": false,
index 23d9889..7750ae3 100644 (file)
@@ -21,7 +21,7 @@
     "description": "test 2",
     "metadata": null,
     "origin": null,
-    "accessTypeCode": "PB",
+    "accessTypeCode": "OR",
     "validationStatusCode": "NV",
     "solutionId": "10101010-1010-1010-1010-101010101010",
     "userId": "d1e838c8-d8be-4ca4-968c-2ba5c6c04e55",